nreco / logging

Generic file logger for .NET Core (FileLoggerProvider) with minimal dependencies
MIT License
284 stars 56 forks source link

Understanding why this happened. #49

Open ProjectMichaelBrooke opened 1 year ago

ProjectMichaelBrooke commented 1 year ago

How do I log to my services.AddLogging file?

So I am trying to put logging into an app of mine. In my Program.cs file I created a service.AddLogging file with a name of app_debug.txt. Being that I am new at using this package. I used the LoggingTests as my examples and created a new LoggingFactory and AddProvider with the file name app.txt. Created a new logger and then build methods to write to the log file (Start, End, Message and Exception). When I run the app from a browser I get all the messages from my debug window in VS written to the app_debug.txt file. All the other messages are written to app.txt. So I am wondering whether creating the factory and logger then disposing of the factory for every message call is going to cause problems if I have 300 people working on the app? Questions? 1) What would be the best way to only have one LoggingFactory and one ILogger logger per session? 2) How coud I write loggs to the app_debug.tx file. I cannot figure this out.

One suggestion. This would be easier if there was some examples of how to use the package.

Thank you,

Michael

VitaliyMF commented 1 year ago

You have to use FileLoggerProvider in the same way as other standard logging providers as described here: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/

If loggers are used according to official MS guidelines they work efficiently. Normally you have only one LoggerFactory instance per application, and if you use standard 'host' infrastructure to maintain DI / Logging / Configurations you don't need to create LoggerFactory implicitely as Host does that for you under the hood, see https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host

Note that FileLoggerProvider implementation doesn't write messages to the file when you call ILogger methods; for efficiency purposes all messages goes into internal queue that is processed in a separate thread, in the same way as standard Console logger does.

You can add several FileLoggerProvider instances and write them to, say, app.txt and app_debug.txt. To skip "Debug" messages for app.txt you can specify minimal logging level for this concrete FileLoggingProvider (by specifying "MinLevel").

From my experience, questions about log levels routing often occur when developer don't understand how Microsoft Logging infastructure works (so I may recommend only to re-read https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/ again).

VitaliyMF commented 1 year ago

Regarding

One suggestion. This would be easier if there was some examples of how to use the package.

makes sense, I've just added simple MVC Core example with 2 file loggers: https://github.com/nreco/logging/tree/master/examples/TwoLogFilesMvc

ProjectMichaelBrooke commented 1 year ago

Thank you for your information. I have read over you code for your examples. I do not understand how the public Startup(... env) method is getting called. In my code I have put all the LoggerFactory Logger information in a constructor. This makes it possible only to run the LoggerFactory once. I noticed that you put your logging code inside a controller. Is that the recommended route?

Thank you, Michael

VitaliyMF commented 1 year ago

I do not understand how the public Startup(... env) method is getting called.

This is standard MVC Core app infrastructure, Startup class is registered in Program.cs with WebHostBuilder.UseStartup<Startup>() (old-style initialization used from .NET Core times). It doesn't matter what initialization style you prefer to use as AddFile call to setup FileLoggerProvider is the same.

I noticed that you put your logging code inside a controller. Is that the recommended route?

See https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/#create-logs and https://learn.microsoft.com/en-us/dotnet/core/extensions/logging

ProjectMichaelBrooke commented 1 year ago

I must be missing something. I have tried using the examples in the two links you used. The problem is that the _logger never gets set up. the public MyClass(ILogger logger) never gets called. This means that my _logger.message call fail.

VitaliyMF commented 1 year ago

Example works, isn't it? ILogger is resolved by DI -- but this works only if you get MyClass instance via DI (DI is also a part of standard MVC Core infrastructure).

ProjectMichaelBrooke commented 1 year ago

The sample works, just not in my application since it is not a MVC Core application. Since this is a API.Net app the process would be different.

VitaliyMF commented 1 year ago

Microsoft.Extensions.Logging is normally used with a standard DI infrastructure; and your console application can use a Generic Host that configures all these standard things (DI & logging). This is how Microsoft recommends to use their standard infrastructure components.

You can use logging without DI and even without ILoggingBuilder - in the same way how FileLoggingProvider tests do that (via ILoggingFactory, and consume ILogger instances created implicitly in your code). However, in this case you have to explore how Microsoft.Extensions.Logging works under the hood to avoid misconfiguration and improper use.