如何从logevent获取格式化输出

时间:2018-01-15 18:34:30

标签: serilog

在WriteTo.Observer方法中,我希望在使用格式化模板呈现时传递格式化的日志消息。我怎么能做到这一点? 感谢

class Program
{
    static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .WriteTo.LiterateConsole()
            .WriteTo.RollingFile("log-{Date}.txt")
            .WriteTo.Observers(events => events.Do(evt => { Console.WriteLine($"Observed event {evt.MessageTemplate.Text}"); }).Subscribe())
            .WriteTo.Observers(events => events.Do(evt => { LogHandler(evt.MessageTemplate.Text);}).Subscribe())
            .CreateLogger();

        Log.Logger.Information("Log msg from Main");
        Console.ReadLine();
    }

    public static void LogHandler(string logMsg)
    {
        Console.WriteLine("LogHandler: " + logMsg); //I want the complete formatted log message as it would appear in a file i.e. "[10:20:14 INF] Log msg from DoNothing"
    }
}

1 个答案:

答案 0 :(得分:4)

我设法解决了这一切以及我对Serilog的其他几个问题。

我最初发布了关于NLog的this question,在解决它的过程中,我发现了Serilog。我很高兴我做到了。

这个答案说明了几个概念:

1。)从Logger中调用自定义处理程序

2.。)格式化日志消息

3.。)在日志消息中包含调用方法名称。感谢和归功于@ his answer found here的@ MovGP0。

class Program
{
    static void Main(string[] args)
    {
        var outputTemplate = "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}in method {MemberName} at {FilePath}:{LineNumber}{NewLine}{Exception}{NewLine}";
        Serilog.Formatting.Display.MessageTemplateTextFormatter tf = new Serilog.Formatting.Display.MessageTemplateTextFormatter(outputTemplate, CultureInfo.InvariantCulture);

        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .WriteTo.CustomSink(tf, LogHandler)
            .CreateLogger();

        Log.Logger.Here().Information("Hello world");
        Console.ReadLine();
    }

    public static void LogHandler(string logMsg)
    {
        Console.WriteLine("LogHandler: " + logMsg); 
    }
}


public class CustomSink : ILogEventSink
{
    private readonly ITextFormatter _formatter;
    private readonly Action<string>[] _handlers;

    public CustomSink(ITextFormatter formatter, params Action<string>[] handlers)
    {
        _formatter = formatter;
        _handlers = handlers;
    }

    public void Emit(LogEvent logEvent)
    {
        var buffer = new StringWriter(new StringBuilder(256));
        _formatter.Format(logEvent, buffer);
        string message = buffer.ToString();

        foreach (Action<string> handler in _handlers)
            handler(message);
    }
}


public static class MySinkExtensions
{
    public static LoggerConfiguration CustomSink(
              this LoggerSinkConfiguration loggerConfiguration,
              ITextFormatter formatter = null, params Action<string>[] handlers)
    {
        return loggerConfiguration.Sink(new CustomSink(formatter, handlers));
    }


    public static ILogger Here(this ILogger logger,
    [CallerMemberName] string memberName = "",
    [CallerFilePath] string sourceFilePath = "",
    [CallerLineNumber] int sourceLineNumber = 0)
    {
        return logger
            .ForContext("MemberName", memberName)
            .ForContext("FilePath", sourceFilePath)
            .ForContext("LineNumber", sourceLineNumber);
    }

}