使用表达式自定义Serilog输出格式

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用表达式自定义Serilog输出格式相关的知识,希望对你有一定的参考价值。

Serilog是.NET Core中常用的结构化日志类库,透过logging API可以轻松的记录应用程式中对象属性,方便快速进行logging内容进行查询与分析,并将其记录内容通过指定方式输出。

今天,介绍一个Nuget包Serilog.Expressions,它可以更容易地控制Serilog事件如何格式化输出。

功能介绍

Serilog.Expressions包含用于文本格式化的ExpressionTemplate类。ExpressionTemplate实现了ITextFormatter,因此它可以与任何基于文本的Serilog接收器一起工作,包括控制台、文件、调试窗口和电子邮件。

1.使用参数

ExpressionTemplate中可以使用下列参数:

  • SourceContext - ILogger< T > 中T对应的类型名

  • @t - 事件时间

  • @m - 格式化后的消息

  • @mt - 原始的消息模板

  • @l - 事件级别

  • @x - 异常

  • @p - 传入参数的字典

  • @i - 事件Id

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console(new ExpressionTemplate("[{@t:HH:mm:ss} {@l:u3} {SourceContext}] {@m}\\n{@x}"))
    .CreateLogger();
Log.Information("公众号“My IO”!");

2.使用函数

ExpressionTemplate中可以使用下列函数:

FunctionDescription
Coalesce(p0, p1, [..pN])返回第一个定义的非空参数。
Concat(s0, s1, [..sN])连接两个或多个字符串。
Contains(s, t)测试字符串“s”是否包含子字符串“t”。
ElementAt(x, i)按名称“i”检索“x”的属性,或按数字索引“i”检索“x”的数组元素。
EndsWith(s, t)测试字符串“s”是否以子字符串“t”结尾。
IndexOf(s, t)返回字符串“s”中子字符串“t”的第一个索引,如果子字符串未出现,则返回-1。
IndexOfMatch(s, p)返回字符串“s”中正则表达式“p”的第一个匹配项的索引,如果正则表达式不匹配,则返回-1。
IsMatch(s, p)测试正则表达式“p”是否与字符串“s”匹配。
IsDefined(x)如果表达式“x”有值,包括“null”,则返回“true”;如果“x”未定义,则返回“false”。
LastIndexOf(s, t)返回字符串“s”中子字符串“t”的最后一个索引,如果子字符串未出现,则返回-1。
Length(x)返回字符串或数组的长度。
Now()返回“DateTimeOffset.Now”。
Rest()在“ExpressionTemplate”中,返回一个对象,该对象包含模板或事件消息中未引用的事件属性。
Round(n, m)将数字“n”四舍五入到“m”小数位。
StartsWith(s, t)测试字符串“s”是否以子字符串“t”开头。
Substring(s, start, [length])返回从“start”到字符串结尾的字符串“s”的子字符串,或返回“length”字符的子字符串.
TagOf(o)返回捕获对象的“TypeTag”字段。
ToString(x, [format])将“x”转换为字符串,如果“x”是“IFormattable”,则应用格式字符串“format”。
TypeOf(x)返回一个描述“x”类型的字符串:如果“x”是标量且非空,或是“array”、“object”、“dictionary”、“null”或“undefined”,则返回.NET类型名。
Undefined()显式Undefined的值。
UtcDateTime(x)将“DateTime”或“DateTimeOffset”转换为UTC“DateTime”。

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console(new ExpressionTemplate("{IndexOf(@m,'My IO')}"))
    .CreateLogger();
Log.Information("公众号“My IO”!");

3.条件语句

可以使用{#if <表达式>}{#end}有条件地显示输出。条件{#if}也支持{#else if <表达式>}{#else}。例如,如果日志包含密码则不输出,避免泄露敏感数据:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console(new ExpressionTemplate("{#if @p['Password'] is not null } 不输出敏感数据 {#else} {@m} {#end}\\n"))
    .CreateLogger();

var user = new { Name = "张三", Password = "xxx" };
Log.Information("登录信息:{@Name} {@Password}", user.Name,user.Password);
Log.Information("登录信息:{@Name} ", user.Name);

4.循环

使用{#each}为@p这样的对象的所有成员重复执行。

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console(new ExpressionTemplate("{#each name, value in @p} {name} = {value}\\n{#end}"))
    .CreateLogger();

var user = new { Name = "张三", Password = "xxx" };
Log.Information("登录信息:{@Name} {@Password}", user.Name,user.Password);

结论

这里只是介绍了Serilog.Expressions部分常用功能,更多内容可以去https://github.com/serilog/serilog-expressions了解。

欢迎关注我的个人公众号”My IO“

以上是关于使用表达式自定义Serilog输出格式的主要内容,如果未能解决你的问题,请参考以下文章

向Serilog添加自定义属性

扩展.net日志框架Serilog的WriteTo

扩展.net日志框架Serilog的WriteTo

.Core中使用Serilog

如何在 Serilog 输出模板中创建可选属性?

无法将类型字符串隐式转换为 serilog.formatting.ITextformatter