使用当前的Serilog ILogger实例将消息格式化为字符串(但不打印)

时间:2019-12-02 22:26:29

标签: c# serilog

我有一个自定义LogEntry类,该类旨在简化序列化。对要发送给用户的对象进行操作时,将发生一些日志条目。我也想将那些相同的条目发送到已配置的控制台/任何serilog接收器。我当前的方法如下:

public static void Info(this Case c, ILogger log, string message, params object[] values)
{
    log.Information(message, values);
    var formattedMessage = string.Empty; // TODO: use serilog to get the string.
                                         // This is what I'm asking for help on!
    var entry = new LogEntry
    {
        LogLevel = LogLevel.Info,
        Message = formattedMessage,
        PhaseType = c.CurrentPhase // <- it would be convenient if I could enrich
                                   //    the current serilog log with this info, 
                                   //    but I don't know how to do that either.
    };

    c.Log.Add(entry);
}

我的Case类是一个POCO,准备发送给newtonsoft进行序列化。为了完整起见,Case类包含以下定义:

public class Case
{
    // ...

    public List<LogEntry> Log { get; set; } = new List<LogEntry>();
}

也许我的方法是完全错误的。希望我已经提供了足够的背景信息来解释我要完成的工作。如果这个问题使我走得更开心:我如何为ILogger实例创建自定义临时接收器?

1 个答案:

答案 0 :(得分:1)

一种选择是收集由记录器调用创建的Serilog LogEvent,并使用它们来构造呈现的消息。

这是总体思路的可执行草图。

using System;
using System.Collections.Generic;
using Serilog;
using Serilog.Core;
using Serilog.Events;

// dotnet add package Serilog.Sinks.Console

class LogEventCollection : ILogEventEnricher
{
    // Note, this is not threadsafe
    public List<LogEvent> Events { get; } = new List<LogEvent>();

    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory _)
    {
        Events.Add(logEvent);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .CreateLogger();

        var collection = new LogEventCollection();

        // Create an `ILogger` with the collector wired in. This
        // also works with `LogContext.Push()`.
        var collected = Log.ForContext(collection);

        collected.Information("Hello");
        collected.Information("World");

        // One entry for each call above
        foreach (var evt in collection.Events)
        {
            Console.WriteLine(evt.RenderMessage(null));
        }
    }
}

输出:

[14:23:34 INF] Hello
[14:23:34 INF] World
Hello
World