serilog / serilog-aspnetcore

Serilog integration for ASP.NET Core
Apache License 2.0
1.32k stars 209 forks source link

Blazor Component Details -- Adding Custom Enrichers #164

Closed kevingates closed 4 years ago

kevingates commented 4 years ago

Problem

The Default Routing gives RequestPath, but with Blazor that's /_Blazor.

I would like to be able to have the File/Component Name, the Method Being Called, and Any Method Parameters for proper debugging.

Type of Data Desired

On a standard Log.Information, I could do this:

Log.Information("Component: {BlazorComponentName} -- Method: {MethodName} -- Parameters: {Parameters}", MethodBase.GetCurrentMethod().DeclaringType, MethodBase.GetCurrentMethod(), MethodBase.GetCurrentMethod().GetParameters());

Desired Solution

Which does return for me the helpful information. But Honestly, I think this would be helpful for all of my log entries so I know in what files the events occurred, which would be helpful for debugging. So if I do Log.Error or Log.Information, I will always have those 3 things supplied.

Current Attempt

I've tried to follow the guide to create a new file:


using System;
using System.Reflection;
using Serilog.Core;
using Serilog.Events;

namespace GCSerilogEnricher
{
    public class AddComponentMethodParametersSerilogEnricher : ILogEventEnricher
    {
        public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
        {
            if (logEvent is null)
            {
                throw new ArgumentNullException(nameof(logEvent));
            }
            logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(
                "ComponentName", MethodBase.GetCurrentMethod().DeclaringType)
                );
            logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(
                "MethodName", MethodBase.GetCurrentMethod())
                );
            logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(
                "Parameters", MethodBase.GetCurrentMethod().GetParameters())
                );
        }
    }
}

At this point, I'm at a loss of getting this connected to the enricher. I'm using appsettings for my Serilog configuration.

Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Configuration;
using Serilog;

namespace DSS_SpecialAccounts_BlazorServerSideApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();

            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)
                .CreateLogger();

            try
            {
                Log.Information("Application Starting Up");
                CreateHostBuilder(args).Build().Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "The application failed to start correctly.");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }

        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                        .UseSerilog()
                        .ConfigureWebHostDefaults(webBuilder =>
                        {
                            webBuilder.UseStartup<Startup>();
                        });
        }

    }
}

appsettings.json, the relevant parts:

 "Serilog": {
    "Using": [ "AddComponentMethodParametersSerilogEnricher" ],
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId", "AddComponentMethodParametersSerilogEnricher" ],
    "WriteTo": [
      { "Name": "Console" },
      {
        "Name": "File",
        "Args": {
          "path": ".......txt",
          "rollingInterval": "Day",
          "rollOnFileSizeLimit": true,
          "fileSizeLimitBytes": "512",
          "retainedFileCountLimit": 3,
          "outputTemplate": "{Timestamp:G} {Message}{NewLine:1}{Exception:1}"
        }
      },
      {
        "Name": "File",
        "Args": {
          "path": "....json",
          "rollingInterval": "Day",
          "rollOnFileSizeLimit": true,
          "fileSizeLimitBytes": "10240",
          "retainedFileCountLimit": 3,
          "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog"
        }
      }
    ]
  }
sungam3r commented 4 years ago
public static class NameDoesNotMatter
{ 
 public static LoggerConfiguration WithMethodParameters(this LoggerEnrichmentConfiguration enrichmentConfiguration)
        {
            if (enrichmentConfiguration == null)
                throw new ArgumentNullException(nameof(enrichmentConfiguration));
            return enrichmentConfiguration.With<AddComponentMethodParametersSerilogEnricher>();
        }
}

+

 "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId", "WithMethodParameters" ]
sungam3r commented 4 years ago

But I think that MethodBase.GetCurrentMethod().DeclaringType will always return AddComponentMethodParametersSerilogEnricher

nblumhardt commented 4 years ago

Assuming @sungam3r 's solution sorted this out :+1: