我有一个自定义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
实例创建自定义临时接收器?
答案 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