datalust / seq-extensions-logging

Add centralized log collection to ASP.NET Core apps with one line of code.
https://datalust.co/seq
Apache License 2.0
84 stars 12 forks source link

Support enrichers #28

Open ipzKellyR opened 4 years ago

ipzKellyR commented 4 years ago

The setup for this is great because its one line and then add a config section, but using this method you cannot easily add enrichers. Am I mistaken?

nblumhardt commented 4 years ago

Thanks for the note. This package wraps up and completely internalizes these bits of Serilog, and it would probably be confusing to expose interfaces like ILogEventEnricher, but, some cut-down enrichment functionality seems useful enough to include.

Which enrichers in particular did you have in mind?

ipzKellyR commented 4 years ago

would it be possible to allow someone to pass enrichers in as options? In my case I want to use custom enrichers.

nblumhardt commented 4 years ago

Probably not via ILogEventEnricher, but something like Func<(string, object)> could be used to provide simple enrichment from ambient state, without necessitating exposure of types like LogEvent, LogEventPropertyValue and so on. Would that work in your case?

    .AddSeq(..., () => ("ThreadId", Thread.CurrentThread.ManagedThreadId))

(We'd need to figure out a workable API to allow for multiple enrichers to be passed, but the above might illustrate the basic idea..)

danbopes commented 2 years ago

@nblumhardt Any chance we can get this implemented. I hate to switch my entire logger over to serilog just to add this feature, but having hostname or the managedthreadid on each log entry would be super helpful.

nblumhardt commented 2 years ago

Thanks for the nudge, @danbopes; I'm taking another look at this now.

danbopes commented 2 years ago

@nblumhardt I ended up adding serilog but only as a logging provider to .net core, which honestly wasn't as bad as I thought. This case I could already leverage all of the .net core ILogger features without having to rewrite a ton of code:

builder.Services.AddLogging(loggingBuilder =>
{
    var serverUrl = builder.Configuration.GetValue<string>("Logging:Seq:ServerUrl");
    var apiKey = builder.Configuration.GetValue<string>("Logging:Seq:ApiKey");

    var logger = new LoggerConfiguration()
        .Enrich.WithAssemblyInformationalVersion()
        .Enrich.WithMachineName()
        .MinimumLevel.Verbose()
        .WriteTo.Console(Serilog.Events.LogEventLevel.Information)
        .WriteTo.Seq(serverUrl, apiKey: apiKey)
        .CreateLogger();

    loggingBuilder.AddSerilog(logger, true);
});

My only pain point now, is simply having to convert json back to a structure to be reencoded with json again.

nblumhardt commented 2 years ago

Thanks for the update @danbopes. UseSerilog() still supports .NET's ILogger, just in case that helps (UseSerilog() is generally a bit more predictable when it comes to levels/filters).

BrianVallelunga commented 2 years ago

Call it an enricher if you want, but it would be nice to be able to just add a few items to the global logging scope supported by ILogger's BeginScope(). I'm specifically looking to add something like a version number or application name. Just static data at the app's start, nothing more.

nblumhardt commented 1 year ago

I've kicked off some work on this; I think because it'll be best if accessible via JSON configuration, it's a good time to overhaul how the sink is configured, so that's the first cab off the rank. I'll keep this thread updated as I go :-)

w5l commented 8 months ago

What speaks against simply opening up ILogEventEnricher (or a variant of it) to dependency injection? We could then register any enricher implementation with DI and have it injected, keeping configuration simple. Adding a default implementation of EnvironmentValueEnricher and/or StaticValueEnricher to the library would cover most people's requirements.

services.AddSingleton<ILogEventEnricher>(() => new StaticValueEnricher("..."));

This matches part of the ITelemetryProcessor pattern in use by Azure AppInsights, see Filter and preprocess telemetry in the Application Insights SDK. Even more powerful, they allow post processing and filtering of the entire log message. Something like a basic ILogProcessor.Process(LogEvent event, Func<LogEvent> next); would cover pretty much every possible use case here.

Would you be open to a PR in either of these directions? Pretty much all code required to support this is already there (ILogEventEnricher, FixedPropertyEnricher, the SafeAggregateEnricher even already takes a collection). It's just all internal right now, for no obvious reason.

nblumhardt commented 8 months ago

@w5l this is already implemented via ReadFrom.Services(serviceCollection), check out the Serilog.AspNetCore examples to see how it's used (IIRC).

ReadFrom.Services() supports sinks, filters, enrichers, and destructuring policies. HTH!

nblumhardt commented 8 months ago

@w5l sorry, I see I'm in datalust-extensions-logging and not serilog-extensions-logging, which I also maintain 😅

w5l commented 8 months ago

No worries, a little shock there thinking I've overseen something glaringly obvious 🙈 but yeah, like the people before me in this thread I was hoping to have this supported in the datalust-seq version without using full-blown serilog.

amitjaura commented 3 weeks ago

@nblumhardt - Just checking if this is in the pipeline. It will be nice to have enrichers setup along with Seq. I like the idea of

.AddSeq(..., () => ("ThreadId", Thread.CurrentThread.ManagedThreadId))

nblumhardt commented 3 weeks ago

Thanks for the nudge @amitjaura, I'll try to loop back to this soon.