I'm trying to use Serilog in a dotnet webapi app. I need logging to go to both the Console and a Rolling log file.
Everything is coming out to the Console but nothing is appearing in the rolling log file and I'm not getting any errors anywhere.
I have setup serilog in my code like so:
// in program.cs Main
var configuration = new ConfigurationBuilder()
.SetBasePath(BASEDIR)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.Enrich.FromLogContext()
.Enrich.With(new ThreadIdEnricher())
.CreateLogger();
// startup.cs Configure
app.UseSerilogRequestLogging();
And in appsetting.json I have
{
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft.AspNetCore.Mvc.Internal": "Warning",
"Microsoft.AspNetCore.Authentication": "Warning",
"Microsoft.AspNetCore": "Warning",
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u1} TID:{ThreadId} {Message:lj}{NewLine}{Exception}",
"theme": "Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme::Literate, Serilog.Sinks.Console"
}
}
]
}
},
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "RollingFile",
"Args": {
"pathFormat": "c:\\logs\\{Date}.log",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u1} TID:{ThreadId} {Message:lj}{NewLine}{Exception}",
"buffered": false,
"rollingInterval": "Serilog.RollingInterval.Day, Serilog.Sinks.File",
"retainedFileCountLimit": 7
}
}
]
}
}
]
}
}
have you tried to change to static file name? does the path exists? it seems that the configuration on the readme from their github page is a bit differnt from yours: https://github.com/serilog/serilog-sinks-file#user-content-json-appsettingsjson-configuration:~:text=node%2C%20%3A-,%7B,%7D,-See%20the%20XML
also maybe try to work your way back from setting it up in code then move back to config file?
Related
Am new to serilog but I cannot see how to set the name of the log being generated by Serilog.
I am using the ASP.net core and have registered serilog and using the appsettings.json to log into my file which works as expected.
However the name of the file isn't adhering to the WriteTo configuration as defined:
"Serilog": {
"Using": [
"Serilog.Sinks.Console"
],
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Debug",
"System": "Debug"
}
},
"Enrich": [
"FromLogContext",
"WithExceptionDetails",
"WithEnvironmentUserName",
"WithMachineName",
"WithProcessId",
"WithProcessName",
"WithThreadId"
],
"WriteTo": [
{
"Name": "Console",
"Args": {
"path": "Logs/logFile_.log"
},
"Theme": "Code"
},
{
"Name": "File",
"Args": {
"path": "Logs/logFile_.log",
"fileSizeLimitBytes": "1000",
"retainedFileCountLimit": 5,
"rollingInterval": "Day"
// , "shared" : "true"
},
"outputTemplate": "===> {Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
}
]
}
The filename looks like:
ProjectName.Api20220309_01.log
Rather than expected:
logfile_20220309_01.log
Is this something out of the box? Or is there something I should look for?
Just for background I have several projects in the one solution where serilog is running.
Can anyone tell me how to get the value from an appsettings.json file in my program.cs file in a Blazor (core 5) App.
Basically just need to write the "var seqUrl =" correctly. I think.
Please and thank you.
In my Main method of Program.cs I have
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", false, true)
.AddJsonFile("appsettings.Development.json", true, true)
.Build();
var levelSwitch = new LoggingLevelSwitch();
var seqUrl = configuration.GetSection("SeriLog").GetSection("WriteTo").GetSection("Name:Seq").GetSection("Args").GetSection("serverUrl").Value;
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.MinimumLevel.ControlledBy(levelSwitch)
.WriteTo.Seq(seqUrl,
apiKey: "xxxxxxxxxxxx",
controlLevelSwitch: levelSwitch)
.CreateLogger();
My appsettings.json looks like this.
"SeriLog": {
"Using": [
"Serilog.Sinks.File",
"Serilog.Sinks.Seq",
"Serilog.Sinks.Console"
],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"system": "Warning"
}
},
"Enrich": [ "WithMachineName", "WithEnvironmentUserName", "WithClientIp", "WithClientAgent", "WithEnvironmentName", "WithProcessId", "WithProcessName", "WithThreadId" ],
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "C:\\Temp\\Logs\\JsonLog.json",
"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
"rollingInterval": "Day"
}
},
{
"Name": "Seq",
"Args": {
"serverUrl": "http://xxxxxxxxxxx"
}
}
]
I think you should consider restructuring the JSON in your appsettings file. The value for "WriteTo" is an array, but I would make it just an object rather than an array, then each element should be a child object. Use the "Name" variable to name them. Like this:
"WriteTo": {
"File": {
"Args": {
"path": "C:\\Temp\\Logs\\JsonLog.json",
"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
"rollingInterval": "Day"
}
},
"Seq": {
"Args": {
"serverUrl": "http://xxxxxxxxxxx"
}
}
}
Then you should be able to retrieve the values using the same style that you are, just with the complete path to the variable you need. For example:
var seqUrl = configuration.GetSection("SeriLog:WriteTo:Seq:serverUrl").Value;
I don't remember if this syntax is 100% correct or not (the path might not be colon separated, I'm not completely sure) but this concept should work. You just weren't entering the correct names into the .GetSection() method in your code, and I think it gets kind of tricky when you are trying to retrieve an array element like this, hence my suggestion to convert from array to a simple object.
I'm developing an application using asp.net core and Serilog for logging.
I have the following code:
Log.Information("Application Starting.");
Log.Information("Message: fetching all Requests");
My Serilog config file look like this:
{
"Serilog": {
"Using": [ "Serilog.Settings.Configuration" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"System": "Warning",
"Microsoft": "Warning"
}
},
{
"Name": "Logger",
"Args": {
"configureLogger": {
"Filter": [
{
"Name": "ByIncludingOnly",
"Args": {
}
}
],
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "..\\Logs\structuredLog.json",
"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
"fileSizeLimitBytes": 20485760
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId"
],
"Properties": {
"ApplicationName": "Serilog.WebApplication"
}
}
}
}
]
}
The Problem:
As an output i get an invalid JSON file:
{"Timestamp":"2021-07-27T10:09:41.9531148+02:00","Level":"Information","MessageTemplate":"Application Starting."}
{"Timestamp":"2021-07-27T10:09:46.7538684+02:00","Level":"Information","MessageTemplate":"Message: fetching all Requests"}
I expect to get something like this:
[
{
"Timestamp":"2021-07-27T10:09:41.9531148+02:00",
"Level":"Information",
"MessageTemplate":"Application Starting."
},
{
"Timestamp":"2021-07-27T10:09:46.7538684+02:00",
"Level":"Information",
"MessageTemplate":"Message: fetching all Requests"
}
]
Can someone please help me to solve this problem!
You are correct with the statement that the JSON file is not a valid JSON object. In the context of a logging library the output should not be seen as a file but a stream of data. So each log entry is one item in a possibly never ending flow.
This is also why it makes no sense to add an opening array indicator and adding comma after each line.
After I generate the json log, I can adjust the format by using the format that comes with vs.
Format shortcut: Ctrl+K or Ctrl+D.
If it doesn't work, do it like this:
Result:
My .NET Core 3 implementation of Quartz.Net is logging the following message approximately twice per minute and I would like to remove it without affecting my applications other logs:
"Batch acquisition of 0 triggers"
2020-06-22 17:42:24.745 +01:00 - [MyApplication] - [Debug] - [Quartz.Core.QuartzSchedulerThread] Batch acquisition of 0 triggers
2020-06-22 17:42:53.689 +01:00 - [MyApplication] - [Debug] - [Quartz.Core.QuartzSchedulerThread] Batch acquisition of 0 triggers
Where [MyApplication] is populated by the Source property and [Quartz.Core.QuartzSchedulerThread] comes from the SourceContext.
Quartz.net logs this automatically and I seem to have no control over deciding to log it or not. My logs are filling up too quickly.
My Appsettings.json file is as follows:
"Serilog": {
"IncludeScopes": false,
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "C:/Logs/my-app.log",
"buffered": "true",
"flushToDiskInterval": "00:00:10",
"rollingInterval": "Infinite",
"rollOnFileSizeLimit": "true",
"fileSizeLimitBytes": 10485760,
"retainedFileCountLimit": 90,
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} - {Source} - [{Level}] - [{SourceContext}] {Message}{NewLine}{Exception}"
}
},
{
"Name": "Async",
"Args": {
"restrictedToMinimumLevel": "Information",
"configure": [
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} - {Source} - [{Level}] - {Message}{NewLine}{Exception}"
}
}
]
}
}
]
}
My Program.cs main initially configures the logger like this:
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.Enrich.FromLogContext()
// set Source property, which we use in output formatting, to the name of the application
.Enrich.WithProperty("Source", value: "MyApplication")
.CreateLogger();
And later in my Startup.cs, when my services & settings have been registered Serilog is reconfigured as follows:
public void Configure(IApplicationLifetime applicationLifetime)
{
SerilogLogger.Reconfigure(
applicationName: "MyApplication",
toFixedFile: !string.IsNullOrEmpty(_loggerSettings.LogFilePathFixed),
fileName: _loggerSettings.LogFilePathFixed,
fileSizeBytes: configuredLogFileSize * 1024 * 1024,
minimalLevel: "Debug",
outputTemplate: _loggerSettings.LogFormat);
}
Where the Reconfigure extension method comes from a 3rd party dll built in another development department.
I have tried to add the following after the invocation of Reconfigure:
SerilogLogger.RefineConfiguration(x => x.MinimumLevel.Override("Quartz", LogEventLevel.Warning));
But it doesn't work because the actual source is MyApplication, and if I use "MyApplication" instead of "Quartz" I suppress all debug and information logs for the entire application.
Any ideas? With code examples please.
I have implemented a solution for this problem, there were two parts to the solution:
1 - As pointed out to me in the Quartz google groups, I was missing the following Serilog configuration from appsettings.json to define the correct logging level for Quartz:
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning",
"System": "Warning",
"Quartz": "Warning"
}
},
The configuration of "Quartz": "Warning" suppressed the Debug "Batch acquisition" messages from being logged.
And
2 - The invocation of both the SerilogLogger.Reconfigure and SerilogLogger.RefineConfiguration methods was completely unnecessary. I removed this. It was overwriting the config from point 1) above. All Serilog configuration should take place in my appsettings.
I have a question relating the configuration of Serilog by appSettings.json.
My project is a console application, based on .Net Core 3.0.
I tried to setup Serilog in order to write log information to the console and to a log file.
When I configure everything within my code itself - everything works like expected.
But when I try to import the Serilog configuration settings from an appsettings.json file, I have the problem, that my ConsoleSink works fine, but my FileSink not.
Here is, what I wrote into my appsettings.json:
{
"Serilog": {
"Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Console" ],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "File",
"Args": { "pathFormat": "Xlog.txt" }
},
{ "Name": "Console" }
]
}
}
And this is the associated code:
IConfiguration configSerilog = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
.Build();
log = new LoggerConfiguration()
.ReadFrom.Configuration(configSerilog)
.CreateLogger();
log.Information("Initializing Serilog....");
My 'test-log-message' get's displayed in my console window, but I didn't get a logfile.
As I mentioned, it works, when I configure the Serilog in my code itself, rather than by the appsettings.
So, I do have the appropriate access rights to create a file.
Any ideas or hints?
Make sure that file proprieties for appsettings.json, property "Copy to Output Directory" is "Copy always" or "Copy if Newer".
And update youe configration as below (pathFormat in Args shoud be path)
{
"Serilog": {
"Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Console" ],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "File",
"Args": { "path": "Xlog.txt" }
},
{ "Name": "Console" }
]
}
}