一套标准的ASP.NET Core容器化应用日志收集分析方案

点击上方蓝字

给一个关注吧

讲故事

关注我公众号的朋友,应该知道我写了一些云原生应用日志收集和分析相关的文章,其中内容大多聚焦某个具体的组件:

  • 超级有用的TraceId,快点用起来吧!

  • 如何利用NLog输出结构化日志,并在Kibana优雅分析日志?   

  • 既然能直接向ElasticSearch写日志,为什么还要logstash等日志摄取器?

本文记录一套标准的、无侵入的的容器化应用日志收集方案:

  1. 什么样的日志应该被收集?

  2. 如何输出为结构化日志?

  3. 使用EFK无侵入的收集分析日志

定制ASP.NET Core日志;       将结构化日志输出到stdout;                           

Fluentbit无侵入式转发容器日志;    存储在Es并在Kibana上分析日志。

定制ASP.NET Core日志

面向互联网的经典应用,不外乎三部分日志:请求、业务处理、数据库操作。
在实际采集日志时,关注[特定日志场景]:

  • 提供给第三方调用的API(????有撕逼可能性)

  • 核心流程业务 (????996排障)

  • 数据库操作(????删库跑路可能性)

  • 应用内部发起的Http请求 (????联调撕逼)

  • Warn、Error、Fatal级别日志(????持续关注)

ASP.NETCore灵活的配置系统、可插拔的组件系统,让我们轻松配置日志、管理日志组件。

日志采集策略

ASP.NET Core应用的日志配置取决于appsettings.{Environment}.json文件的Logging配置节
支持多个LogProvider、过滤日志、定制特定种类日志的收集级别。

 "Logging": {"LogLevel": {"Microsoft": "Warning","Microsoft.AspNetCore.Hosting.Diagnostics": "Information",    // 提供给第三方调用API日志"Microsoft.Hosting.Lifetime": "Information","Microsoft.EntityFrameworkCore.Database.Command": "Information",  //数据库操作sql日志"System.Net.Http.HttpClient": "Information",    // 应用内部发起的Http请求日志"Default": "Warning"    // 除以上日志之外,记录Warning+级别日志}}

以上Logging配置针对[特定日志场景],满足经典互联网应用的日志采集需求。

NLog Provider

结构化日志提出[MessageTemplate]来解决传统文本日志对机器不友好的问题。

① 这里使用NLog Provider接管所有的日志输出

// Please  install-package NLog.Web.AspNetCore
internal static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureLogging((hostBuilder, loggerBuilder) =>{loggerBuilder.ClearProviders();loggerBuilder.AddNLog("nlog.production.config");}).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});

② 编写NLog[JsonLayout]将传统文本日志转换为JSON格式日志:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogFile="logs/nlog-internal.log" internalLogLevel="Info" ><targets async="true"><target name="console" xsi:type="Console"><layout xsi:type="JsonLayout" includeAllProperties="true" excludeProperties="EventId_Id,EventId_Name,EventId"><attribute name="time" layout="${date:format=yyyy/MM/dd HH\:mm\:ss.fff zzz}" /><attribute name="category" layout="${logger}" /><attribute name="log_level" layout="${level:lowerCase=true}" /><attribute name="message" layout="${message}" /><attribute name="trace_id" layout="${aspnet-TraceIdentifier:ignoreActivityId=true}" /><attribute name="user_id" layout="${aspnet-user-identity}" /><attribute name="exception" layout="${exception:format=tostring}" /></layout></target></targets><rules><logger name="*" minlevel="Info" writeTo="console"   ruleName="console" /></rules>
</nlog>

与业务紧密相关的日志字符:

  • includeAllProperties="true"  输出日志条目的所有属性

  • trace_id=${aspnet-TraceIdentifier:ignoreActivityId=true}  取得trace_id,排障时很有用

  • user_id=${aspnet-user-identity}  取得该条日志生产者的名字

启动应用日志长这样:

请保持所有应用日志的输出目标为stdout,让Fluent-bit无侵入采集!

....【TODO: 容器制作镜像!!!!】 ...

Fluent-Bit收集容器日志

Fluent-bit采集日志,小巧够用!

采集容器日志需要将容器应用的Logging Driver改为[Fluentd]
Fluentd Driver默认会在宿主机24224端口监听Forward消息 。

一个简单的容器Docker-compose示例:

version: "3.7"services:website:image: ${DOCKER_REGISTRY}/eap/website:0.1ports:- "80:80"environment:- TZ=Asia/Shanghainetworks:- webnetlogging:driver: fluentdoptions:
#       fluentd-address: localhost:24224tag: eap-websiterestart: always
networks:webnet:external: truename: eap-net

Fluentd Driver采集的格式如下 :

{
"container_id": "...",
"container_name": "...",
"source": "stdout",
"log": "This is log content"
}

容器应用产生的json日志(log字段)会被编码,这就很尴尬了,处心积虑的结构化日志没有萃取出日志字段!!

多番搜索,在Fluentbit上找到Decoders 插件, 能将被编码的JSON字符串解码:

完整的fluent-bit.conf 如下:

[SERVICE]flush            1log_Level        infodaemon           offhttp_server      on    // 在宿主机作为http server启动http_listen      0.0.0.0http_port        2020storage.metrics  onParsers_File     parsers.conf
[INPUT]name             forwardmax_chunk_size   1Mmax_buffer_size  5M
[FILTER]Name  parserMatch *Key_Name log            // 要解析的字段Parser  docker          // 以docker日志格式解析,内容在parser.conf文件Preserve_Key   True     // 保留原解析的字段Reserve_Data   True     // 保留原始其他字段
[OUTPUT]name             esmatch            *host             es01port             9200logstash_format  onreplace_dots     onretry_limit      false

这样输出的结果就是:

nice,后面就请自由在Kibana中分析日志吧。

完整的EFK收集容器日志的源码配置,github传送门:https://github.com/zaozaoniao/dockercompose-efk

以上就是小码甲总结的使用EFK收集/分析容器化ASP.NET Core应用日志的全过程, 可学习可商用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306654.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法设计与分析——递归与分治策略——棋盘覆盖

问题描述 棋盘覆盖问题要求在2^k * 2^k 个方格组成的棋盘中&#xff0c;你给定任意一个特殊点&#xff0c;用一种方案实现对除该特殊点的棋盘实现全覆盖。 建立模型如图&#xff1a; 解决方案就是利用分治法&#xff0c;将方形棋盘分成4部分&#xff0c;如果该特殊点在某一部…

函数求值需要运行所有线程_JavaScript函数式编程(二)

纯函数就是&#xff0c;对于相同的输入&#xff0c;永远会得到相同的输出&#xff0c;而且没有任何可观察的副作用&#xff0c;也不依赖外部环境的状态但是实际的编程中&#xff0c;特别是前端的编程范畴里&#xff0c;“不依赖外部环境”这个条件是根本不可能的&#xff0c;我…

如何在 C# 中使用 RabbitMQ

译文链接&#xff1a;https://www.infoworld.com/article/3200210/how-to-work-with-rabbitmq-in-c.htmlRabbitMQ 是一个非常流行的&#xff0c;开源的&#xff0c;使用Erlang语言编写的框架&#xff0c;通常在电信级平台中作为消息中间件使用&#xff0c;RabbitMQ实现了高级的…

算法设计与分析——递归与分治——归并排序

归并排序采用的是一种分治的思想&#xff0c;如下图&#xff0c;先将要排序的元素分为两块&#xff0c;每个块又开始分裂&#xff0c;然后逐个按照特定顺序合并&#xff0c;合成最后我们需要的数组。 归并排序的复杂度&#xff1a; 时间复杂度&#xff1a;O(nlogn) 空间复杂度&…

git 回退上一个版本_Git小白使用教程:详细、显现、真正手把手教!

不少小伙伴私信问我GitHub怎么使用&#xff1f;今天更一下&#xff0c;希望能帮到你&#xff0c;有问题评论区拍砖交流吧。

在传统行业做数字化转型之业务篇

【数字化转型】| 作者 / Edison Zhou这是EdisonTalk的第307篇原创内容在过去的两年时间里&#xff0c;我加入了一家传统行业的企业参与其数字化转型的过程&#xff0c;现在我将我的经历分享出来&#xff0c;本文是第三部分—业务篇&#xff0c;主要会介绍一下传统企业通用的三大…

算法设计与分析——递归与分治策略——快速排序

快速排序——递归算法 处理i,j的先后顺序不能改变 快速排序的基本思想&#xff1a;通过一趟排序将待排记录分隔成独立的两部分&#xff0c;其中一部分记录的关键字均比另一部分的关键字小&#xff0c;则可分别对这两部分记录继续进行排序&#xff0c;以达到整个序列有序。 函数…

git pull 覆盖本地_SVN与Git比较的优缺点差异

一、 集中式vs分布式1. Subversion属于集中式的版本控制系统集中式的版本控制系统都有一个单一的集中管理的服务器&#xff0c;保存所有文件的修订版本&#xff0c;而协同工作的人们都通过客户端连到这台服务器&#xff0c;取出最新的文件或者提交更新。Subversion的特点概括起…

C#阻塞队列BlockingCollection

BlockingCollection是一个比较冷门的类&#xff0c;我们先看下官方对这个类的定义&#xff1a;简单来说&#xff0c;BlockingCollection就是一个线程安全的阻塞队列&#xff0c;利用阻塞这个特性&#xff0c;我们可以实现进程内的生产者-消费者模式&#xff0c;比如消息转发、日…

算法设计与分析——递归与分治策略——线性时间选择

顾名思义&#xff1a;这篇文章讲解的就是如果用线性时间算法来作出元素选择问题。 问题描述&#xff1a;给定线性序集中n个元素和一个整数k&#xff0c;1<k<n.要求找出这n个元素中第k小的元素&#xff0c;即如果将这个n个元素依其线性序排列时&#xff0c;排在第k个位置的…

如何在 .NET 中使用 Redis缓存

译文链接&#xff1a;https://www.infoworld.com/article/3187905/how-to-work-with-redis-cache-in-net.html缓存是一种状态管理机制&#xff0c;通常用于提升你的应用程序性能&#xff0c;它很大程度上能够减少一个请求对你系统资源的消耗。Redis是一个开源的&#xff0c;高性…

git push被拒绝_规范git项目提交并自动生成项目commit log

commit message 是开发的日常操作, 好的 log 不仅有助于他人 review, 还可以有效的输出 CHANGELOG, 对项目的管理实际至关重要, 但是在平时工作时&#xff0c;只依赖大致的开发规范和自觉&#xff0c;很难形成一种普遍约束。而通过本文&#xff0c;对项目进行一些基础配置&…

算法设计与分析——递归与分治策略——全排列

算法设计与分析——递归与分治策略——全排列 全排列问题的解决是通过分治与递归思想来解决的 首先判断是否递归到了最后一位&#xff0c;如果递归到了最后一位&#xff0c;则输出他当前的全排列序列。 如果没有到达最后一位&#xff0c;则循环的交换该第K个元素与其后面的所有…

asp.net core 集成 prometheus

asp.net core 集成 prometheusIntroPrometheus 是一个开源的现代化&#xff0c;云原生的系统监控框架&#xff0c;并且可以轻松的集成 PushGateway, AlertManager等组件来丰富它的功能。对于 k8s 下部署的系统来说使用 Prometheus 来做系统监控会是一个比较不错的选择&#xff…

vba 不等于_EXCEL中VBA基础语句(1)

萌二笔记分类目录及书单一、If-Then语句 说明&#xff1a;条件判断&#xff0c;如果......那么......例1&#xff1a;A2单元格的成绩大于等于60&#xff0c;则弹出对话框提示“及格”。Sub 判断成绩()If Range("A2") > 60 Then MsgBox "及格"End Sub操作…

PHP大势已去,PHP宝藏可为我所用

编者注&#xff1a; PHP有着庞大的生态系统&#xff0c;还是可以为我dotnet所用&#xff1a;介绍一个基于 .NET 的船的新 PHP SDK Runtime: PeachPie。PHP 8 昨天发布了&#xff0c;今天不写代码&#xff0c;聊聊我对 PHP 的看法。昨天在今日头条发了一条微头条&#xff0c;引…

leetcode——242. 有效的字母异位词

问题描述&#xff1a; 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 示例 1: 输入: s “anagram”, t “nagaram” 输出: true 示例 2: 输入: s “rat”, t “car” 输出: false 说明: 你可以假设字符串只包含小写字母。 进阶: 如…

python常用函数和操作_python一条语句分析几个常用函数和概念 -

前言 过年也没完全闲着&#xff0c;每天用一点点时间学点东西&#xff0c;本文为大家介绍几个python操作的细节&#xff0c;包含all、any、for in等操作&#xff0c;以及介绍我解决问题的思路。 一、开篇 先从我看到的一个简单的语句开始。 刚看到这个语句的时候我整个人完全懵…

.NET5发布了,腾讯招聘点名要求精通MySQL,而不是SQLServer!

.NET5正式发布&#xff0c;社区一片欢腾&#xff0c;.NET相关技术栈也会迎来大变革&#xff0c;而大厂的招聘要求可谓是技术风向标&#xff01;紧盯腾讯网易顺丰等大厂的招聘&#xff0c;会发现都在明确要求。MySQL&#xff0c;而不是SQL Server了。究其根本&#xff0c;还是跨…

leetcode——344. 反转字符串

leetcode——344. 反转字符串 问题概述&#xff1a; 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 你可以假…