.NET Core开发日志——结构化日志

在.NET生态圈中,最早被广泛使用的日志库可能是派生自Java世界里的Apache log4net。而其后来者,莫过于NLog。Nlog与log4net相比,有一项较显著的优势,它支持结构化日志。

结构化日志,也被称为语义化日志。其作用有二,利于查询与方便分析。

当系统上线被广泛使用或者时间久远之后,日志的大量出现不可避免。且日志本身作为一种数据,也有其重要的价值。因此,如何有效地对其进行查询以及最大价值化地分析处理便成了一个重要的问题。

非结构化日志

对于日志的处理,需要权衡对开发者的友好性与对程序解析的方便性。传统的非结构化日志更倾向于前者。当开发者想要记录一段日志时,他可以很简单地加上一行代码,即可达成其目的。

logger.Info("Logon by user:{0} from ip_address:{1}", "Kenny", "127.0.0.1");

然后这行代码的执行结果可能被存于文本文件或者数据库中。

2018-12-22 16:29:29.2793|Info|Logon by user:Kenny from ip_address:127.0.0.1

这样的日志以开发者的角度来看,清晰易懂,十分友好。但如果要使用程序去查找海量的上述例子里的某段时间内的特定登陆用户,则很难高效地完成这一要求,因为需要对每个日志进行字符串解析。

消息模板

消息模板规范是结构化日志的通用语法,其是一个与开发语言无关的规范,能以特定格式捕获及呈现结构化日志,同时提供对开发者与程序解析的友好支持。

以上图片中的日志记录方式乍看起来与非结构化日志差不多,但它们之间具有本质的区别,在结构化日志里,是以对象而非字符串处理日志内容的。

如果将非结构化日志例子里的代码改成结构化日志的写法。

logger.Info("Logon by {user} from {ip_address}", "Kenny", "127.0.0.1");

执行后两者的结果是这样的:

2018-12-22 16:29:29.2793|Info|Logon by user:Kenny from ip_address:127.0.0.1
2018-12-22 16:29:29.2976|Info|Logon by "Kenny" from "127.0.0.1"

似乎差别并不大,再将输出类型改成JSON风格看看:

{ "time": "2018-12-22 16:30:15.1314", "level": "INFO", "message": "Logon by user:Kenny from ip_address:127.0.0.1" }
{ "time": "2018-12-22 16:30:15.1569", "level": "INFO", "message": "Logon by \"Kenny\" from \"127.0.0.1\"", "user": "Kenny", "ip_address": "127.0.0.1" }

显而易见,对于后者,因为user被作为对象的属性独立分离出来,在做程序处理时,可以很方便地以其为条件进行筛选。这对于查询或者分析日志是极为重要的。

NLog

NLog中对于结构化日志的支持是在4.5版本才开始的。这一改动并不会破坏原有的代码,而如果想要使用新的特性,则只要用符合消息模板的语法编写所需的代码即可。

Object o = null;

logger.Info("Test {value1}", o); // null case. Result:  Test NULL
logger.Info("Test {value1}", new DateTime(2018,03, 25)); // datetime case. Result:  Test 25-3-2018 00:00:00 (locale TString)
logger.Info("Test {value1}", new List<string> { "a", "b" }); // list of strings. Result: Test "a", "b"
logger.Info("Test {value1}", new[] { "a", "b" }); // array. Result: Test "a", "b"
logger.Info("Test {value1}", new Dictionary<string, int> { { "key1", 1 }, { "key2", 2 } }); // dict. Result:  Test "key1"=1, "key2"=2

var order = new Order
{
    OrderId = 2,
    Status = OrderStatus.Processing
};

logger.Info("Test {value1}", order); // object Result:  Test MyProgram.Program+Order
logger.Info("Test {@value1}", order); // object Result:  Test {"OrderId":2, "Status":"Processing"}
logger.Info("Test {value1}", new { OrderId = 2, Status = "Processing"}); // anomynous object. Result: Test { OrderId = 2, Status = Processing }
logger.Info("Test {@value1}", new { OrderId = 2, Status = "Processing"}); // anomynous object. Result:Test {"OrderId":2, "Status":"Processing"}

代码的格式化结果依据数据的类型而定。

  • 字符串类型将被双引号包围
  • 数值类型没有引号
  • null显示为NULL
  • 列表或数组类型,以逗号分隔,例如:"item1", "item2"
  • 字典类型,健与值之间用等号相联,例如:"key1"="value1", "key2"="value2"
  • 对象类型,调用ToString方法显示结果

此外,还可以有@与$符号:

  • @ 以JSON格式格式化数据
  • $ 强制调用ToString方法

而将日志输出格式改成JSON的方法,是在NLog.config配置文件里将布局切换成JsonLayout类型,同时设置includeAllPropertiestrue,以显示所有对象属性。

<target name="console" xsi:type="Console">
  <layout xsi:type="JsonLayout" includeAllProperties="true">
    <attribute name="time" layout="${longdate}" />
    <attribute name="level" layout="${level:upperCase=true}"/>
    <attribute name="message" layout="${message}" />
  </layout>
</target>

Serilog

能够实现结构化日志的类库除了NLog之外,其它较常用的当属Serilog。

与NLog相比,Serilog省去了配置文件,直接使用代码,实现方式更加简洁。

var position = new { Latitude = 25, Longitude = 134 };
var elapsedMs = 34;

var log = new LoggerConfiguration()
    .WriteTo.Console(new JsonFormatter())
    .CreateLogger();
log.Information("Processed {@Position} in {Elapsed:000} ms.", position, elapsedMs);

执行结果:

{"Timestamp":"2018-12-22T17:15:23.6389082+08:00","Level":"Information","MessageTemplate":"Processed {@Position} in {Elapsed:000} ms.","Properties":{"Position":{"Latitude":25,"Longitude":134},"Elapsed":34},"Renderings":{"Elapsed":[{"Format":"000","Rendering":"034"}]}}

原文地址:https://www.cnblogs.com/kenwoo/p/9906185.html

时间: 2024-08-01 15:37:08

.NET Core开发日志——结构化日志的相关文章

Asp.Net Core中利用Seq组件展示结构化日志功能

在一次.Net Core小项目的开发中,掌握的不够深入,对日志记录并没有好好利用,以至于一出现异常问题,都得跑动服务器上查看,那时一度怀疑自己肯定没学好,不然这一块日志不可能需要自己扒服务器日志来查看,果然,很多东西没掌握,至此,花点时间看了下日志的相关操作.利用日志服务来查看日志数据. 本文地址:https://www.cnblogs.com/CKExp/p/9246788.html 本文Demo的地址:https://gitee.com/530521314/LogPanel.git 一.日志

海量结构化日志分析系统

背景 日志,角色不同,出发点和认识的角度也不同 RD使用日志,首先是为了调试程序,当程序上线后,日志是为了记录err和trace. PM可以通过日志分析,可以得出业务指标相关的统计情况. 日志的作用大致有三:异常.trace.统计. 日志使用的痛点 使用日志时大部分的场景或特点如下: 1.日志为纯文本,即可读. 2.日志分散在各个机器上,或者同步到某一台机器. 3.某某发现一个问题,让某某去查log. 这里有几个问题,或者说提高点 1.文本冗余度太大,浪费资源,如果转换为二进制,预估有5倍的收益

SQL Server 最小化日志操作解析,应用[手稿]

Sql Server 中数据库在BULK_LOGGED/SIMPLE模式下的一些操作会采用最小化日志的记录方式,以减小tran log落盘日志量从而提高整体性能. 这里我简单介绍下哪些操作在什么样的情况下会最小化日志记录.以及现实生产环境中如何应用最小化日志. 概念:SQL Server在满足相应条件的基础上时进行一些特定的操作如Rebuild Index时会进行最小化Tran Log记录操作,从而改善系统性能. 注意:含最小化操作日志操作段日志无法按时间点恢复(point in time) 需

SQL Server 最小化日志操作解析,应用

Sql Server 中数据库在BULK_LOGGED/SIMPLE模式下的一些操作会采用最小化日志的记录方式,以减小tran log落盘日志量从而提高整体性能. 这里我简单介绍下哪些操作在什么样的情况下会最小化日志记录.以及现实生产环境中如何应用最小化日志. 概念:SQL Server在满足相应条件的基础上时进行一些特定的操作如Rebuild Index时会进行最小化Tran Log记录操作,从而改善系统性能. 注意:含最小化操作日志操作段日志无法按时间点恢复(point in time) 需

ASP.NET Core 开发-Logging 使用NLog 写日志文件

ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 .NET Core 和 ASP.NET Core . ASP.NET Core已经内置了日志支持,可以轻松输出到控制台. 学习Logging 组件的相关使用,使用NLog 将日志写入到文件记录. Logging 使用 新建一个 ASP.NET Core 项目,为了方便,我选择Web 应用程序,改身份验证 改为 不进行身份验证. 新建好以后,会自动引用好对应的 类库.这样我们就可以直接使用 Logge

Hadoop经典案例Spark实现(七)——日志分析:分析非结构化文件

相关文章推荐 Hadoop经典案例Spark实现(一)--通过采集的气象数据分析每年的最高温度 Hadoop经典案例Spark实现(二)--数据去重问题 Hadoop经典案例Spark实现(三)--数据排序 Hadoop经典案例Spark实现(四)--平均成绩 Hadoop经典案例Spark实现(五)--求最大最小值问题 Hadoop经典案例Spark实现(六)--求最大的K个值并排序 Hadoop经典案例Spark实现(七)--日志分析:分析非结构化文件 1.需求:根据tomcat日志计算ur

.NET Core开发日志——RequestDelegate

本文主要是对.NET Core开发日志--Middleware的补遗,但是会从看起来平平无奇的RequestDelegate开始叙述,所以以其作为标题,也是合情合理. RequestDelegate是一种委托类型,其全貌为public delegate Task RequestDelegate(HttpContext context),MSDN上对它的解释,"A function that can process an HTTP request."--处理HTTP请求的函数.唯一参数,

.NET Core开发日志——Entity Framework与PostgreSQL

Entity Framework在.NET Core中被命名为Entity Framework Core.虽然一般会用于对SQL Server数据库进行数据操作,但其实它还支持其它数据库,这里就以PostgreSQL作为例子. PostgreSQL PostgreSQL可以选用原生系统与Docker两种安装方式. Official Docker Package 在应用程序工程中添加相关的引用. dotnet add package Npgsql.EntityFrameworkCore.Postg

.Net Core开发日志——从搭建开发环境开始

.Net Core自2016年推出1.0版本开始,到目前已是2.1版本,在其roadmap计划里明年更会推出3.0版本,发展不可不谓之迅捷.不少公司在经过一个谨慎的观望期后,也逐步开始将系统升级至最新的.Net Core平台,所以现在开始进行.Net Core开发可谓正当其时. 因为.Net Core支持Windows系统以外的Linux与Mac系统,在选择开发环境时,并不需要局限在原有的Windows平台,这里我选用了Mac平台. 开发硬件设备是一台14年款的Apple Macbook Air