Showing posts with label serilog logging in .net6. Show all posts
Showing posts with label serilog logging in .net6. Show all posts

Sunday, 29 May 2022

Serilog file logging in .Net 6

 

To read more about basics of serilog and setting up project and SQL logging using Serilog please see my previous post Serilog SQL logging

Further in the same solution we will add below setting for file logging.

We will have to add one more setting to write to file in Serilog section in appsettings.json as below

{
        "Name": "File",
        "Args": {
           "path": "c:\\Serilogs\\\\NkSerilogDemoLogs.log"
        }
}

as we can see from above setting that we need to provide path of the log file along with filename in path parameter. Here I have provided absolute path. This path can be an absolute or relative path. 


Now we have kept both SQL and File logging setting in appsettings.json so after running the application & generating error condition it will write logs to both SQL table & file as well. Below is the screenshot of logs written to the file.


Structure Logging

As you can see from above post it add logs in plain text. If you want structured logging in JSON format you just need to add formatter to setting defined above in appsettings.json. 

Instead of modifying existing file setting let me add one more section so that we will have both logging to file in simple format and logging to file in JSON format.

{
        "Name": "File",
        "Args": {
          "path": "C:\\Serilogs\\\\NkSerilogDemoLogs.log"
        }
      },
      {
        "Name": "File",
        "Args": {
          "path": "C:\\Serilogs\\\\NkSerilogDemoJSONLogs.log",
          "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog"
        }
      }

Now if we run application and observe the second file log you can see it is logged as json as below.










You can also see the source code for this demo project on github source code


Hope it helps you.

If you have any queries/suggestions feel free to comment.

Friday, 27 May 2022

Using Serilog logging in .Net 6

 

  About Serilog

ASP.NET Core has a built-in logging API that supports a wide variety of logging providers. The in-built logging API is available in Microsoft.Extensions.Logging namespace and works mostly all in-built and third-party logging providers.

Serilog is a third-party logging provider which can be used in ASP.NET Core and uses .NET Core standard API for logging.

Sinks are the targets where you want to send your logs and the most popular sinks are file and console targets.


Serilog in ASP.NET Core provides a structured logging framework.

When we have an application running on many servers and every server have say text file logging then it will be difficult to manually check log on every server and there can be mistakes scanning for errors manually.  So Log data should be easily accessible, readable. i.e. log should be structured which will allow the log reader to query data from the log store using named values.



Serilog Logging to SQL Server in .NET 6

Here I will explain how we can integrate Serilog in .NET6 application to log to SQL server database.

Create new .NET 6 "ASP.NET Core Web API" project (Open Visual Studio 2022 -> Select Create a new project -> "ASP.NET Core Web API" template -> Provide Project, Solution name -> select Framework as .NET 6.0 and other properties as in below screenshot)











This will create a default controller and other minimal code for API. If you just run the solution you can see the sample API method in swagger as below




Now in this solution we want to add logging using Serilog library.

For this install below 2 packages from Nuget manager

  • Serilog.AspNetCore
  • Serilog.Sinks.MSSqlServer 










appsettings.json

{

//Start: Added this settings for serilog

"Serilog": 
{
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
                    }
},

"WriteTo": [
{
"Name": "MSSqlServer",
"Args": {
"connectionString": "Data Source=DESKTOP-9OEV9UG;Initial Catalog=LogDb;Persist Security Info=True;;Integrated Security=true",
"tableName": "ApiLog",
"autoCreateSqlTable": false
}
}
]
},
//End: Added this settings for serilog

// Commented below default Logging settings, you can remove it
//"Logging": {
// "LogLevel": {
// "Default": "Information",
// "Microsoft.AspNetCore": "Warning"
// }
//},

"AllowedHosts": "*"
}

In .NET 6 Microsoft has removed the Startup.cs class, so we will be adding all configuration for serilog in Program.cs only. We need to add below highlighted lines in Program.cs

using Serilog;

var builder = WebApplication.CreateBuilder(args);

//start: serilog related configuration
Log.Logger = new LoggerConfiguration().CreateBootstrapLogger();
builder.Host.UseSerilog(((ctx, lc) => lc.ReadFrom.Configuration(ctx.Configuration)));
//end: serilog related configuration
var app = builder.Build();

//serilog related configuration
app.UseSerilogRequestLogging();


Modify controller method and include logger LogInformation and logger LogError to test Logging information message and error message. To test logging exception i am creating and throwing a sample exception. 

        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            try
            {
                _logger.LogInformation("Executing WeatherForecast Get method");
                throw new Exception("Sample user created exception.",new Exception("Sample inner exception"));
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = Random.Shared.Next(-20, 55),
                    Summary = Summaries[Random.Shared.Next(Summaries.Length)]
                })
               .ToArray();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, String.Format("Error/exception in WeatherForecast Get method. Error {0}",ex.Message));
                throw;
            }
        }





You can see above database records to see information and error messages getting logged.

---------------------

---------------------

You can see only the default columns are getting populated and user defined columns were not get populated.

If we want to populate say user defined column [correlationId] then we can do it in below steps

First we need to define columnOptionsSection/additionalColumns in "appsettings.json" as below

"Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "Microsoft.Hosting.Lifetime": "Information"
      }
    },

    "WriteTo": [
      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": "Data Source=DESKTOP-9OEV9UG;Initial Catalog=LogDb;Persist Security Info=True;;Integrated Security=true",
          "tableName": "ApiLog",
          "autoCreateSqlTable": false,
          "columnOptionsSection": {
            "additionalColumns": [
              {
                "ColumnName": "correlationId",
                "DataType": "varchar",
                "AllowNull": true,
                "DataLength": 500
              }
            ]
          }
        }
      }
    ]
  },


Now in controller method to LogInformation and LogError we need to add property correlationID in message so that it gets logged in corresponding column as below

 _logger.LogInformation("Executing WeatherForecast Get method with {correlationId} =", requestID.ToString());              

  _logger.LogError(ex, "Error/exception in WeatherForecast Get method. Error {error}, {correlationId} =", ex.Message, requestID.ToString());

           



You can also see the source code for this demo project on github source code


Hope it helps you.

If you have any queries/suggestions feel free to comment.