{"id":1884,"date":"2023-06-15T09:05:57","date_gmt":"2023-06-15T09:05:57","guid":{"rendered":"http:\/\/waqar-arshad.com\/?p=1884"},"modified":"2023-06-15T09:05:57","modified_gmt":"2023-06-15T09:05:57","slug":"serilog-logging-fundamental","status":"publish","type":"post","link":"http:\/\/waqar-arshad.com\/index.php\/2023\/06\/15\/serilog-logging-fundamental\/","title":{"rendered":"SeriLog &#8211; Logging Fundamental"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"1884\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><div class=\"pld-dislike-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-dislike-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"1884\" data-trigger-type=\"dislike\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-down\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-dislike-count-wrap pld-count-wrap\"><\/span>\r\n<\/div><\/div>\n<p><strong>What is Serilog?<\/strong><strong><\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/serilog.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">Serilog<\/a>&nbsp;is a .NET library that provides diagnostic logging to files, the console, and almost everywhere you would like.&nbsp;<\/p>\n\n\n\n<p>Serilog can be used in classic .NET Framework applications and for applications running on the latest and greatest .NET 6.<\/p>\n\n\n\n<p>One of the biggest strengths of Serilog is that it has been built with&nbsp;<a href=\"https:\/\/www.sumologic.com\/glossary\/structured-logging\/\" target=\"_blank\" rel=\"noreferrer noopener\">structured logging<\/a>&nbsp;in mind.<\/p>\n\n\n\n<p>You can find more information on&nbsp;<a href=\"https:\/\/serilog.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">Serilog\u2019s website<\/a>.<\/p>\n\n\n\n<p><strong>Why do I use Serilog?<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Now that we know more about Serilog let me tell you my personal experience with it.&nbsp;<strong>I used Serilog in a few applications with different logging requirements, and I was always satisfied with my results.<\/strong><\/p>\n\n\n\n<p>I cannot speak much about performance because I don\u2019t work with large distributed ultra-scalable applications, but&nbsp;<strong>the performance was never an issue<\/strong>&nbsp;in my use cases.<\/p>\n\n\n\n<p>I like Serilog\u2019s simple integration into .NET applications, the ease of use, how simple you can start, and what more advanced features are available and can be used later in your journey.<\/p>\n\n\n\n<p>Let\u2019s create an application and integrate Serilog.<\/p>\n\n\n\n<p><strong>Creating an ASP.NET Core Web API Project<\/strong><strong><\/strong><\/p>\n\n\n\n<p>In Visual Studio 2022, we create a&nbsp;<strong>new project based on the ASP.NET Core Web API<\/strong>&nbsp;project template.<\/p>\n\n\n\n<p>We choose&nbsp;<strong>SerilogDemo<\/strong>&nbsp;as the project name and, on the next dialog page, we stick with the defaults and use&nbsp;<strong>.NET 6<\/strong>.<\/p>\n\n\n\n<p>We click on&nbsp;<strong>Create<\/strong>&nbsp;and wait until Visual Studio generated the project for us.<\/p>\n\n\n\n<p><strong>Install Serilog<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Installing Serilog is simple. First, we open the NuGet Package Manager and search for the&nbsp;<a href=\"https:\/\/www.nuget.org\/packages\/Serilog.AspNetCore\/\" target=\"_blank\" rel=\"noreferrer noopener\">Serilog.AspNetCore<\/a>&nbsp;package and install the latest stable version.<\/p>\n\n\n\n<p>After a few seconds, Serilog is installed.<\/p>\n\n\n\n<p><strong>Configure Serilog-Logging in Program.cs<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Next, let\u2019s integrate Serilog into our application by registering it as a logging provider.<\/p>\n\n\n\n<p><strong>var<\/strong> logger = new LoggerConfiguration()<\/p>\n\n\n\n<p>.ReadFrom.Configuration(builder.Configuration)<\/p>\n\n\n\n<p>.Enrich.FromLogContext()<\/p>\n\n\n\n<p>.CreateLogger();<\/p>\n\n\n\n<p>builder.Logging.ClearProviders();<\/p>\n\n\n\n<p>builder.Logging.AddSerilog(logger);<\/p>\n\n\n\n<p>I insert a code snippet that defines a new LoggerConfiguration. We configure the configuration to read the application configuration from the application builder. We also enrich Serilog with the log context.<\/p>\n\n\n\n<p>Next, we clear all existing logging providers. The&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/aspnet\/core\/migration\/50-to-60?view=aspnetcore-6.0&amp;tabs=visual-studio#new-hosting-model\" target=\"_blank\" rel=\"noreferrer noopener\">WebApplication builder<\/a>&nbsp;adds, for example, the console logging provider, and we want to get rid of that.<\/p>\n\n\n\n<p>Last but not least, we add Serilog to the logging providers for our application and provide the configured LoggerConfiguration object as its sole argument.<\/p>\n\n\n\n<p><strong>Configure Serilog in appsettings.json<\/strong><strong><\/strong><\/p>\n\n\n\n<p>We configured the logger to use the settings from the application configuration. Let\u2019s open the&nbsp;<strong>appsettings.json<\/strong>&nbsp;file and configure Serilog.<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p><strong>&#8220;Logging&#8221;:<\/strong> {<\/p>\n\n\n\n<p><strong>&#8220;LogLevel&#8221;:<\/strong> {<\/p>\n\n\n\n<p><strong>&#8220;Default&#8221;:<\/strong> &#8220;Information&#8221;,<\/p>\n\n\n\n<p><strong>&#8220;Microsoft.AspNetCore&#8221;:<\/strong> &#8220;Warning&#8221;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>},<\/p>\n\n\n\n<p><strong>&#8220;AllowedHosts&#8221;:<\/strong> &#8220;*&#8221;,<\/p>\n\n\n\n<p><strong>&#8220;Serilog&#8221;:<\/strong> {<\/p>\n\n\n\n<p><strong>&#8220;Using&#8221;:<\/strong> [ &#8220;Serilog.Sinks.File&#8221; ],<\/p>\n\n\n\n<p><strong>&#8220;MinimumLevel&#8221;:<\/strong> {<\/p>\n\n\n\n<p><strong>&#8220;Default&#8221;:<\/strong> &#8220;Information&#8221;<\/p>\n\n\n\n<p>},<\/p>\n\n\n\n<p><strong>&#8220;WriteTo&#8221;:<\/strong> [<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p><strong>&#8220;Name&#8221;:<\/strong> &#8220;File&#8221;,<\/p>\n\n\n\n<p><strong>&#8220;Args&#8221;:<\/strong> {<\/p>\n\n\n\n<p><strong>&#8220;path&#8221;:<\/strong> &#8220;..\/logs\/webapi-.log&#8221;,<\/p>\n\n\n\n<p><strong>&#8220;rollingInterval&#8221;:<\/strong> &#8220;Day&#8221;,<\/p>\n\n\n\n<p><strong>&#8220;outputTemplate&#8221;:<\/strong> &#8220;[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {CorrelationId} {Level:u3}] {Username} {Message:lj}{NewLine}{Exception}&#8221;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>]<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>I insert a sample configuration. Let\u2019s take a look at it. First, there is the using property where we define an array of log targets. In Serilog, log targets are called&nbsp;<a href=\"https:\/\/github.com\/serilog\/serilog\/wiki\/Provided-Sinks\" target=\"_blank\" rel=\"noreferrer noopener\">sinks<\/a>. We configure an array with a single sink, the&nbsp;<strong>Serilog.Sinks.File<\/strong>&nbsp;sink.<\/p>\n\n\n\n<p>Next, we can configure log levels and, more importantly, the&nbsp;<strong>WriteTo<\/strong>&nbsp;section. In the WriteTo section, we configure information for the File sink. The name property with the value \u201cFile\u201d defines that the property provided in the \u201cArgs\u201d property will be used for the File sink.<\/p>\n\n\n\n<p>We configure the path where our log file should be written. The&nbsp;<strong>rollingInterval property<\/strong>&nbsp;defines when a new file should be created. And the&nbsp;<strong>outputTemplate<\/strong>&nbsp;defines the structure of the log output for each log statement.<\/p>\n\n\n\n<p><strong>Add a Log Statement in the WeatherForecastController<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Now that Serilog is configured, we open the WeatherForecastController class and insert a log statement in the Get method.<\/p>\n\n\n\n<p>_logger.LogInformation(&#8220;Weather Forecast executing&#8230;&#8221;);<\/p>\n\n\n\n<p>Now let\u2019s start the application.<\/p>\n\n\n\n<p><strong>Sending a Get Request<\/strong><strong><\/strong><\/p>\n\n\n\n<p>We use&nbsp;<a href=\"https:\/\/swagger.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Swagger<\/a>&nbsp;to send a simple get request to the&nbsp;<strong>WeatherForecast<\/strong>&nbsp;controller. Open the entry in the endpoints list and click on the \u201cTry it out\u201d button. We click the big blue Execute button to send a request.<\/p>\n\n\n\n<p>We receive an array with weather data.<\/p>\n\n\n\n<p>However, let\u2019s close the application and look at the&nbsp;<strong>log files<\/strong>.<\/p>\n\n\n\n<p><strong>Exploring the Log File<\/strong><strong><\/strong><\/p>\n\n\n\n<p>We open the project directory and open the&nbsp;<strong>logs folder<\/strong>. The file name contains the prefix we configured in the&nbsp;<strong>appsettings.json<\/strong>&nbsp;file, and the part after the dash is the current day.<\/p>\n\n\n\n<p>With the current configuration, Serilog creates a separate file for every day. We collect all the log statements for any given day in its file.<\/p>\n\n\n\n<p>[2022-01-22 17:15:54.496 +01:00 INF] Now listening on: https:\/\/localhost:7068<\/p>\n\n\n\n<p>[2022-01-22 17:15:54.520 +01:00 INF] Now listening on: http:\/\/localhost:5068<\/p>\n\n\n\n<p>[2022-01-22 17:15:54.524 +01:00 INF] Application started. Press Ctrl+C to shut down.<\/p>\n\n\n\n<p>[2022-01-22 17:15:54.524 +01:00 INF] Hosting environment: Development<\/p>\n\n\n\n<p>[&#8230;]<\/p>\n\n\n\n<p>[2022-01-22 17:16:06.353 +01:00 INF] Request starting HTTP\/2 GET https:\/\/localhost:7068\/WeatherForecast &#8211; &#8211;<\/p>\n\n\n\n<p>[2022-01-22 17:16:06.359 +01:00 INF] Executing endpoint &#8216;SerilogDemo.Controllers.WeatherForecastController.Get (SerilogDemo)&#8217;<\/p>\n\n\n\n<p>[2022-01-22 17:16:06.367 +01:00 INF] Route matched with {action = &#8220;Get&#8221;, controller = &#8220;WeatherForecast&#8221;}. Executing controller action with signature System.Collections.Generic.IEnumerable`1[SerilogDemo.WeatherForecast] Get() on controller SerilogDemo.Controllers.WeatherForecastController (SerilogDemo).<\/p>\n\n\n\n<p>[2022-01-22 17:16:06.369 +01:00 INF] Weather Forecast executing&#8230;<\/p>\n\n\n\n<p>[2022-01-22 17:16:06.371 +01:00 INF] Executing ObjectResult, writing value of type &#8216;SerilogDemo.WeatherForecast[]&#8217;.<\/p>\n\n\n\n<p>[2022-01-22 17:16:06.380 +01:00 INF] Executed action SerilogDemo.Controllers.WeatherForecastController.Get (SerilogDemo) in 9.1166ms<\/p>\n\n\n\n<p>[2022-01-22 17:16:06.381 +01:00 INF] Executed endpoint &#8216;SerilogDemo.Controllers.WeatherForecastController.Get (SerilogDemo)&#8217;<\/p>\n\n\n\n<p>[2022-01-22 17:16:06.382 +01:00 INF] Request finished HTTP\/2 GET https:\/\/localhost:7068\/WeatherForecast &#8211; &#8211; &#8211; 200 &#8211; application\/json;+charset=utf-8 28.4984ms<\/p>\n\n\n\n<p>Let\u2019s open the file and scroll through it. We can see a timestamp and our log statement that we added to the WeatherForecastController class.<\/p>\n\n\n\n<p><strong>Provided Sinks<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Now that we learned about the basics of Serilog and integrated it into our application let\u2019s look at the&nbsp;<a href=\"https:\/\/github.com\/serilog\/serilog\/wiki\/Provided-Sinks\" target=\"_blank\" rel=\"noreferrer noopener\">provided sinks<\/a>.<\/p>\n\n\n\n<p>As we can see, there are sinks for popular cloud providers, including Amazon CloudWatch, Azure Analytics, and many other cloud services. There are also sinks for the Windows event log, Microsoft Teams, and other interesting log targets.<\/p>\n\n\n\n<p><strong>Additional features<\/strong><strong><\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You can&nbsp;<a href=\"https:\/\/dejanstojanovic.net\/aspnet\/2018\/october\/extending-serilog-with-additional-values-to-log\/\" target=\"_blank\" rel=\"noreferrer noopener\">enrich Serilog with additional information<\/a>&nbsp;such as a&nbsp;<strong>SessionID<\/strong>&nbsp;or a web&nbsp;<strong>RequestID<\/strong>.<\/li>\n\n\n\n<li>You can configure the output format with placeholders and configure JSON instead of plain text output.<\/li>\n\n\n\n<li>You can explore all the additional opportunities Serilog provides in the&nbsp;<a href=\"https:\/\/github.com\/serilog\/serilog\/wiki\/\" target=\"_blank\" rel=\"noreferrer noopener\">Wiki<\/a>&nbsp;on the&nbsp;<a href=\"https:\/\/github.com\/serilog\/serilog\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub project site<\/a>.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>What is Serilog? Serilog&nbsp;is a .NET library that provides diagnostic logging to files, the console, and almost everywhere you would like.&nbsp; Serilog can be used in classic .NET Framework applications and for applications running on the latest and greatest .NET 6. One of the biggest strengths of Serilog is that it has been built with&nbsp;structured [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[12,13,11,15],"tags":[],"class_list":["post-1884","post","type-post","status-publish","format-standard","hentry","category-asp-net","category-asp-net-core","category-csharp","category-log-framework"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"admin","author_link":"http:\/\/waqar-arshad.com\/index.php\/author\/waqar_29_1\/"},"uagb_comment_info":17,"uagb_excerpt":"What is Serilog? Serilog&nbsp;is a .NET library that provides diagnostic logging to files, the console, and almost everywhere you would like.&nbsp; Serilog can be used in classic .NET Framework applications and for applications running on the latest and greatest .NET 6. One of the biggest strengths of Serilog is that it has been built with&nbsp;structured&hellip;","_links":{"self":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/1884","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/comments?post=1884"}],"version-history":[{"count":1,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/1884\/revisions"}],"predecessor-version":[{"id":1885,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/1884\/revisions\/1885"}],"wp:attachment":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/media?parent=1884"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/categories?post=1884"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/tags?post=1884"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}