Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explore Logging Alternatives #20

Open
AndyLPK247 opened this issue Oct 23, 2020 · 2 comments
Open

Explore Logging Alternatives #20

AndyLPK247 opened this issue Oct 23, 2020 · 2 comments

Comments

@AndyLPK247
Copy link
Contributor

Serilog is a popular .NET logging library.

Should we use Serilog as part of Boa Constrictor? Maybe. Let's discuss that possibility here in this issue.

Pros:

  • Serilog is very popular and well supported.
  • Boa Constrictor wouldn't need to maintain its own logging pattern.

Cons:

  • What if projects using Boa Constrictor don't want to use Serilog or already use a different logger?
@shack05
Copy link
Contributor

shack05 commented Oct 24, 2020

I found it very easy to get started with Boa Constrictor and I like that there isn't much ceremony required to get started.
I also like that I can provide my own implementation of a logger.
I see the appeal of using an existing logging library like Serilog so that users can choose from existing sinks but as you noted not everybody may want to use Serilog.

As I see it, there is a balance between supporting different use cases:

  1. Users who are happy with basic logging (and just want to get started quickly)
  2. Users want greater flexibility.

With that in mind, some thoughts:

1. Use an action/event for logging
Rather than have Boa Constrictor depend on some kind of logger interface or implementation, what if the library just raised log events and users can provide their own implementation for handling those events?

A possible implementation using Actions could be something like:

  • Define LogEvent type with LogSeverity and Message.
  • In IActor replace ILogger with Action<LogEvent>
  • In Actor accept a LoggingAction of type Action<LogEvent>.
  • Any time you wish to log just invoke the action: LoggingAction?.Invoke(new LogEvent(severity, message)

For use case 1 Boa Constrictor can provide one or more basic implementations such as a console logger with a fixed message template.

This also meets use case 2 since as a user I can now handle logs as I wish, eg:
Action<LogEvent> loggingAction = (logEvent) => Console.WriteLine($"[{logEvent.Severity}] {message}")
or I could use Serilog, or whatever I want.

An alternative to using Actions could be using actual events, and users create their own event handlers.

2. Use Microsoft.Extensions.Logging.Abstractions

Rather than adding a dependency to a specific logging implementation, what about using Microsoft.Extensions.Logging.Abstractions which provides a common logging abstraction? Users can then choose from an existing implementation (Serilog, NLog, ...) or provide their own. So this meets use case 2.

This does introduce some effort from the users perspective in terms of wiring up an actual implementation, particularly if they aren't already familiar with logging in .NET. Also, my experience has been that many of search results related to logging in .NET are geared towards ASP.NET (or at least expects the user to be using a DI container).

To meet use case 1:

  • an example using one of the popular implementations (such as Serilog) could be included in the tutorial.
    A basic example of wiring up Serilog would be something like:
// Create Serilog logger
Log.Logger = new LoggerConfiguration()
       .MinimumLevel.Debug()
       .WriteTo.Console(outputTemplate: "{Timestamp:HH:mm:ss.fff} [{Level:u4}] {Message:lj}{NewLine}{Exception}")
       .CreateLogger();

// Create logger factory
var loggerFactory = new LoggerFactory();
loggerFactory.AddSerilog();
            
// Create logger instance to pass in to actor
_logger = loggerFactory.CreateLogger<MyClass>();

and/or,

  • Boa Constrictor could includes its own logger implementation. That example is for ASP.NET Core 3.1, but the only bit which would change is the usage and registration.
    Say Boa Constrictor defined SimpleLogger, SimpleLoggerProvider, and SimpleLoggerConfiguration, using the logger would be:
var simpleLoggerConfig = new SimpleLoggerConfiguration
{
    LogLevel = LogLevel.Trace
};

var loggerFactory = LoggerFactory.Create(builder => builder.AddProvider(new SimpleLoggerProvider(simpleLoggerConfig)));
var logger = loggerFactory.CreateLogger<MyClass>();

The above could be wrapped up in a single method.
This approach would mean that users don't need to add any additional packages.

*The above examples are using the latest versions of the respective libraries.

Personally I prefer option 1 since I feel it's a lighter touch and doesn't introduce any new dependencies whatsoever, but interested to hear any thoughts.

@AndyLPK247
Copy link
Contributor Author

@shack05, thanks for those awesome ideas! I think I agree with you - I like option 1.

@AutomationPanda AutomationPanda changed the title Explore Serilog Explore Logging Alternatives Oct 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants