serilog / serilog-sinks-email

A Serilog sink that writes events to SMTP email
Apache License 2.0
70 stars 68 forks source link

Serilog Email sink is not sending emails #44

Closed xantari closed 6 years ago

xantari commented 6 years ago
            Log.Logger = new LoggerConfiguration()
                .WriteTo.RollingFile(AppSettings.SerilogErrorLoggingFilePattern)
                .WriteTo.ColoredConsole()
                .WriteTo.Email(new EmailConnectionInfo()
                    {
                        FromEmail = AppSettings.ErrorEmailFrom,
                        EnableSsl = AppSettings.SmtpInfo.Network.EnableSsl,
                        EmailSubject = "FaxFormCreator Error",
                        IsBodyHtml = true,
                        MailServer = AppSettings.SmtpInfo.Network.Host,
                        NetworkCredentials = !(string.IsNullOrEmpty(AppSettings.SmtpInfo.Network.UserName)) ? new NetworkCredential(AppSettings.SmtpInfo.Network.UserName, AppSettings.SmtpInfo.Network.Password) : null,
                        Port = AppSettings.SmtpInfo.Network.Port,
                        ToEmail = AppSettings.ErrorOperatorEmail
                    },
                    restrictedToMinimumLevel: LogEventLevel.Information)
                .CreateLogger();

Using the above code, no email is ever sent. Works fine via regular SMTP .NET connection.

How to debug?

xantari commented 6 years ago

Also, I am running different log statements (Log.Information, Log.Error). But it doesn't send.

fredjeck commented 6 years ago

Hello, Email Sink is relying on the PeriodicBatching Sink which following its configuration buffers the logs and periodically (or when you hit the batchPostingLimit threshold) writes them to the sink. That means that before your application is closing you have to explicitely flush your sinks (overall its a good practice) to trigger a write : just call the Log.CloseAndFlush(); method in a finally block

try{
    //Boring application code
}catch(Exception e){
    Log.Fatal(e, "Woops, something went wrong");
}finally{
    Log.CloseAndFlush();
}
hellfirehd commented 6 years ago

If an error is occurs while Serilog is attempting to send the email (due to a configuration issue, or error connecting to the server, etc.) then Serilog just swallows it. If you want to see the error/exception you have to provide someplace for Serilog to dump it when you initialize logging:

Serilog.Debugging.SelfLog.Enable(Console.WriteLine);

or

var selfLogMessages = new List<String>();
Serilog.Debugging.SelfLog.Enable(selfLogMessages.Add);
Inrego commented 6 years ago

In the following case, no emails are sent at all, even with 100 events written to the log:

static void Main(string[] args)
{
    try
    {
        Serilog.Debugging.SelfLog.Enable(Console.WriteLine);
        var emailInfo = new EmailConnectionInfo
        {
            EmailSubject = "Serilog Email Bug",
            EnableSsl = false,
            FromEmail = "fromEmail",
            MailServer = "smtpServer",
            ToEmail = "toEmail",
            NetworkCredentials = new NetworkCredential("username", "password")
        };

        var logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .WriteTo.Email(emailInfo)
            .CreateLogger();

        for (var i = 1; i <= 100; i++)
        {
            logger.Information($"Log #{i}");
        }
    }
    finally
    {
        Log.CloseAndFlush();
    }
}
nblumhardt commented 6 years ago

@Inrego for Log.CloseAndFlush() to work, you need to assign the shared Log.Logger; a using block will work otherwise:

static void Main(string[] args)
{
    Serilog.Debugging.SelfLog.Enable(Console.WriteLine);
    var emailInfo = new EmailConnectionInfo
        {
            EmailSubject = "Serilog Email Bug",
            EnableSsl = false,
            FromEmail = "fromEmail",
            MailServer = "smtpServer",
            ToEmail = "toEmail",
            NetworkCredentials = new NetworkCredential("username", "password")
        };

    using (var logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .WriteTo.Email(emailInfo)
            .CreateLogger())
    {
        for (var i = 1; i <= 100; i++)
        {
            logger.Information($"Log #{i}");
        }
    }
}
Inrego commented 6 years ago

Aha, that makes sense. Thank you!

nblumhardt commented 6 years ago

Closing this thread as it's diverged a bit :+1:

djangohunt commented 4 years ago

Using this example code, I still can't get the email sink to work. I don't see any errors or exceptions, I just don't receive any emails.