MindscapeHQ / serilog-sinks-raygun

A Serilog sink that writes events to Raygun
Apache License 2.0
11 stars 20 forks source link

Does this support .NET Core console applications? #24

Closed benjaminsampica closed 4 years ago

benjaminsampica commented 4 years ago

I've got two projects I'm trying to share logging implementation between - an ASP.NET Core 3.1 application and a .NET Core 3.1 application. I cannot seem to figure out how to have this log to .NET Core console applications using a static logger - specifically when the application starts up.

My static logger with Serilog:

public static class SerilogUtilities
    {
        private static readonly string DotNetEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
            ?? Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Development";

        public static ILogger GetLogger()
        {
            var configurationBuilder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{DotNetEnvironment}.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables()
                .Build();

            return new LoggerConfiguration()
                .ReadFrom.Configuration(configurationBuilder)
                .Enrich.FromLogContext()
                .Enrich.WithMachineName()
                .CreateLogger();
        }
    }

Both my ASP.Net Core and .NET Core console applications have the following relevant NuGet packages

Serilog.AspNetCore
Serilog.Sinks.Raygun

and appsettings.json files.

  "Serilog": {
    "WriteTo": [
      {
        "Name": "Raygun",
        "Args": {
          "applicationKey": "APIKEY",
          "tags": [
            "Production"
          ]
        }
      }
    ]
  }

Finally, both Program.cs files are essentially the same thing - here's my console applications Program.cs file

    class Program
    {
        static async Task Main(string[] args)
        {
            Log.Logger = SerilogUtilities.GetLogger();
            Log.Logger.Information("Appointment Reminder started");
            try
            {
                var host = BuildHost(args);
                using (var scope = host.Services.CreateScope())
                {
                    throw new Exception("Ignore me exception");
                }
            }
            catch (Exception ex)
            {
                Log.Logger.Fatal(ex, "Host terminated unexpectedly.");

                throw;
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }

        private static IHost BuildHost(string[] args)
        {
            var host = Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostingContext, services) =>
                {
                    services.AddPersistence(hostingContext.Configuration);
                    services.AddApplication();
                    services.AddInfrastructure(hostingContext.Configuration, hostingContext.HostingEnvironment);
                })
                .UseSerilog()
                .Build();

            return host;
        }
    }

Could you tell me if startup logging is supported for .NET Core? This works just fine if I use RayGun4Net directly inside the catch block, but I'd like to stick with Serilog for sinking to other places as well (which also is working correctly right now).

QuantumNightmare commented 4 years ago

The Raygun Serilog Sink does support .NET Core Console apps. To confirm, is it logging exceptions fine while the app is running, and just having trouble during startup crashes?

I believe the issue will be due to sending exceptions to Raygun in a separate thread. So in the event of a crash, the main thread terminates and brings down all the other threads with it before the request to Raygun completes.

In situations where the app is not crashing, you typically do want to send exceptions to Raygun in a thread to avoid blocking the main execution. This is easy with the Raygun4Net client because you call Send or SendInBackground as appropriate. So we need to come up with a way to control this with the Raygun Serilog Sink as currently it's hard coded to only send in a thread.

Since using Send vs SendInBackground is situational, we probably don't want a global setting that you apply once to specify which method to use. The most flexible way might be to have a particular property that's detected per log message that controls how the request is sent, but this may be cumbersome to use. The other thought is to keep Logger.Error send in background, but have Logger.Fatal send on the main thread. I lean towards that last option as it's straightforward to use, the use of those two log levels matches the choice of when you'd typically want to use Send vs SendInBackground and it should just work for most people without even needing to think about what's going on under the hood - as long as Error vs Fatal is being used as appropriate.

Any thoughts on this?

benjaminsampica commented 4 years ago

You are correct - just on startup crashes. The console application was so tiny everything was run right in startup (just doing one small thing). I agree with your primary solution - using Fatal on the main thread and Error otherwise. In the long-term, it might be worth looking into a configurable option but, as you said, for most use cases it's just not needed.

If you're looking for contributors, I could take a crack at it sometime in the next few weeks.

QuantumNightmare commented 4 years ago

Great, let's go with sending exception reports to Raygun synchronously for the Fatal log level then. Feel free to contribute a PR, though I'm currently working on other updates for this sink and could pick this up before long if you haven't already.

QuantumNightmare commented 4 years ago

Thanks for contributing a PR, I've merged this now. There's one other unrelated change that I'm working on for this Sink and will look to getting a new version released after that.

QuantumNightmare commented 4 years ago

Update - I haven't been able to work on this sink much recently, but just wrapping up the final changes this week and will next look at organizing a release.

QuantumNightmare commented 4 years ago

Version 5.0.1 has just been released to NuGet which includes your change to fix this issue.