seq-extensions-logging icon indicating copy to clipboard operation
seq-extensions-logging copied to clipboard

Support enrichers

Open ipzKellyR opened this issue 6 years ago • 15 comments

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?

ipzKellyR avatar Aug 07 '19 02:08 ipzKellyR

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?

nblumhardt avatar Aug 07 '19 22:08 nblumhardt

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

ipzKellyR avatar Aug 08 '19 00:08 ipzKellyR

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..)

nblumhardt avatar Aug 08 '19 00:08 nblumhardt

@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.

danbopes avatar Jan 15 '22 15:01 danbopes

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

nblumhardt avatar Jan 18 '22 07:01 nblumhardt

@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.

danbopes avatar Jan 18 '22 07:01 danbopes

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).

nblumhardt avatar Jan 18 '22 07:01 nblumhardt

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.

BrianVallelunga avatar Jul 30 '22 11:07 BrianVallelunga

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 :-)

nblumhardt avatar Aug 02 '22 05:08 nblumhardt

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.

w5l avatar Nov 21 '23 06:11 w5l

@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 avatar Nov 21 '23 06:11 nblumhardt

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

nblumhardt avatar Nov 21 '23 06:11 nblumhardt

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.

w5l avatar Nov 21 '23 06:11 w5l

@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))

amitjaura avatar Jul 04 '24 01:07 amitjaura

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

nblumhardt avatar Jul 05 '24 22:07 nblumhardt