6

I have a ASP .NET Core application and i am trying to enrich the Serilog logger with a property and pass it throghout method calls. I have used Serilog.Context to enrich it to no avail, the property is not present in the log.

Program

Log.Logger = new LoggerConfiguration().Enrich.FromLogContext()
                .WriteTo.File(logpath)
                .CreateLogger();

Controller

public class SomeController{

   public ILogger logger=Log.ForContext<SomeController>();
   private SomeService Service;

   public SomeController(SomeService serv)
   {
      this.service=serv;
   }

   [HttpGet]
   public async Task DoSomething()
   {
          string corellationId=Guid.NewGuid().ToString();
          LogContext.PushProperty("id",corellationId);
          service.Run();
    }
}

Service

class SomeService
{
   private ILogger logger=Log.ForContext<SomeService>();
   public void Run()
   {
       logger.Information("I AM NOT SEEING the ID from upstream !");
   }
}

Basically i want the logs of SomeService to have the id provided upstream (Controller action). What i want:

"[id] [value]"+ "[SomeService log]" 

P.S The service is injected via dependency injection if it matters.

Bercovici Adrian
  • 8,794
  • 17
  • 73
  • 152

1 Answers1

13

You need to use the Properties token in your outputTemplate, e.g.

var mt = "{LogLevel:u1}|{SourceContext}|{Message:l}|{Properties}{NewLine}{Exception}"

when you format the output for your sink e.g.:

 .WriteTo.File(logpath, outputTemplate: mt)

(ASIDE: You should be using the LogContext.Push return value)

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
  • So in order for me to put a `string` inside the format would a form like this suffice : `"{Timestamp:Yy:Mm:dd HH:mm:ss} [{Level:u3}] {corellationId} {Message}` ? – Bercovici Adrian Nov 27 '19 at 14:13
  • 2
    yes, if you always do a `using LogContext.Push("corellationId",value)`, then that'll show the value per message (the `{Properties}` token shows all properties not referenced either in the message or the message template) – Ruben Bartelink Nov 27 '19 at 14:52
  • I just want to bind the property once per request , when my request enters a `ASP NET Controller` and then be present in all logs from nested methods. – Bercovici Adrian Dec 02 '19 at 15:17
  • You need to use LogContext.Push for that - this can be done in middleware, or by doing a `using (LogContext.Push("req",id))` in your controller etc. Best to got find a good tutorial on Serilog LogContext – Ruben Bartelink Dec 02 '19 at 16:02