0

I want to implement logging in a console application. And since I'm using libraries that expect ILogger, I need to provide one.

For reasons I don't quite fully understand, every article seems to recommend I use SeriLog rather than writing my own logger. But no one has provided a convincing reason why.

In either case, I need the following:

  • Logged information should go to the console.
  • Logged information should go to a log file.
  • After my application runs, I want to put all the information logged into an email.

Can anyone tell me how I could accomplish all three, and if I really need something like SeriLog to do so?

NOTE: I do not think it makes sense to read from the log file and use that to email the log. The log file could include logging from many sessions and I only want to email data from the most recent session.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • Using a logging library **is** a good thing. If you don’t like Serilog, then other logging libraries are available. – stuartd Oct 21 '21 at 21:13
  • 1
    @stuartd: Yes, as indicated, everyone is saying using a logging library is a good thing. But without a good reason why, it's all noise to me. – Jonathan Wood Oct 21 '21 at 21:15
  • 1
    think it this way, is there a good reason not to use it? – urlreader Oct 21 '21 at 21:22
  • @urlreader: Of course. If I write my own, it will work exactly how I want it to, and I'll know exactly how it works. – Jonathan Wood Oct 21 '21 at 21:23
  • 1
    1) talk about reinventing the wheel 2) it emits structured logs 3) it takes less time to learn it than it does to roll your own (unless you're going to cut a lot of corners). You *could* do it yourself and it *would* do exactly what you want (nothing more) and you'd know how it works but I don't find those reasons to be compelling unless you just have free time to do this. I'd poke around in [here](https://github.com/serilog/serilog/wiki/) and see if you can't find some good reasons to use it (or other already implemented and tested solution). – ChiefTwoPencils Oct 21 '21 at 21:47
  • @ChiefTwoPencils: That's fine. But I've written dozens of NuGet packages and don't find it a negative thing to write my own code. Also, I don't see how SeriLog can be passed as Microsoft's `ILogger` interface, which is necessary in my case. And, in fact, getting answers to those kind of questions is not faster than I could write my own. – Jonathan Wood Oct 21 '21 at 21:51
  • 1
    Oh, Okay, lol; I won't argue with that. I can provide a quick answer tho for MS' ILogger...yes, it works and it's very easy to get going. – ChiefTwoPencils Oct 21 '21 at 21:53
  • @ChiefTwoPencils: Okay, so how can I pass a SeriLog logger to a library that expects an Microsoft `ILogger`? – Jonathan Wood Oct 21 '21 at 21:56
  • https://stackoverflow.com/questions/61544047/use-serilog-with-microsoft-extensions-logging-ilogger – Khior Oct 21 '21 at 21:56
  • @Khior: Thanks, but I'm using SeriLog in a console application, and I need to call a class library that also works in a web application. So I don't have a `Webhost` or other objects used in that example. – Jonathan Wood Oct 21 '21 at 21:58
  • You can still use the generic `Host` when running a console application, which should work perfectly fine with Serilog. https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-3.1 – Khior Oct 21 '21 at 22:04
  • That would depend but if that's your need maybe ask about that so you can provide enough context and example. – ChiefTwoPencils Oct 21 '21 at 22:38
  • 1
    @ChiefTwoPencils: So now I've spent the past hour or so trying to get `CreateHostBuilder()` working in my console app. Found a few articles, and all have comments saying how the code is wrong. I went with the simplest approach but I still have elements not working. Fact is, I had this working perfectly until I decided I needed to use a library that relies on Microsoft's `ILogger`. And *that's* why I would consider just writing it myself. – Jonathan Wood Oct 21 '21 at 23:19
  • You shouldn't need that. In `Program.cs` you need something like `Log.Logger = new LoggerConfiguration()...` . [`Log.Logger` is an `ILogger`](https://github.com/serilog/serilog/blob/dev/src/Serilog/Log.cs). You can then configure services to DI it where needed. – ChiefTwoPencils Oct 22 '21 at 00:32
  • @ChiefTwoPencils: I don't think so. It's `Serilog.ILogger`. You can't pass one of those to a class expecting a `Microsoft.Extensions.Logging.ILogger`. – Jonathan Wood Oct 22 '21 at 00:35
  • Once you configure your services you can then get MS' `ILogger` injected. When you add serilog, you're just adding a logging provider. You don't depend on serilog in the dependent code. `services.AddLogging(...)`. – ChiefTwoPencils Oct 22 '21 at 00:47

1 Answers1

3

Based on the requirements you listed, it seems Serilog would be a perfect fit for you, as you can leverage a combination of the existing sinks such as Console, File, and possibly Memory - though you don't need the last one... You can easily create a unique log file per session, read that file and send over email if that's what you want to achieve...

If you're really particular about the last part, you can write your own Serilog sink that buffers the log events the way you want and then send by email at the end.

That said, sending logs to yourself via email is not really something people do anymore these days... There are better sinks that you can use to send logs directly to a store/service that can continuously ingest logs automatically and provide great UIs and APIs to query your logs... You might want to take a look at Seq, Sentry, DataDog, and others...


Serilog is a well designed library, very widely used, and thoroughly tested, with close to 27,000 open-source projects and hundreds of contributors, as of this writing.

If you think you can innovate on how logging is done and take it to the next level, then that would be a good reason to roll your own library, otherwise seems like a waste of time reinventing the wheel.

Innovation is actually how Serilog came about... Other widely used logging libraries such as Log4Net and NLog existed before, but Serilog made semantic logging mainstream in the .NET space coupled with a well designed way of creating extensions (sinks, enrichers, destructurers, ...). The rest is history... NLog soon after followed the footsteps of Serilog, and over time Log4Net became obsolete and is legacy at this point.

C. Augusto Proiete
  • 24,684
  • 2
  • 63
  • 91
  • How about an example that shows how to configure for a log file and a custom sink with `ConfigureLogging` in .NET Core? I'm having trouble finding good examples of that. – Jonathan Wood Oct 22 '21 at 02:17
  • I'm not sure I understand what example you're asking as it doesn't matter if you're using a custom sink or not - It's configured the same way. If you're looking to integrate Serilog with Microsoft's logging interface, then you can use [`Serilog.Extensions.Logging`](https://github.com/serilog/serilog-extensions-logging), or [`Serilog.Extensions.Hosting `](https://github.com/serilog/serilog-extensions-hosting), or [`Serilog.AspNetCore`](https://github.com/serilog/serilog-aspnetcore) depending on the kind of app you have. They all have examples in their repos. – C. Augusto Proiete Oct 22 '21 at 02:23
  • @JonathanWood, see if [this](https://github.com/ChiefTwoPencils/SeriSink) doesn't help you any. It shows how to log in Program.cs and how to get an MS.ILogger there and also how to get an MS.Logger injected. All log configs are in appsettings.json. – ChiefTwoPencils Oct 22 '21 at 16:59
  • 1
    @ChiefTwoPencils: Thanks. I got things working last night using `Host.CreateDefaultBuilder()`. I picked up some things from your code but it's kind of a different approach so I can't really incorporate much of it. Still a lot here that I'm not entirely comfortable with, but it is working. – Jonathan Wood Oct 22 '21 at 20:07