Skip to content

siganberg/Siganberg.SerilogElasticSearch

Repository files navigation

SerilogElasticSearch Nuget Nuget

What is this library?

This library extend Serilog UseSerilogRequestLogging functionality. Using UseSerilogRequestLogging is already better than Microsoft way of logging HTTP request. Instead of writing HTTP request information like method, path, timing, status code and exception details in several events, UseSerilogRequestLogging collects information during the request (including from IDiagnosticContext) and writes a single event at request completion. This reduced chattiness of the logs.

Extended functionality:

  • Hide or omit value in Request Header such as Authorization. Useful for hiding sensitive information in logs.
  • Control HTTP Request logging dynamically. For example, you don't want to log HTTP request logs from health check, metrics or swagger. Or you can use LaunchDarkly switch to control ON/OFF of HTTP request logging without restarting the application.
  • Ability to include or exclude HTTP request/response body or headers.
  • Easily able to switch developer view logging or json logging (UseDeveloperView). Developer view logging is much easier to read during development.
  • Ability to control what elastic properties to include on the log or map to a custom name. Useful if your Kibana is using different index name.

Installation

First, install the Siganberg.SerilogElasticSearch NuGet package into your app.

dotnet add package Siganberg.SerilogElasticSearch

Next, in your application's Program.cs file, configure Serilog.

public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);

    builder.UseSerilog(); //-- Switch to Serilog with extended functionality
    
    builder.Services.AddControllers();

    //-- This is optional Interceptor to control when to log HTTP request. 
    builder.Services.AddSingleton<IRequestLoggingInterceptor, YourOwnRequestLoggingInterceptor>()
    

    var app = builder.Build();
    
    app.UseRequestLogging(); //-- For logging HTTP Request. Add this before any middleware
        
    if (app.Environment.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
        
    app.UseRouting();

    app.UseAuthorization();
    app.MapControllers();
    app.Run();
}

Then, add appsettings.json configuration.

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information"
    }
  }
}

That's it.

Advance usage and configuration

Sample advance JSON configuration

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information"
    },
    "RequestLoggingOptions": {
      "IncludeResponseBody": "true",
      "IncludeRequestHeaders": "true",
      "ExcludeHeaderNames": [
        "Authorization",
        "Origin",
        "Referer"
      ]
    },
    "ElasticMappings": {
      "SourceContext": "callsite",
      "RequestMethod": "method"
    }
  }
}

Serilog

On top of default Serilog configuration, these are configuration for added functionality.

Property Default Descriptions
UseDeveloperView false Switch logging format to more compact and readable for developer.
ElasticMappings SourceContext : callsite
RequestMethod : method
Path : path
QueryString : queryString
StatusCode : responseStatus
Elapsed : durationMs
RequestHeaders : requestHeaders
RequestBody : requestBody
ResponseBody : responseBody
ContentType : contentType
ContentLength : contentLength
Control what properties to include and also there mapping name. You can use this to map to what name in Kibana index.

RequestLoggingOptions

Property Default Descriptions
IncludeResponseBody false When true, it will add middleware to capture and add response body to the RequestLogging. This add overhead and should only use for troubleshooting if necessary.
IncludeRequestHeaders true Include Request Headers.
ExcludeHeaderNames empty Array of string of header names. Ignored if IncludeRequestHeaders is set to false. Header name will still be log but value is set to <OMITTED>
ExcludeHeaderNames empty Array of string of header names. Ignored if IncludeRequestHeaders is set to false. Header name will still be log but value is set to <OMITTED>

Controlling RequestLogging dynamically

By default, there is a registered DefaultRequestLoggingInterceptor. This interceptor automatically filters out request logging for URLs containing either health, swagger, or metrics.

If you want to implement your own request logging interceptor create your own class that inherits from IRequestLoggingInterceptor and register it using dependency injection. See example above.

Note: This is only applicable for normal request flow. When ERROR occured, request logging are always injected since the goal of this logger is to get as much as information when something goes wrong.

public class RequestLoggingInterceptor : IRequestLoggingInterceptor
{
    private readonly List<string> _excludedPaths = new List<string>
    {
        "healthz",
        "swagger"
    };

    public bool IncludeRequestWhen(HttpContext context)
    {
        var path = context.Request.Path.ToString();
        if (_excludedPaths.Any(a => path.Contains(a)))
            return false;

        //-- TODO: Add more logic here.  
        //-- example: Evaluate LaunchDarkly flag to turn ON/OFF RequestLogging based on some flag.

        return true;
    }    
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published