0

I am using serilog in my Net 5 project and I want to set the subject dynamically in code before the email is sent. I read that from version 2.2.0 this should be possible but I can't find any example of how to do this.

this is my serilog settings

Log.Logger = new LoggerConfiguration()
                .WriteTo.File(path + "TTLog_" + time + ".txt")
                .WriteTo.Console(theme: SystemConsoleTheme.Literate)
                .WriteTo.Email(new EmailConnectionInfo {
                    FromEmail = FromEmail,
                    ToEmail = ToEmail,
                    MailServer = SMTP_Server,
                    NetworkCredentials = new NetworkCredential {
                        UserName = SMTP_Username,
                        Password = SMTP_Password
                    },

                    EnableSsl = false,
                    Port = SMTP_Port,
                    EmailSubject = "Test Subject",

                },
                outputTemplate: "[{Level:u4}] {Message}{NewLine}{Exception}{Timestamp}"
                ).CreateLogger();

In my code I want to update the EmailSubject after the LoggerConfiguration is set. how can I do that?

Update as requested in comments:

Log.Logger = new LoggerConfiguration()
                .WriteTo.File(path + "TTLog_" + time + ".txt")
                .WriteTo.Console(theme: SystemConsoleTheme.Literate)
                .WriteTo.Email(new EmailConnectionInfo {
                    FromEmail = FromEmail,
                    ToEmail = ToEmail,
                    MailServer = SMTP_Server,
                    NetworkCredentials = new NetworkCredential {
                        UserName = SMTP_Username,
                        Password = SMTP_Password
                    },

                    EnableSsl = false,
                    Port = SMTP_Port,
                    EmailSubject = "{Msg}"
                },
                outputTemplate: "[{Level:u4}] {Message}{NewLine}{Exception}{Timestamp}"
                ).Enrich.FromLogContext()
            .CreateLogger();

then if I use this it works, the email subject is "TT Log - Updated A"

string x = "A";
Serilog.Context.LogContext.PushProperty("Msg", "TT Log - Updated " + x);

but if I do this it does not work, the message subject is empty

string x = "A";
Log.Information("Test");
Serilog.Context.LogContext.PushProperty("Msg", "TT Log - Updated " + x);

How do I dynamically set the email subject from anywhere in my code?

Thomas Adrian
  • 3,543
  • 6
  • 32
  • 62
  • What do you want to update the subject based on? What conditions cause it to change? – mason Jun 25 '21 at 14:14
  • well, my code does a lot, I may want the subject to say how many lines I processed or if the code was successful or not – Thomas Adrian Jun 25 '21 at 14:16
  • Did you look at [the source code](https://github.com/serilog/serilog-sinks-email/blob/3d2b58d16cb5d50a886d36b106c20569673815f3/src/Serilog.Sinks.Email/LoggerConfigurationEmailExtensions.cs#L97)? You can specify template properties for the email subject. – mason Jun 25 '21 at 14:18
  • I read about that feature but I can't find an example how to do it. I have not digged into the serilog code, I do enough digging in my own code :-) – Thomas Adrian Jun 25 '21 at 14:19
  • Well it's open source code, and it's readily available to you to dig through. Moreover, it's easy code. There's only a few classes and the code is nicely laid out. Don't be afraid to at least take a look at it. As for the template properties, it looks like you're already doing something similar with your outputTemplate. Use that same syntax on your EmailSubject, but put property names that you care about such as LinesProcessed or OperationSuccessful or whatever names you've set for the properties you log on your events. – mason Jun 25 '21 at 14:28
  • I set this in the configuration: EmailSubject = "{Msg}", how do I set Msg? – Thomas Adrian Jun 25 '21 at 17:09
  • Do you know how Serilog works? You pass objects to Serilog like `Log.Information("Message received {msg}", msg);` or you can add properties without putting them in the message template, see [this answer](https://stackoverflow.com/questions/48591809/how-to-add-my-own-properties-to-serilog-output-template/48594025#48594025). – mason Jun 25 '21 at 17:27
  • added this -> EmailSubject = "{Msg}" and this -> Enrich.FromLogContext() and then this -> Serilog.Context.LogContext.PushProperty("Msg", "Log - Updated " + updated); only works before I call any Log.information() – Thomas Adrian Jun 25 '21 at 18:02
  • I don't understand your last comment. Is everything working now, or are you still having trouble still? If you're having trouble, you need to clearly explain what the issue is and provide a [mcve]. – mason Jun 25 '21 at 18:39
  • You are using LogContext.PushProperty wrong. That returns an IDisposable, which you should wrap in a using block. Any logged statements in the using block would include the property, any statements outside of it would not. Again, review the answer I linked you to. – mason Jun 26 '21 at 16:16
  • I already know how not to do it, not sure why you don’t provide the answer – Thomas Adrian Jun 26 '21 at 16:35

1 Answers1

1

If problem has not resolved yet,maybe you can try serilog-sinks-map

Sample code is using .Net 6

// Program.cs
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
    .Enrich.FromLogContext()
    .WriteTo.Map("Msg", "default msg", (msg, wt) => wt.Email(new EmailConnectionInfo()
    {
        MailServer = "smtp.gmail.com",
        Port = 465,
        EnableSsl = true,
        NetworkCredentials = new NetworkCredential("xxx.com", "xxxxx"),
        EmailSubject = msg,
        FromEmail = "xxx@gmail.com",
        ToEmail = "xxx@gmail.com",
    }))
    .CreateLogger();

Then, you can use static method Log to test.

Log.Fatal("Host terminated unexpectedly");        
Log.Fatal("Host terminated unexpectedly {Msg}", "Test Subject");
Log.Fatal("Host terminated unexpectedly {Msg}", "Test2 Subject");
L1uXO330B7
  • 11
  • 4