Serilog.Sinks.Email - 没有失败的迹象?

Serilog.Sinks.Email - No Indication of Failure?

我一直在使用 Serilog.Sinks.Email,我注意到(除了我没有收到电子邮件这一事实),当我执行日志语句。即使我为 MailServer 放入垃圾,Log 语句也像成功一样执行。

我已经尝试了 SelfLog 语句,但在我的输出 window 中什么也看不到。

Serilog.Debugging.SelfLog.Enable(msg => Debug.WriteLine(msg));

我已经添加了 SymbolSource (http://www.symbolsource.org/Public/Wiki/Using),并且能够单步执行 Serilog 的代码,但再次没有捕获到异常。

Serilog 真的没有给出任何错误指示,还是我遗漏了什么?

使用:.NET Framework 4.6.2、Serilog 2.8、Serilog.Sinks.Email 2.3

示例代码:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Email(new EmailConnectionInfo
    {
        FromEmail = "xxx",
        ToEmail = "xxx",
        MailServer = "smtp.xxx.com",
        EmailSubject = "My Test"
    }
    ).CreateLogger();

Log.ForContext<Program>().Error("Test Number {Parm}", "1");

写入 Serilog 记录器应该是一个安全的操作并且永远不会抛出异常,by design,因此发送电子邮件时发生的任何异常只会出现在 SelfLog -在您的情况下,它会写入 Debug 控制台。

现在,您甚至没有在 SelfLog 中看到异常的原因是因为电子邮件是通过 Serilog.Sinks.Email are sent asynchronously 发送的,并且您的程序在 Sink 有机会发送之前终止电子邮件。

在您的程序终止之前,您需要调用 Log.CloseAndFlush() 以便在应用程序关闭之前发送所有日志。

static void Main(string[] args)
{
    Serilog.Debugging.SelfLog.Enable(msg => Console.WriteLine(msg));

    Log.Logger = new LoggerConfiguration()
        .WriteTo.Email(...)
        .CreateLogger();

    try
    {
        Log.ForContext<Program>().Error("Test Number {Parm}", "1");

        // ...
    }
    finally
    {
        Log.CloseAndFlush();
    }
}

这样您就可以通过 SelfLog 查看您正在编写的错误消息。

您可以在文档中阅读更多相关信息:Lifecycle of Loggers


ps:如果你正在记录的操作足够重要以至于你想保证它成功(如果不成功则抛出异常)那么你应该使用Audit Logging,即使用 .AuditTo.Email(...) 而不是 .WriteTo.Email(...)