asp.net-coreserilogserilog-filter

Serilog logging to different tables


I am using Serilog on .NET and I am trying to log on different tables. To achieve this, I seem to understand that I need to use filters. I already have all my configuration in appsettings.json file, so I would like to keep using the file instead of moving this setting in the code but I cannot seem to understand how to do it.

I was able to specify a global level filter and it works, but I would like the filter to be specific for a sink. Following is the relevant section of my appsettings.json file:

"Serilog": {
  "Using": [
    "Serilog.Sinks.Console",
    "Serilog.Sinks.File",
    "Serilog.Sinks.MSSqlServer",
    "Serilog.Expressions"
  ],
  "MinimumLevel": {
    "Default": "Information"
  },
  //"Filter": [
  //  {
  //    "Name": "ByIncludingOnly",
  //    "Args": {
  //      "expression": "SourceContext like '%ApiRequest%'"
  //    }
  //  }
  //],
  "WriteTo": [
    {
      "Name": "Console",
      "Args": {
        "restrictedToMinimumLevel": "Information",
        "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
        "outputTemplate": "[{Timestamp:u} {Level:u3}] {Message:lj} <{SourceContext}> <{LogTypeName}>{NewLine}{Exception}"
      }
    },
    {
      "Name": "File",
      "Args": {
        "restrictedToMinimumLevel": "Debug",
        "path": "Logs/log.txt",
        "outputTemplate": "[{Timestamp:u} {Level:u3}] {Message:lj} <{SourceContext}> <{LogTypeName}>{NewLine}{Exception}",
        "rollOnFileSizeLimit": true,
        "fileSizeLimitBytes": 4194304,
        "retainedFileCountLimit": 500,
        "rollingInterval": "Day"
      }
    },
    {
      "Name": "MSSqlServer",
      "Args": {
        "connectionString": "DocumentsDatabaseConnectionString",
        "sinkOptionsSection": {
          "tableName": "Log_ApiRequests",
          "autoCreateSqlTable": true,
          "configureLogger": {
            "Filter": [
              {
                "Name": "ByIncludingOnly",
                "Args": {
                  "expression": "SourceContext like '%ApiRequest%'"
                }
              }
            ]
          }
        },
        "restrictedToMinimumLevel": "Information"
      }
    },
    {
      "Name": "MSSqlServer",
      "Args": {
        "connectionString": "DocumentsDatabaseConnectionString",
        "sinkOptionsSection": {
          "tableName": "Log_ApiResponses",
          "autoCreateSqlTable": true
        },
        "columnOptionsSection": {
          "additionalColumns": [
            {
              "ColumnName": "EventId",
              "DataType": "uniqueidentifier",
              "AllowNull": false
            },
            {
              "ColumnName": "HTTPMethod",
              "DataType": "nvarchar",
              "DataLength": 50
            },
            {
              "ColumnName": "Endpoint",
              "DataType": "nvarchar",
              "DataLength": 256
            },
            {
              "ColumnName": "Body",
              "DataType": "nvarchar",
              "DataLength": 4000
            },
            {
              "ColumnName": "StatusCode",
              "DataType": "int"
            },
            {
              "ColumnName": "RequestGuid",
              "DataType": "uniqueidentifier",
              "AllowNull": true
            },
            {
              "ColumnName": "ResponseTime",
              "DataType": "int",
              "AllowNull": true
            }
          ]
        },
        "restrictedToMinimumLevel": "Information"
      }
    }
  ],
  "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]

It is not working as every log of my application is written in the Log_ApiRequests table, even if it does not meet the filter criteria. What am I doing it wrong? Is it even possible to achieve this?

I tried reading Serilog offical doc and asking ChatGPT but they were of no help, as the doc is incomplete and ChatGPT gives deprecated answers


Solution

  • Test Result

    enter image description here

    Here is the sample settings for you.

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*",
      "Serilog": {
        "Using": [
          "Serilog.Sinks.Console",
          "Serilog.Sinks.File",
          "Serilog.Sinks.MSSqlServer",
          "Serilog.Expressions"
        ],
        "MinimumLevel": "Debug",
        "Enrich": [ "FromLogContext" ],
        "WriteTo": [
          {
            "Name": "Logger",
            "Args": {
              "configureLogger": {
                "Filter": [
                  {
                    "Name": "ByIncludingOnly",
                    "Args": {
                      "expression": "SourceContext = 'ApiRequestLogger'"
                    }
                  }
                ],
                "WriteTo": [
                  {
                    "Name": "Console",
                    "Args": {
                      "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
                    }
                  },
                  {
                    "Name": "MSSqlServer",
                    "Args": {
                      "connectionString": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=LogsDb;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False",
                      "sinkOptionsSection": {
                        "tableName": "Log_ApiRequests",
                        "autoCreateSqlTable": true
                      },
                      "restrictedToMinimumLevel": "Information"
                    }
                  }
                ]
              }
            }
          },
          {
            "Name": "Logger",
            "Args": {
              "configureLogger": {
                "Filter": [
                  {
                    "Name": "ByIncludingOnly",
                    "Args": {
                      "expression": "SourceContext = 'ApiResponseLogger'"
                    }
                  }
                ],
                "WriteTo": [
                  {
                    "Name": "Console",
                    "Args": {
                      "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
                    }
                  },
                  {
                    "Name": "MSSqlServer",
                    "Args": {
                      "connectionString": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=LogsDb;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False",
                      "sinkOptionsSection": {
                        "tableName": "Log_ApiResponses",
                        "autoCreateSqlTable": true
                      },
                      "restrictedToMinimumLevel": "Information"
                    }
                  }
                ]
              }
            }
          },
          {
            "Name": "File",
            "Args": {
              "path": "logs/log.txt",
              "rollingInterval": "Day",
              "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
            }
          }
        ]
      }
    }