So I've done some C# [#csharp] today. I tried reproducing some things I really liked in the `tracing` crate in Rust:

- The module path to the function (the call site or something ?)
- Inline parameters as context

I tried #NLog. It works very well, but getting the call site was either performance expensive or I had to do a dance when logging stuff.

I checked out #Serilog, I haven't found something where the class logging the message would be written.

I tried #log4net. The doc is a bit lackluster (where the fsck is the API doc !?) but I was able to log the module calling the log function. Haven't tried with properties yet.

Do you have any #logging libs I should checkout or some examples on paw ?

@l4p1n I think this is what you're looking for: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/caller-information

It's baked into the runtime so you can wrap your logger with this or push it into the context.

Attributes interpreted by the compiler: Tracking caller information - C# reference

These attributes instruct the compiler to generate information about the code that calls a member. You use the CallerFilePath, CallerLineNumber, CallerMemberName, and CallerArgumentExpression to provide detailed trace information

@l4p1n I think generally that logging libraries avoid this so you don’t shoot yourself in the foot. Tracing can be very intensive. In the past, I’ve used tools that take an approach of manually turning it in when you need it.

I’m betting that going down the rabbit hole of OpenTelemetry will give you lots of options, though.

@jakecarpenter You reminded me on how the tracing crate in Rust does its thing behind the scenes: procedural macros. Tracing being intensive makes sense.

I'll try logging with OpenTelemetry and see what I can get

@l4p1n I have a dirty solution for this:

`public static void Log(this object source, LogEventLevel level, string message, [CallerMemberName] string caller = "", params object[] parameters)`

It's more of a proof-of-concept just to get the idea of `[CallerMemberName]` across

@l4p1n this sounds like aspect-oriented programming to me. Tools like PostSharp can do this: https://doc.postsharp.net/il/logging
Logging

PostSharp Logging is a tool that allows detailed, customizable logging for applications. It supports various logging frameworks and structured log servers, and is especially useful for distributed systems.

@l4p1n I generally only use Serilog these days, have dropped nlog like 15 years ago, log4net when .net core came around. Serilog pretty much covers everything and more than someone could want from a logger in my experience.

Because I'm not familiar with Rust and it's tracing crates, what do they actually do?

@maxitb In a nutshell, the tracing lib has a procedural macro (code generating code, meta-programming) you write on a function. The generated code has all the information to trace what function was called with what values. Since it's code generation, there's little overhead involved at runtime.

What I appreciate in tracing, is the "context stacking" aspect, such as on one line you can sort of figure out the call chain and the values passed around functions.

I'll take note of serilog and see what I can do combined with the call site annotations in logging methods :)

@l4p1n Ah, I see. In C# you usually scope via classes by injecting a scoped logger. You can create scopes in every method but not outside. And most modern logger allow you to add properties for this scope - so you can pack everything in it (but no code generation AFAIK).

Here a link that should give you a good overview by Ben Foster:
https://benfoster.io/blog/serilog-best-practices/

Serilog Best Practices - Ben Foster

Serilog is a structured logging library for Microsoft .NET and has become the preferred logging library for .NET at Checkout.com.. It supports a variety of logging destinations, referred to as Sinks, from standard console and files based sinks to logging services such as Datadog. This guide started off as an article in our engineering handbook and after receiving positive feedback internally, I decided to release it on my blog.

Ben Foster