1

Microsoft.Extensions.Logging当我想存储一个短(<200 个字符)参数化字符串时,我的 ASP.NET Core 2.x Web 应用程序习惯性地使用它来执行“跟踪”式日志记录。这些记录的事件与围绕 Serilog 等结构化日志系统构建的工具和生态系统配合得很好。

例如

public IActionResult DisplayCustomers(String customerName, String country)
{
    this.logger.LogInformation( "Search performed for customers named {name} in {country}.", customerName, country );
}

StringBuilder但是,我的应用程序还需要记录由应用程序使用以及由第三方组件生成的类似文本块构建的较大的文本块 (2-3KB) ,通常这些会消耗IProgress<String>该输出许多短字符串值的方式类似于临时使用Console.WriteLine.

例如

// Backend method (no structured logging available):
public void ProcessData(LotsOfData data, IProgress<String> report)
{
    Stopwatch sw = Stopwatch.StartNew();
    for( Int32 i = 0; i < data.Records.Count; i++ )
    {
        if( i % 500 == 0 ) report.Report( String.Format( "{0}ms - Processed {1} records.", sw.ElapsedMilliseconds, i ) );

        if( data.Records[i].Foo )
        {
            // (send job off to SQL Server and get back SPROC output via PRINT and RAISERROR)
            String sprocRaiseErrorOutput = ...
            report.Report( "Sproc output: " +  sprocRaiseErrorOutput );
        }

        if( data.Records[i].Bar ) report.Report( "Contents of bar: " +  data.Records[i].Bar.Text );
    }
    report.Report( "{0}ms - Completed.", sw.ElapsedMilliseconds );
}

class StringBuilderProgress : IProgress<String>
{
    private StringBuilder sb;
    public StringBuilderProgress(StringBuilder sb) { this.sb = sb; }

    public void Report(String value) { this.sb.AppendLine( value ); }
}

// Frontend method:
public IActionResult ProcessData(LotsOfData data)
{
    StringBuilder sb = new StringBuilder();
    StringBuilderProgress sbp = new StringBuilderProgress( sb );

    backendService.ProcessData( data, sbp );

    this.logger.LogInformation( "Process data ran: {report}", sb.ToString() );
}

...这会产生一个包含有用信息并且需要单独查看的大型非结构化文本 blob,但它不适合现有的结构化日志记录工具。

ILogger我认识到一个通用的解决方案是为该实现编写一个包装器IProgress<String>- 但这种方法存在一些问题:

  • 原始文本块中的每个输出行都成为一个结构化对象,受其自身的附加属性的限制,这些属性会显着增加日志的大小。
  • 这会导致重复数据,例如结构化日志系统会添加时间戳,但文本也已经包含秒表时间值。
  • 通常,文本 blob 包含诸如用于框和指示处理区域的 ACII-art 之类的内容,并且每行缩进以表示更深层次的处理 - 如果每行单独存储且独立于其文本上下文,则此信息将丢失。
    • 只包含 ASCII 艺术矩形框的第一行的日志条目有什么用?

Serilog 或 MEL 中是否有专门处理文本 blob 的方法?比如将它们输出到自己的文件中?

4

1 回答 1

0

您可以很容易地实现一个接收器来解析输出(抱歉,在 C# 中没有这个),因为您认为合适并适当地渲染,无论是您自己的形状文件还是日志。或者,您可以将内容作为属性隔离到日志条目中,然后通常使用那里提供的过滤机制在接收器和/或日志链中处理它们(更深入的示例)。

  • 在自定义接收器中,您可以访问以Serilog.Events.LogEvent几乎不可变的形式保存结构的 a ,但承认可以添加/删除属性。

    因此,您应该能够提取嵌入式属性并将它们写入单独的日志(并在允许它继续之前从 LogEvent 中删除它们)。如果您在Async接收链中执行此操作,它也不会影响作者的性能。

  • 另一种选择是使用各种可能的再现来呈现为json ,然后在带外对自己进行后处理

  • 最后,如果你很好地标记了东西和/或有与项目相关的相关识别标记,那么像Seq这样的东西是为了有效地解析这样的东西而构建的(尽管我不知道有一种方法可以在那里将东西呈现为固定宽度格式)(东西也会在商店等中被压缩,并且始终保留完整的事件)

于 2019-02-02T07:36:45.920 回答