Closed Klexoid closed 11 months ago
I'm not sure that I understand the question. MVC app logging providers should be added via loggingBuilder
, you shouldn't add them directly as services. See https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/
The issue is that I have a singleton checking a localmachine certificate is present (ServiceA) before app is running but I also need to log information inside this singleton.
I think I did somethings disgusting but it works like I want:
builder.Services.AddLogging(loggingBuilder => {
loggingBuilder.AddFile("logs/app_{0:yyyy}-{0:MM}-{0:dd}.log", fileLoggerOpts => {
fileLoggerOpts.Append = true;
fileLoggerOpts.FileSizeLimitBytes = 104857600;
fileLoggerOpts.MaxRollingFiles = 30;
fileLoggerOpts.FormatLogFileName = fName => {
return String.Format(fName, DateTime.UtcNow);
};
fileLoggerOpts.FormatLogEntry = (msg) =>
{
var sb = new System.Text.StringBuilder();
StringWriter sw = new StringWriter(sb);
var jsonWriter = new Newtonsoft.Json.JsonTextWriter(sw);
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("TimeStamp");
jsonWriter.WriteValue(DateTime.Now.ToString("o"));
jsonWriter.WritePropertyName("LogLevel");
jsonWriter.WriteValue(msg.LogLevel.ToString());
jsonWriter.WritePropertyName("LogName");
jsonWriter.WriteValue(msg.LogName);
jsonWriter.WritePropertyName("EventId");
jsonWriter.WriteValue(msg.EventId.Id);
jsonWriter.WritePropertyName("Context");
jsonWriter.WriteValue(msg.Message);
jsonWriter.WritePropertyName("Exception");
jsonWriter.WriteValue(msg.Exception?.ToString());
jsonWriter.WriteEndObject();
return sb.ToString();
};
});
});
var logFactory = LoggerFactory.Create(loggingBuilder => {
loggingBuilder.AddFile("logs/app_{0:yyyy}-{0:MM}-{0:dd}.log", fileLoggerOpts => {
fileLoggerOpts.Append = true;
fileLoggerOpts.FileSizeLimitBytes = 104857600;
fileLoggerOpts.MaxRollingFiles = 30;
fileLoggerOpts.FormatLogFileName = fName => {
return String.Format(fName, DateTime.UtcNow);
};
fileLoggerOpts.FormatLogEntry = (msg) =>
{
var sb = new System.Text.StringBuilder();
StringWriter sw = new StringWriter(sb);
var jsonWriter = new Newtonsoft.Json.JsonTextWriter(sw);
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("TimeStamp");
jsonWriter.WriteValue(DateTime.Now.ToString("o"));
jsonWriter.WritePropertyName("LogLevel");
jsonWriter.WriteValue(msg.LogLevel.ToString());
jsonWriter.WritePropertyName("LogName");
jsonWriter.WriteValue(msg.LogName);
jsonWriter.WritePropertyName("EventId");
jsonWriter.WriteValue(msg.EventId.Id);
jsonWriter.WritePropertyName("Context");
jsonWriter.WriteValue(msg.Message);
jsonWriter.WritePropertyName("Exception");
jsonWriter.WriteValue(msg.Exception?.ToString());
jsonWriter.WriteEndObject();
return sb.ToString();
};
});
});
ILogger logger = logFactory.CreateLogger<Program>();
builder.Services.AddSingleton(new ServiceA(configuration, logFactory.CreateLogger<ServiceA>()));
...
var app = builder.Build();
But now I would like this logging configuration in my appsettings.json but not sure if it's possible.. EDIT : Do not work x) "File used by an other process"
I'm not sure that I understand the purpose of this:
builder.Services.AddSingleton(new ServiceA(configuration, logFactory.CreateLogger
()));
If this is a singleton service of MVC Core app, it is unclear why you're trying to create a separate logFactory
and then obtain an instance of ILogger<ServiceA>
from it instead of resolving it from the DI service provider:
builder.services.AddSingleton<ServiceA>( (srvPrv) => {
var logger= srvPrv.GetRequiredService<ILogger<ServiceA>>();
return new ServiceA(configuration, logger);
});
EDIT : Do not work x) "File used by an other process"
This is because you have 2 file loggers that are configured for the same file. If you want to use 2 different file loggers they should write to different log files (or your code should resolve ILogger
instances from the same logger factory to write all logs to the same file).
Hope this helps.
Ok, this is perfect ! \o/ Love u ! Thanks for helping me!
My last question, is it possible to put this logging configuration into appsettings.json ? Like for FormatLogEntry and FormatLogFileName (code above), I have no idea how to transcribe that..
Thanks again for your time.
My last question, is it possible to put this logging configuration into appsettings.json ? Like for FormatLogEntry and FormatLogFileName (code above), I have no idea how to transcribe that..
Standard options (like log file name, FileSizeLimitBytes, MaxRollingFiles etc) may be read from appsettings.json section via
var loggingSection = Configuration.GetSection("Logging"); // "File" sub-section is used by default
loggingBuilder.AddFile(loggingSection, fileLoggerOpts => {
});
in appsetting.json
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
},
"File": {"Path":"app.log"}
}
}
FormatLogFileName and FormatLogEntry handlers are code snippets, they cannot be in appsettings.json directly; however, you can make them configurable by using app's configuration (somehow) inside these handlers.
Ok, thanks you very much!
Hello, firstly thanks for your work.
Is it possible to pass this code below to a singleton ? From:
To:
I'm trying to migrate logging from EventLog to File. For now it keeps logging into EventLog obvly. I'm new to C# and I'm struggling with this.. My Service look like this: