13

I'm new to Serilog - trying it out to see if it will help. I'm using Serilog v2 and Serilog.Sinks.MsSqlServer v5

I have the following console app code:

static void Main(string[] args)
    {
        var logger = CreateLogger();

        var employee = new Person()
        {
            Name = "Rob",
            Age = 45
        };

        logger.Debug("Employee details {Employee}", employee);

        Console.ReadKey();

    }

private static ILogger CreateLogger()
    {

        string levelString = SSOSettingsFileManager.SSOSettingsFileReader.ReadString(
                            "LCC.Common", "Serilog.MinimumLevel");

        SerilogLevel level = (SerilogLevel)Enum.Parse(typeof(SerilogLevel), levelString);

        string conString = SSOSettingsFileManager.SSOSettingsFileReader.ReadString(
                            "LCC.Common", "Serilog.ConnectionString");

        var levelSwitch = new LoggingLevelSwitch();
        levelSwitch.MinimumLevel = (Serilog.Events.LogEventLevel)level;

        return new LoggerConfiguration()
            .MinimumLevel.ControlledBy(levelSwitch)
            .WriteTo.MSSqlServer(connectionString: conString, tableName: "Logs", autoCreateSqlTable: true)
            .CreateLogger();
    }

I would have expected the details of Person to be logged i.e. Name Rob and Age 45. However, I find the following logged to the Properties column on my Sql Server Sink:

<properties><property key='Employee'>ConsoleApplication1.Person</property></properties>

Where did I go wrong?

3 Answers 3

33

here is Serilog documentation

For this task, Serilog provides the @ destructuring operator.

var sensorInput = new { Latitude = 25, Longitude = 134 };
Log.Information("Processing {@SensorInput}", sensorInput);

as you can see to do destructuring you have to set @ before key name. This is missed in your sample code

logger.Debug("Employee details {Employee}", employee);
Sign up to request clarification or add additional context in comments.

Comments

0

@oleksa's answer worked for me and helped me realize what I needed to do in my case of trying to log some info from a controller using the Log.ForContext(...) approach. Here are a couple examples:

Option 1:

I prefer this approach since it keeps the view cleaner in the log aggregator (Seq in my case).

// Inside controller GET method

Employee employee = await myService.GetData();

// Need to set the `destructureObjects` flag to `true`
Log.ForContext<Employee>(Serilog.Events.LogEventLevel.Information, "Employee", employee, true)
   .Information("Employee Information");

Option 2:

// Inside controller GET method

Employee employee = await myService.GetData();

Log.Information("Employee Information {@Employee}", employee);

.NET 6 & Serilog 5.0

Comments

-4

The logging framework is going to call ToString on the object passed to it. If you want the details logged, one option would be to override the ToString method to serialize the object (assumes reference to Newtonsoft.JSON library):

// in Person.cs
public override string ToString()
{
    return JsonConvert.SerializeObject(this);
}

1 Comment

I thought the idea of serilog was to avoid the need for such explicit serialisation - it is a structured logging framework

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.