简体   繁体   中英

ASP.NET Core 3 - Serilog how to configure Serilog.Sinks.Map in appsettings.json file?

I came across the Serilog.Sinks.Map addon today which will solve my challenge with routing specific log events to a specific sink interface. In my environment, I am writing to a log file as well as using the SQL interface. I only want certain logs to be written to the SQL Server though.

Reading the instructions on GitHub by the author, I can only see an example for implementing the LoggerConfiguration through C# in the Program.CS, but I am using the appsettings.json file and unsure what to change from the provided example to the required json format.

Example given by Serilog on GitHub:

Log.Logger = new LoggerConfiguration()
.WriteTo.Map("Name", "Other", (name, wt) => wt.File($"./logs/log-{name}.txt"))
.CreateLogger();

My current configuration: Note I haven't implemented the Sinks.Map in my code yet. Program.CS File:

public static void Main(string[] args)
{
    // Build a configuration system with the route of the app settings.json file.
    // this is becuase we dont yet have dependancy injection available, that comes later.
    var configuration = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json")
        .Build();

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

    var host = CreateHostBuilder(args).Build();
}

And here is my appsettings.json file. I want to be able configure sink name 'MSSqlServer' as the special route, then use the standard file appender sink for all the other general logging.

    "AllowedHosts": "*",
  "Serilog": {
    "Using": [],
    "MinumumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
    "WriteTo": [
      { "Name": "Console" },
      {
        "Name": "File",
        "Args": {
          //"path": "C:\\NetCoreLogs\\log.txt", // Example path to Windows Drive.
          "path": ".\\Logs\\logs.txt",
          //"rollingInterval": "Day", // Not currently in use.
          "rollOnFileSizeLimit": true,
          //"retainedFileCountLimit": null, // Not currently in use.
          "fileSizeLimitBytes": 10000000,
          "outputTemplate": "{Timestamp:dd-MM-yyyy HH:mm:ss.fff G} {Message}{NewLine:1}{Exception:1}"
          // *Template Notes*
          // Timestamp 'G' means UTC Time
        }
      },
      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": "DefaultConnection",
          "schemaName": "EventLogging",
          "tableName": "Logs",
          "autoCreateSqlTable": true,
          "restrictedToMinimumLevel": "Information",
          "batchPostingLimit": 1000,
          "period": "0.00:00:30"
        }
      }
      //{
      //  "Name": "File",
      //  "Args": {
      //    "path": "C:\\NetCoreLogs\\log.json",
      //    "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog"
      //  }
      //}
    ]
  }

Lastly if i could squeeze in another quick question on the topic, when using the SQL sink interface, how do manage the automatic purging/deletion of the oldest events ie DB should only store max 1,000,000 events then automatically write over the oldest event first, thanks in advance

I believe it is currently impossible to configure the standard Map call in json, since it relies on a few types that have no serialization support right now, like Action<T1, T2> . I created an issue to discuss this in the repository itself:

However, there is a way to still get some functionality out of it in Json, by creating a custom extension method. In your particular case, it would be something like this:

    public static class SerilogSinkConfigurationExtensions
    {
        public static LoggerConfiguration MapToFile(
            this LoggerSinkConfiguration loggerSinkConfiguration,
            string keyPropertyName,
            string pathFormat,
            string defaultKey)
        {
            return loggerSinkConfiguration.Map(
                keyPropertyName,
                defaultKey,
                (key, config) => config.File(string.Format(pathFormat, key));
        }
    }

Then, on your json file, add a section like this:

    "WriteTo": [
      ...
      {
        "Name": "MapToFile",
        "Args": {
          "KeyPropertyName": "Name",
          "DefaultKey": "Other",
          "PathFormat": "./logs/log-{0}.txt"
        }
      }
    ]

To have these customizations work properly, Serilog needs to understand that your assembly has these kinds of extensions, to load them during the parsing stage. As per the documentation, you either need to have these extensions on a *.Serilog.* assembly, or add the Using clause on the json:

// Assuming the extension method is inside the "Company.Domain.MyProject" dll
"Using": [ "Company.Domain.MyProject" ]

More information on these constraints here:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM