-
-
Save nblumhardt/0e1e22f50fe79de60ad257f77653c813 to your computer and use it in GitHub Desktop.
using System; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Runtime.CompilerServices; | |
using Serilog; | |
using Serilog.Configuration; | |
using Serilog.Core; | |
using Serilog.Events; | |
namespace ConsoleApp24 | |
{ | |
class CallerEnricher : ILogEventEnricher | |
{ | |
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) | |
{ | |
var skip = 3; | |
while (true) | |
{ | |
var stack = new StackFrame(skip); | |
if (!stack.HasMethod()) | |
{ | |
logEvent.AddPropertyIfAbsent(new LogEventProperty("Caller", new ScalarValue("<unknown method>"))); | |
return; | |
} | |
var method = stack.GetMethod(); | |
if (method.DeclaringType.Assembly != typeof(Log).Assembly) | |
{ | |
var caller = $"{method.DeclaringType.FullName}.{method.Name}({string.Join(", ", method.GetParameters().Select(pi => pi.ParameterType.FullName))})"; | |
logEvent.AddPropertyIfAbsent(new LogEventProperty("Caller", new ScalarValue(caller))); | |
return; | |
} | |
skip++; | |
} | |
} | |
} | |
static class LoggerCallerEnrichmentConfiguration | |
{ | |
public static LoggerConfiguration WithCaller(this LoggerEnrichmentConfiguration enrichmentConfiguration) | |
{ | |
return enrichmentConfiguration.With<CallerEnricher>(); | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Log.Logger = new LoggerConfiguration() | |
.Enrich.WithCaller() | |
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message} (at {Caller}){NewLine}{Exception}") | |
.CreateLogger(); | |
Log.Information("Hello, world!"); | |
SayGoodbye(); | |
Log.CloseAndFlush(); | |
} | |
[MethodImpl(MethodImplOptions.NoInlining)] | |
static void SayGoodbye() | |
{ | |
Log.Information("Goodbye!"); | |
} | |
} | |
} |
@johannesmols This is a great solution! I switched from my home brewn one to yours. Works like a charm. Thx a lot!
@digitalsigi Awesome, great to hear!
@johannesmols, @nblumhardt
Hi, I need to close the nuget and github the next days (...), do you like to take over the nuget
https://www.nuget.org/packages/Serilog.Enrichers.WithCaller
Thanks
@pmetz-steelcase Sure, I can take over the nuget package. Will be difficult to maintain it without the source code though. Do you mind me asking why you deleted it?
@johannesmols sorry, it's public again, I have to delete my account
@pmetz-steelcase okay, I made a fork https://github.com/johannesmols/Serilog.Enrichers.WithCaller to preserve the code. On nuget, you can transfer ownership as well (same username as on github). I won't update the package since I created my own improved version of it, but then we will at least have the code available still if someone needs it or makes a PR.
@johannesmols
I added you as additional owner of nuget, after your approval, I'll remove my name
question, the code https://github.com/pm4net/serilog-enrichers-callerinfo , it is yours, too?
@pmetz-steelcase great, I accepted it. And yes, that is my spin on it that I created to suit my needs better
I stumbled upon this because I needed the namespace, source file, line number, etc. in a structured format. The package posted above is great but throws everything into a single string, making it hard to parse the different values again.
I made a new library based on this code but adds all these attributes separately. It also supports multiple assemblies in multi-project solutions and can figure out the referenced assemblies by itself. You can also configure a prefix for the attribute names to avoid name clashes.
It is available here: https://github.com/pm4net/serilog-enrichers-callerinfo/. Hopefully it is useful for not just my use case :)