讲故事

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

  • 超级有用的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、过滤日志、定制特定种类日志的收集级别。

  1. "Logging": {
  2. "LogLevel": {
  3. "Microsoft": "Warning",
  4. "Microsoft.AspNetCore.Hosting.Diagnostics": "Information", // 提供给第三方调用API日志
  5. "Microsoft.Hosting.Lifetime": "Information",
  6. "Microsoft.EntityFrameworkCore.Database.Command": "Information", //数据库操作sql日志
  7. "System.Net.Http.HttpClient": "Information", // 记录内部http请求
  8. "Default": "Warning" // 除以上日志之外,记录Warning+级别日志
  9. }
  10. }

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

NLog Provider

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

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

  1. // Please install-package NLog.Web.AspNetCore
  2. internal static IHostBuilder CreateHostBuilder(string[] args) =>
  3. Host.CreateDefaultBuilder(args)
  4. .ConfigureLogging((hostBuilder, loggerBuilder) =>
  5. {
  6. loggerBuilder.ClearProviders();
  7. loggerBuilder.AddNLog("nlog.production.config");
  8. })
  9. .ConfigureWebHostDefaults(webBuilder =>
  10. {
  11. webBuilder.UseStartup<Startup>();
  12. });

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

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogFile="logs/nlog-internal.log" internalLogLevel="Info" >
  4. <targets async="true">
  5. <target name="console" xsi:type="Console">
  6. <layout xsi:type="JsonLayout" includeAllProperties="true" excludeProperties="EventId_Id,EventId_Name,EventId">
  7. <attribute name="time" layout="${date:format=yyyy/MM/dd HH\:mm\:ss.fff zzz}" />
  8. <attribute name="category" layout="${logger}" />
  9. <attribute name="log_level" layout="${level:lowerCase=true}" />
  10. <attribute name="message" layout="${message}" />
  11. <attribute name="trace_id" layout="${aspnet-TraceIdentifier:ignoreActivityId=true}" />
  12. <attribute name="user_id" layout="${aspnet-user-identity}" />
  13. <attribute name="exception" layout="${exception:format=tostring}" />
  14. </layout>
  15. </target>
  16. </targets>
  17. <rules>
  18. <logger name="*" minlevel="Info" writeTo="console" ruleName="console" />
  19. </rules>
  20. </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示例:

  1. version: "3.7"
  2. services:
  3. website:
  4. image: ${DOCKER_REGISTRY}/eap/website:0.1
  5. ports:
  6. - "80:80"
  7. environment:
  8. - TZ=Asia/Shanghai
  9. networks:
  10. - webnet
  11. logging:
  12. driver: fluentd
  13. options:
  14. # fluentd-address: localhost:24224
  15. tag: eap-website
  16. restart: always
  17. networks:
  18. webnet:
  19. external: true
  20. name: eap-net

Fluentd Driver采集的格式如下 :

  1. {
  2. "container_id": "...",
  3. "container_name": "...",
  4. "source": "stdout",
  5. "log": "This is log content"
  6. }

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

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

完整的fluent-bit.conf 如下:

  1. [SERVICE]
  2. flush 1
  3. log_Level info
  4. daemon off
  5. http_server on // 在宿主机作为http server启动
  6. http_listen 0.0.0.0
  7. http_port 2020
  8. storage.metrics on
  9. Parsers_File parsers.conf
  10. [INPUT]
  11. name forward
  12. max_chunk_size 1M
  13. max_buffer_size 5M
  14. [FILTER]
  15. Name parser
  16. Match *
  17. Key_Name log // 要解析的字段
  18. Parser docker // 以docker日志格式解析在parser.conf文件
  19. Preserve_Key True // 保留原解析的字段
  20. Reserve_Data True // 保留原始其他字段
  21. [OUTPUT]
  22. name es
  23. match *
  24. host es01
  25. port 9200
  26. logstash_format on
  27. replace_dots on
  28. retry_limit false

这样输出的结果就是:

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

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

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

一套标准的ASP.NET Core容器化应用日志收集分析方案的更多相关文章

  1. .NET Core容器化开发系列(零)——计划

    .NET Core相当完善的跨平台特性以及其轻量化的底层接口为我们能顺畅进行微服务开发提供了非常棒的基础. 作为支撑微服务最常见的基础技术--容器化将是本系列的核心内容. 接下来我计划用一个月左右的时 ...

  2. kubernetes高级之创建只读文件系统以及只读asp.net core容器

    系列目录 使用docker创建只读文件系统 容器化部署对应用的运维带来了极大的方便,同时也带来一些新的安全问题需要考虑.比如黑客入侵到容器内,对容器内的系统级别或者应用级别文件进行修改,会造成难以估量 ...

  3. 一题多解,ASP.NET Core应用启动初始化的N种方案[下篇]

    [接上篇]"天下大势,分久必合,合久必分",ASP.NET应用通过GenericWebHostService这个承载服务被整合到基于IHostBuilder/IHost的服务承载系 ...

  4. .NET Core容器化之多容器应用部署@Docker-Compose

    1.引言 紧接上篇.NET Core容器化@Docker,这一节我们先来介绍如何使用Nginx来完成.NET Core应用的反向代理,然后再介绍多容器应用的部署问题. 2. Why Need Ngin ...

  5. .NET Core容器化之多容器应用部署-使用Docker-Compose

    原文补充: -- docker-compose.ymlversion: ' services: mvc-web: container_name: mvc.web.compose build: . re ...

  6. ASP.NET Core扩展库之日志

        上一篇我们对Xfrogcn.AspNetCore.Extensions扩展库功能进行了简单的介绍,从这一篇文章开始,我将逐步介绍扩展库中的核心功能.     日志作为非业务的通用领域基础功能, ...

  7. Asp.net core 使用log4net作为日志组件,记录日志到本地。

    原文:Asp.net core 使用log4net作为日志组件,记录日志到本地. GitHub demo :https://github.com/zhanglilong23/Asp.NetCore.D ...

  8. Asp.net Core + Log4net + ELK 搭建日志中心

    原文:Asp.net Core + Log4net + ELK 搭建日志中心 Docker中一键安装ELK 对于这种工具类的东西,第一步就直接到docker的hub中查找了,很幸运,不仅有Elasti ...

  9. 利用 ELK 搭建 Docker 容器化应用日志中心

    利用 ELK 搭建 Docker 容器化应用日志中心 概述 应用一旦容器化以后,需要考虑的就是如何采集位于 Docker 容器中的应用程序的打印日志供运维分析.典型的比如SpringBoot应用的日志 ...

随机推荐

  1. 常用的实现Javaweb页面跳转的方式

    我们有两大种方式来实现页面跳转:1.JS(javascript):2.jsp跳转 先说jsp(金j三s胖p):1.转发:request.getRequestDispatcher("1.jsp ...

  2. 企业级数据大屏设计如何实现,div+html+echarts

    大屏是什么? 大屏设计是最近比较流行的概念,一般按照功能来分有几种: 1. 可交互的触摸屏,大多运用在互动教学课程或者报告演示现场,用户可结合交互操作来阐述具体内容.设计师需要对交互形式和传达内容作统 ...

  3. 删除指定路径下指定天数之前(以文件的最后修改日期为准)的文件:BAT + VBS

    代码如下: @echo off ::演示:删除指定路径下指定天数之前(以文件的最后修改日期为准)的文件. ::如果演示结果无误,把del前面的echo去掉,即可实现真正删除. ::本例调用了临时VBS ...

  4. Linux 系统编程 学习:11-线程:线程同步

    Linux 系统编程 学习:11-线程:线程同步 背景 上一讲 我们介绍了线程的属性 有关设置.这一讲我们来看线程之间是如何同步的. 额外安装有关的man手册: sudo apt-get instal ...

  5. mysql 一主多从环境搭建(亲测)

    前期准备 三台服务器,服务器使用的是 centos7 mysql-5.7.24-linux-glibc2.12-x86_64 安装包 使用是版本是 mysql-5.7.24 数据库安装 将 mysql ...

  6. Java_静态代理与Lambda

    静态代理 要点: 公共接口 真实角色 代理角色 public class StaticProxy { public static void main(String[] args) { You you ...

  7. 剑指offer之打印超过数组一半的数字

    问题描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  8. leetcode115:search -insert-position

    题目描述 给出一个有序的数组和一个目标值,如果数组中存在该目标值,则返回该目标值的下标.如果数组中不存在该目标值,则返回如果将该目标值插入这个数组应该插入的位置的下标 假设数组中没有重复项. 下面给出 ...

  9. Java设计系列之书店管理系统单机版

    书店管理系统: 项目练习目标 :1.Java应用程序基本分析2.培养面向对象编程的基本思想3.Java基本设计模式综合应用4.掌握分层和接口的基本设计5.构建合理的Java应用程序包结构6.综合应用J ...

  10. 理解js参数

    <!DOCTYPE html><html><head> <meta charset="utf-8" /> <title> ...