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中可以使用下列函数:
Function | Description |
---|---|
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“