Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] HttpContext.User is not used in Serilog EcsTextFormatter #350

Open
luuksommers opened this issue Dec 14, 2023 · 2 comments
Open

[BUG] HttpContext.User is not used in Serilog EcsTextFormatter #350

luuksommers opened this issue Dec 14, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@luuksommers
Copy link

luuksommers commented Dec 14, 2023

ECS integration/library project(s): Elastic.CommonSchema.Serilog 8.6.1, Serilog 3.1.1

ECS .NET assembly version (e.g. 1.4.2): 8.6.1

.NET framework / OS: .NET 6 / Windows 11

Description of the problem, including expected versus actual behavior:

Steps to reproduce:

  1. Use ASP.NET Core with authentication and ClaimsIdentity (e.g. a user is logged in)
  2. The user claims are not included in the ecs output

Cause:
The logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(PropertyName, r)); in the HttpContextEnricher doesn't store the raw object, instead the default propertyFactory does a .ToString() of the r-value, which makes the value of the property: Elastic.CommonSchema.Serilog.HttpContextEnricher,Elastic.CommonSchema.Serilog instead or the original object. In the LogEventConverter, the object cannot be retrieved in (for example) the GetUser method

if (e.TryGetScalarPropertyValue(SpecialKeys.HttpContext, out var httpContext)
	 && httpContext.Value is HttpContextEnricher.HttpContextEnrichments enriched) // httpContext.Value is a string!!
	return enriched.User; // <-- never returned

This causes that the reported user is always the environment user instead of the user doing the request.

A workaround is to override the enricher:

using Elastic.CommonSchema.Serilog;
using Serilog.Core;
using Serilog.Events;

public class PatchedHttpContextEnricher : HttpContextEnricher, ILogEventEnricher
{
    private readonly RawPropertyFactory _rawPropertyFactory;

    public PatchedHttpContextEnricher(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
    {
        _rawPropertyFactory = new RawPropertyFactory();
    }

    void ILogEventEnricher.Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        base.Enrich(logEvent, _rawPropertyFactory);
    }

    private class RawPropertyFactory : ILogEventPropertyFactory
    {
        public LogEventProperty CreateProperty(
            string name,
            object? value,
            bool destructureObjects = false)
        {
            return new LogEventProperty(name, new ScalarValue(value));
        }
    }
}
builder.Host.UseSerilog((ctx, config) =>
{
    // Ensure HttpContextAccessor is accessible
    var httpAccessor = ctx.Configuration.Get<HttpContextAccessor>();

    config
        .ReadFrom.Configuration(ctx.Configuration)
        //.Enrich.WithEcsHttpContext(httpAccessor) <-- this is the unpatched code
        .Enrich.With(new PatchedHttpContextEnricher(httpAccessor));
});
@luuksommers luuksommers added the bug Something isn't working label Dec 14, 2023
@fetters5
Copy link

fetters5 commented Jan 5, 2024

Thanks I also ran into this issue and this helped me get httpContext information

One minor change was that for me the following line in the RawPropertyFactory has to be

return new LogEventProperty(name, new ScalarValue(value));

@luuksommers
Copy link
Author

Thanks I also ran into this issue and this helped me get httpContext information

One minor change was that for me the following line in the RawPropertyFactory has to be

return new LogEventProperty(name, new ScalarValue(value));

You're right, I've updated the original post with your comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants