Skip to content

Instantly share code, notes, and snippets.

@dahlsailrunner
Created August 19, 2021 16:58
Show Gist options
  • Save dahlsailrunner/29776d5caa94d9012a7a30a44e32b13f to your computer and use it in GitHub Desktop.
Save dahlsailrunner/29776d5caa94d9012a7a30a44e32b13f to your computer and use it in GitHub Desktop.

Revisions

  1. dahlsailrunner created this gist Aug 19, 2021.
    79 changes: 79 additions & 0 deletions CustomSerilogRequestLogging.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,79 @@
    # Central Code within a Library or other location

    You can create the following code in some central library or folder if desired:

    ```csharp
    public static IApplicationBuilder UseCustomSerilogRequestLogging(this IApplicationBuilder app, bool includeHealthChecks = false)
    {
    return app.UseSerilogRequestLogging(options =>
    {
    if (!includeHealthChecks)
    {
    options.GetLevel = ExcludeHealthChecks;
    }
    options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
    {
    diagnosticContext.Set("RequestHost", httpContext.Request.Host.Value);
    diagnosticContext.Set("RequestScheme", httpContext.Request.Scheme);
    var user = httpContext.User.Identity;
    if (user != null && user.IsAuthenticated)
    {
    var userInfo = GetUserInfoFromHttpContext(user as ClaimsIdentity);
    var userInfoJson = JsonConvert.SerializeObject(userInfo, Formatting.Indented);
    diagnosticContext.Set("UserInfo", userInfoJson);
    diagnosticContext.Set("LoginName", userInfo.UserName);
    }
    };
    });
    }

    private static UserInfo GetUserInfoFromHttpContext(ClaimsIdentity user)
    {
    var excluded = new List<string>
    {
    "nbf", "exp", "auth_time", "amr", "sub", "aud", "jti"
    };
    const string userIdClaimType = "sub";
    const string userNameClaimType = "userName";
    var userId = user.Claims.FirstOrDefault(a => a.Type == userIdClaimType)?.Value;
    var userName = user.Claims.FirstOrDefault(a => a.Type == userNameClaimType)?.Value;
    var userInfo = new UserInfo
    {
    UserName = userName,
    UserId = userId,
    UserClaims = new Dictionary<string, List<string>>()
    };
    foreach (var distinctClaimType in user.Claims
    .Where(a => excluded.All(ex => ex != a.Type))
    .Select(a => a.Type)
    .Distinct())
    {
    userInfo.UserClaims[distinctClaimType] = user.Claims
    .Where(a => a.Type == distinctClaimType)
    .Select(c => c.Value)
    .ToList();
    }
    return userInfo;
    }
    private static LogEventLevel ExcludeHealthChecks(HttpContext ctx, double _, Exception ex) =>
    ex != null
    ? LogEventLevel.Error
    : ctx.Response.StatusCode > 499
    ? LogEventLevel.Error
    : IsHealthCheckEndpoint(ctx) // Not an error, check if it was a health check
    ? LogEventLevel.Verbose // Was a health check, use Verbose
    : LogEventLevel.Information;

    private static bool IsHealthCheckEndpoint(HttpContext ctx)
    {
    var userAgent = ctx.Request.Headers["User-Agent"].FirstOrDefault() ?? "";
    return ctx.Request.Path.Value.EndsWith("health", StringComparison.CurrentCultureIgnoreCase) ||
    userAgent.Contains("HealthCheck", StringComparison.InvariantCultureIgnoreCase);
    }

    ```

    Then in the Configure method of Startup.cs, add this line:
    ```
    app.UseCustomSerilogRequestLogging();
    ```