C# Serilog config in ASP.NET Core 6 - c#

I have the following in appsettings.json for Serilog:
"Serilog": {
"Using": [],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft.AspNetCore": "Warning",
"System": "Warning" //Amik ezekből a névterekből jönnek is Informationok lesznek.
}
},
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
"WriteTo": [
{ "Name": "Console" }
]
},
I tried to add Serilog for my bootstrap app, but nothing worked well :(.
It is not logging to the console.

I have the following settings in appsettings.json for Serilog. I tried to add Serilog for my bootstrap app, but nothing worked well
It is not logging into console.
Well, its not quite clear if you have followed all the steps accordingly. Based on your shared appsettings.json it appreared that your configuration is partially correct. If you don't define anything inside using block its better to ommit that. In addition to this, you haven't defined your "Args" parameter where need to log what I mean is the path. Furthermore, whether you have install the required nuget package and included the required code snippet in your program.cs file
Therefore, you can follow the steps below to implement it correctly.
Prerequisite:
Serilog Nuget Package
appsettings.json configuration
1. Serilog Nuget Package
To configure Serilog for asp.net core reagrdless of its version, you need to following package in your application reference.
serilog.aspnetcore, serilog.aspnetcore and serilog.expressions
You can add from your Nuget Package Manager as following:
Once all the required package installed accordingly it should look like below:
In addititon, you even can using nuget package manager console command which are like below:
dotnet add package serilog.aspnetcore
dotnet add package serilog.sinks.seq
dotnet add package serilog.expressions
2. appsettings.json configuration
Please replace your appsettings.json file as following for serilog.
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"path": "./logs/log-.txt",
"rollingInterval": "Day"
}
}
]
},
"AllowedHosts": "*"
}
Program.cs file
using Serilog;
Log.Logger = new LoggerConfiguration()
.WriteTo.Console().CreateBootstrapLogger();
Log.Information("Staring up logging");
try
{
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog((context, logConfig) => logConfig
.WriteTo.Console()
.ReadFrom.Configuration(context.Configuration));
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseSerilogRequestLogging();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
catch (Exception ex)
{
Log.Fatal(ex,"Unhandled Exception");
}
finally
{
Log.Information("Log Complete");
Log.CloseAndFlush();
}
Output:
Note: If you would like to know more details about logging in asp.net core you could check the official document here

Related

Steeltoe Serilog Dynamic Logging not working with .NET 7

I am trying to setup Serilog Dynamic Logging with Steeltoe. I am using .NET 7. I am using the Host Builder to add the functionality. Code example below using Host builder:
.AddDynamicSerilog((cfg, log) => log.ReadFrom.Configuration(cfg.Configuration))
I have set a breakpoint in the extension here but my code is not hitting this breakpoint:
public static IHostBuilder AddDynamicSerilog(
this IHostBuilder hostBuilder,
Action<HostBuilderContext, LoggerConfiguration> configureLogger = null,
bool preserveStaticLogger = false,
bool preserveDefaultConsole = false)
Steeltoe Configuration:
"Serilog": {
"MinimumLevel": "Information",
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "File",
"Args": { "path": "Logs/log.txt" }
}
],
"Properties": {
"Application": "Test"
}
}
My application is logging when i use the logger but it is logging in just the regular format no application name or tracing extensions etc. so I am assuming my configuration is not being read somehow? Is the Serilog Dynamic Logging package compatible with .NET 7? Or is there something else going on?
Tried given examples. Logging does not look like Serilog configuration is being read or applied from settings file. Also extension code isn't executed.
You can try this particular sample here: https://github.com/SteeltoeOSS/Samples/tree/main/Management/src/CloudFoundry
Change the target to <TargetFramework>net7.0</TargetFramework>
I just tried this and you can see in the picture the Serilog configuration being read. Note the versions of Steeltoe etc in the sample (to help narrow down the issue).
As far as debugging - we enable sourcelink on our nuggets so you should be able to view and debug Steeltoe code by enabling it in your debug options.
I suspect the problem is that outputTemplate is missing in appsettings. It needs to include "{Properties}", so that scoped values are included in the message.
"Serilog": {
"MinimumLevel": "Information",
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext}: {Properties} {NewLine} {EventId} {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": { "path": "Logs/log.txt" }
}
],
"Properties": {
"Application": "Test"
}
}
I took the following steps to reproduce the issue and make it work:
In Visual Studio: File > New > Project > ASP.NET Core Web API
From the Package Manager Console:
install-package Serilog.AspNetCore
install-package Steeltoe.Extensions.Logging.DynamicLogger
install-package Steeltoe.Extensions.Logging.DynamicSerilogCore
install-package Steeltoe.Management.TracingCore
Add to Program.cs:
// Add services to the container.
builder.AddDistributedTracincAspNetCore();
builder.AddDynamicSerilog((cfg, log) =>
log.ReadFrom.Configuration(cfg.Configuration));
builder.AddDynamicLogging();
Add the section from above to appsettings.Development.json
Run the application
This prints the following line on my console:
[14:13:08 INF] Microsoft.AspNetCore.Hosting.Diagnostics: {Protocol="HTTP/2", Method="GET", ContentType=null, ContentLength=null, Scheme="https", Host="localhost:7142", PathBase="", Path="/weatherforecast", QueryString="", RequestId="0HMNU1ISSN7T6:00000001", RequestPath="/weatherforecast", ConnectionId="0HMNU1ISSN7T6", Scope=[" [DynamicLoggingWebApi,52a92b64eb0209466ca872311bf309cc,e425a4b06ed50908,0000000000000000,true] "], Application="Test"}
{ Id: 1 } Request starting HTTP/2 GET https://localhost:7142/weatherforecast - -
From the line above, the tracing info is:
[DynamicLoggingWebApi,52a92b64eb0209466ca872311bf309cc,e425a4b06ed50908,0000000000000000,true]
Hope that helps!
By the way, I didn't have any problems stepping into the sources. To set up Visual Studio, follow the instructions at https://devblogs.microsoft.com/dotnet/improving-debug-time-productivity-with-source-link/#enabling-source-link.

StackExchange.Exceptional not logging exceptions from Blazor

I have a Blazor Server-Side app running with .NET 5.0 and I'm trying to switch from ElmahCore to Exceptional.
But I can't get it to log Blazor exceptions.
When I throw an exception in a MVC controller it gets logged, but if I throw one in e.g. OnAfterRenderAsync nothing gets logged.
What do I need to configure to get Blazor exceptions logged with Exceptional?
Also in ElmahCore I could use ElmahExtensions.RiseError(exception); to log an exception I catched/handled in code but still wanted to show up in the error-log. Is there something similar for Exceptional?
I configured Exceptional with the default configuration from HERE.
I downloaded the package first:
Install-Package StackExchange.Exceptional.AspNetCore -Version 2.2.17
Next, add the Exceptional tag configuration to the appsettings.json file, which contains the connection string used to store errors in the database:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Exceptional": {
"Store": {
"ApplicationName": "Test",
"Type": "SQL",
"ConnectionString": "Your Db"
}
}
}
Registering AddExceptional service in ConfigureServices Method:
services.AddExceptional(Configuration.GetSection("Exceptional"), settings =>
{
settings.UseExceptionalPageOnThrow = HostingEnvironment.IsDevelopment();
});
After adding ConfigureServices next, we are going to add “UseExceptional” middleware in Configure method.
Adding app.UseExceptional(); Middleware in Configure method to handle errors:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseExceptional();
.....
}
Then I wrote a throw exception throw new NotImplementedException();
Then you can see the record:
According to the article you provided, it should be done.Which side did you have a problem with?

Microsoft Service Fabric and logging

I am investigating the best way to implement logging for my Service Fabric Stateless API and have been somewhat overwhelmed by the varying different solutions for what appears to be a relatively simple requirement.
I have implemented logging using the WebHostBuilder().ConfigureLogging and have successfully logged my trace messages to the Debug window and via Serilog.Extensions.Logging.File I have also managed to dump this log to a file, this all being controlled via a #if DEBUG directive and this I was happy with.
Then I needed to configure what would happen when deployed to a cluster within Azure and this is when I became overwhelmed!!!
I thought that I could register ServiceEventSource type logger in the same manner as I did with AddDebug however it was not this simple.
So I have managed to get my logs to appear within the diagnostic window using the ServiceEventSource.Current.Message but these logs are not integrated within the ASP.NET logging framework :/
My continued investigation has led me to understand that Service Fabric logging should be directed towards Application Insights albeit many, many articles having varying degrees of detail and applicability to the latest framework.
My current thinking is that I need to remove the ASP.NET logging and implement something such as EventFlow to allow my trace messages to be generated and subsequently piped through to Application Insights for interrogation at a later date, is my thinking correct??
Or am I currently going off at a tangent?
UPDATE 15/05/2019
After deploying this to Azure Service Fabric the log files were not populated, this appears to be an incompatibility between the Serilog.Sinks.AzureBlobStorage NUGET package and the .NET Core version 2.2.0 that my project was targeting.
I have posted a ticket on the GitHub page and await a response, in the short term you can download the source code and migrate the project to a Microsoft.NETCore.App 2.2.0 project and directly reference this and everything works perfectly.
ORIGINAL ANSWER
I seem to do this quite a lot, answering my own question but here goes again. It's taken me a day or two to get to the bottom of this so I thought I would share my findings and solution with the community in-case it might help somebody else in the future and/or somebody might have something to add or even contradict me which I'd welcome any input.
My development environment is as follows: -
Microsoft Visual Studio 15.9.11
Windows 10 Professional
SDK: Microsoft.NETCore.App 2.2.0
I created a new Service Fabric Stateless Service the purpose of this service is to provide RESTful endpoints to a Angular 7 front end web application.
My requirement was to provide logging information in both my development environment via the Debug window and to also provide similar logging information whilst my apps are being hosted within a Service Fabric Cluster on Azure.
NUGET Package Installations
Microsoft.Extensions.Logging (2.2.0)
Serilog.AspNetCore (2.1.1)
Serilog.Enrichers.Environment (2.1.3)
Serilog.Settings.Configuration (3.0.1)
Serilog.Sinks.Debug (1.0.1)
Serilog.Sinks.AzureBlobStorage (1.3.0)
Controlling Development & Production Environments
I control the development & production environments using the DEBUG pre-processor directive to include either the appsettings.json or appsettings.Development.json file.
My appSettings.Development.json file is like this: -
{
"AppSettings": {
// My app settings not applicable to this
},
"Serilog": {
"Using": [ "Serilog.Sinks.Debug" ],
"MinimumLevel": {
"Default": "Verbose",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Debug",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {MachineName} {Level:u3}] {Message:lj}{NewLine}{Exception}"
}
}
],
"Enrich": ["WithMachineName"]
}
}
My appSettings.json file is like this: -
{
"AppSettings": {
// My app settings not applicable to this
},
"Serilog": {
"Using": [ "Serilog.Sinks.AzureBlobStorage" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "AzureBlobStorage",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {MachineName} {Level:u3}] {Message:lj}{NewLine}{Exception}",
"connectionString": "[Connection String]",
"storageContainerName": "app",
"storageFileName": "{yyyy}-{MM}-{dd}.log"
}
}
],
"Enrich": [ "WithMachineName" ]
}
}
As you can see from the above settings files I output to the Debug window when in development and I have chosen to output to Azure Blob Storage when deployed to a Service Fabric Cluster in Azure.
To implement the Serilog logging simple review my Stateless Service class implementation below, which shows how to toggle the two different appSettings.json files dependent upon the environment and also how the Serilog logger is inserted into the dependency injection system via the use of the UseSerilog extension method.
using System.Collections.Generic;
using System.Fabric;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.ServiceFabric.Services.Communication.AspNetCore;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
using Microsoft.ServiceFabric.Services.Runtime;
using Serilog;
namespace Caboodal.Manatee.ServiceFabric.Api.Identity
{
internal sealed class Identity : StatelessService
{
public Identity(StatelessServiceContext context)
: base(context)
{
}
private string AppSettingsFilename
{
get
{
#if DEBUG
return "appsettings.Development.json";
#else
return "appsettings.json";
#endif
}
}
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
var appSettings = GetAppSettings();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(appSettings)
.CreateLogger();
return new[]
{
new ServiceInstanceListener(
serviceContext =>
new KestrelCommunicationListener(
serviceContext,
"ServiceEndpoint",
(url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");
return new WebHostBuilder()
.UseKestrel()
.ConfigureAppConfiguration(
(builderContext, config) =>
{
config.AddJsonFile(AppSettingsFilename, false, true);
})
.ConfigureServices(
services => services
.AddSingleton(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseSerilog()
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}))
};
}
private IConfigurationRoot GetAppSettings()
{
return new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(AppSettingsFilename)
.Build();
}
}
}
Using the Logger within a controller
Because the ILogger instance is configured as a Dependency Injected instance it can simply be accessed within your Controller classes like any other dependency e.g.
[Authorize]
[ApiController]
[Route("[controller]")]
public class UserController : ApiController
{
private readonly IUserService _userService;
private readonly ILogger<UserController> _logger;
public UserController(IUserService userService, ILogger<UserController> logger)
{
_userService = userService;
_logger = logger;
}
[AllowAnonymous]
[HttpPost("authenticate")]
public IActionResult Authenticate([FromBody] DtoAuthenticateRequest request)
{
// Adding log entries
_logger.Log(LogLevel.Debug, "Here is a log entry");
// Some code in here
return Ok(response);
}
}
I got very sidetracked with the ServiceEventSource.cs class but with the usage of Serilog I have now ignored this aspect of the project template.
If you wish to output your logs to other data consumers or simply into different formats then just review the Serilog website here for a complete list of the Sinks available, with Application Insights being one of the many.

Serilog JsonFormatter in an ASP.Net Core 2 not being applied from appsettings file

I have an ASP.Net Core 2 web application where I'm trying to configure SeriLog to output in JSON format, configured via an appsettings.json file. I cannot get this to work with either the standard Serilog.Formatting.Json.JsonFormatter or the compact Serilog.Formatting.Compact.CompactJsonFormatter.
I see there's a similar question asked here, but there seems to be no conclusive answer using appsettings.json, and the thread has gone quiet for over a year (and I don't have enough reputation to comment to nudge further responses).
I'm using the following SeriLog packages:
Serilog.AspNetCore - 2.1.0
Serilog.Enrichers.Environment - 2.1.2
Serilog.Enrichers.Thread - 3.0.0
Serilog.Formatting.Compact - 1.0.0
Serilog.Settings.Configuration - 2.4.0
Serilog.Sinks.RollingFile - 3.3.0
The SeriLog section of my appsettings.json file reads:
"Serilog": {
"Using": ["Serilog.Sinks.RollingFile"],
"MinimumLevel": {
"Default": "Verbose",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "RollingFile",
"Args": {
"pathFormat": "C:\\Logs\\MLSBPortal-{Date}.txt",
"formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact",
"restrictedToMinimumLevel": "Debug",
"retainedFileCountLimit": "10",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{ThreadId}] [{SourceContext}] [{SessionId}] [{UserName}]: {Message}{NewLine}{Exception}"
}
}
],
with the formatter line modified to the following when testing with the default JSON formatter:
"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
As suggested in multiple other places.
My output is being written fine, but the formatter setting does not appear to be making any difference to the output.
Am I doing something wrong here, or is this functionality not implemented via a configuration file read yet?
Thanks in advance for any help.
It turns out that it is not (currently) possible to specify both a formatter and outputTemplate at the same time (as clarified at https://github.com/serilog/serilog-aspnetcore/issues/31 ).
Hopefully this situation may change in the future...

Azure function : Appsetting.json is not working with Serilog.Sinks.Sumologic

We are trying to implement logging using Serilog.Sinks.SumoLogic(1.0.1) to Azure function apps (without .NET core). Below is the code and appsetting.json we are using.
Code:
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json",optional: false, reloadOnChange: true)
.Build();
var loggerFromConfig = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
Appsettings.json:
{"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"System": "Warning",
"Microsoft": "Warning"
}
},
"WriteTo": [
{
"Name": "SumoLogic",
"Args": {
"endpointUrl": "https:"
}
}
]
}
}
With above appsetting we are not able to bind the sumologic sink with loggerFromConfig object and _sinks = {Serilog.Core.ILogEventSink[0]} which shows that there is no sink configured.
If we try the same code with a sample project with Microsoft.NET.Core.Apps dependency it is working fine.
It seems that appsettings.json is supported with .NET core apps only.
Please suggest how to write log using Serilog with appsettings.json (without .NET core apps).
As far as I know, the ReadFrom.Configuration method is used to get the setting from appsettings.json in .net core project.
Since the ReadFrom.Configuration method needs IConfiguration object. If you want to use ConfigurationBuilder, you need install the Microsoft.Extensions.Configuration package from the Nuget.
If you install this Nuget Package, you could use the ConfigurationBuilder class. But it will also install the Microsoft.NETCore.Platforms package.
In my opinion, the right way to use the Serilog in .net apps is using LoggerConfiguration().WriteTo.SumoLogic method like this.
var logger = new LoggerConfiguration().WriteTo.SumoLogic(url,
sourceName: "CustomSourceName",
sourceCategory: "CustomSourceCategory",
restrictedToMinimumLevel: LogEventLevel.Debug,
batchSizeLimit: 20,
period: TimeSpan.FromSeconds(1),
textFormatter: new RawFormatter())
More details, you could refer to this codes.
Since the ReadFrom.Configuration method also read the setting from the appsettings.json file then using these setting to create LoggerConfiguration object, I suggest you could directly use the LoggerConfiguration().WriteTo.SumoLogic method.
Besides, if you still want to use appsettings.json, I suggest you could read the appsettings.json's setting by using Newtonsoft package. Then you could pass these settings as parameters into LoggerConfiguration().WriteTo.SumoLogic method.

Categories

Resources