Traditional .NET logging can slow your app. Switch to LoggerMessage delegates for better performance or leverage source-generated logging (in .NET 6+) for minimal runtime costs and cleaner code. Boost efficiency, reduce overhead, and log like a pro! 🚀
Ever wondered if logging in .NET could be made more efficient? Efficient logging is crucial for modern software development. It helps monitor applications and aids in debugging and performance tuning.
In .NET, while the traditional extension methods for logging are common, there are better, more performant ways to log messages. In this short .NET post, I will show you these options and teach you how they can elevate your logging practices. 🔥
Traditional Logging
Most .NET developers are familiar with the standard approach, like the one below.
logger.LogInformation("Processing request for {Endpoint}", endpoint);
While pretty straightforward, this method can lead to performance issues due to the repeated parsing of message templates and the overhead of handling variable parameters. Modern .NET versions may even warn you about this, which is cool! ✌️
CA1848 - Use LoggerMessage delegates for improved performance
An error/warning you might encounter in your IDE (if enabled) would be this one.
If you don't have it but would like to enable this warning, you should update your .csproj file and change the analysis level to latest-recommended. That will automatically give you this warning.
So how can we make this warning go away and improve our software? 🤓
Unlocking Performance with LoggerMessage Delegates
Wo what does that message mean? Let's break it apart a bit.
.NET offers LoggerMessage delegates to improve the performance. How? .NET is capable of pre-compiling message templates and strongly type parameters. Here’s how you can achieve just that.
Step 1 - Define a new delegate
The first thing we would have to do in our application would be to define a new delegate. In the example below I have created a new ProcessRequestLog template that I will be using whenever I log some information about processing an event in my application.
You can place it at any place in your application, but I would recommend you do it within the same project and inside a folder for all your delegates.
private static readonly Action<ILogger, string, Exception?> ProcessRequestLog =
LoggerMessage.Define<string>(
LogLevel.Information,
new EventId(101, "ProcessRequest"),
"Processing request for {Endpoint}"
);
🧑💻
A delegate in .NET is essentially a type-safe function pointer. It allows you to encapsulate a method’s reference in an object, enabling the method to be passed as a parameter or assigned to a variable. In the context of LoggerMessage, delegates help pre-define logging methods to improve performance and enforce consistency.
Step 2 - Wrap it
Now that we have a new delegate in place, we should wrap it inside an extension method for our convenience. Here is the code for that:
With the extension in place, we can now easily use it on the existing logger instance in our classes. Here how-to:
logger.LogProcessRequest("/api/users");
By following the above approach we can eliminate the need to parse the message template every time the log is invoked, improving performance in high-throughput applications. ⚡️
Taking It One Step Further
Beginning with .NET 6 we have the option to take advantage of source generators. What does that mean Christian and do I need it? Well if you want to make our logging even more efficient and developer-friendly then read along.
We are in such a lucky position that LoggerMessage is also an attribute 💪 In .NET we can use attributes to enable compile-time generation of our logging methods with little to minimal effort.
Here is how you can achieve just that.
Step 1 - Declare a partial method
The first thing we have to do is declare a partial method for our LogProcessRequest. The code you need:
With that in place, we can now continue in our business logic with the following as we did before:
logger.LogProcessRequest("/api/users");
Why do it this way compared to the first way I showed you? With this approach, the logging logic is generated at compile time, reducing runtime overhead and boilerplate code in your application.
Comparing The Two Approaches
Interested in a high-level comparison of the two approaches? Here is a quick comparison for you.
Approach
Benefits
Drawbacks
Traditional Logging
Simple and familiar
Performance overhead
LoggerMessage Delegates
High performance, strong typing
Requires additional boilerplate
Source-Generated Logging
Best performance, minimal code
Requires .NET 6 or later
Pro Tips for Better Logging
Here are my top three tips for improved logging in .NET applications.
Set Analysis Level - Enabling latest-recommended analyzers help identify areas for improvement directly in your IDE.
Use Event IDs - Event IDs will make it easier to filter and identify logs at runtime.
Leverage Source Generation - It’s the future of logging in .NET, reducing runtime costs - what's not to like?!
Summary
Modern .NET frameworks provide several tools for high-performance logging, from LoggerMessage delegates to source-generated logging.
By using these built-in methods, you can write cleaner, faster, and more maintainable logging code. I am sure you and your colleagues will thank you. I hope you learned something new in this short post. Until next time - Happy coding! ✌️
My name is Christian. I am a 28-year-old Solution Architect & Software Engineer with a passion for .NET, Cloud, and Containers. I love to share my knowledge and teach other like-minded about tech.
How To Achieve High-Performance Logging in .NET
Traditional .NET logging can slow your app. Switch to LoggerMessage delegates for better performance or leverage source-generated logging (in .NET 6+) for minimal runtime costs and cleaner code. Boost efficiency, reduce overhead, and log like a pro! 🚀
— Christian Schou Køster
How To Achieve High-Performance Logging in .NET
Ever wondered if logging in .NET could be made more efficient? Efficient logging is crucial for modern software development. It helps monitor applications and aids in debugging and performance tuning.
In .NET, while the traditional extension methods for logging are common, there are better, more performant ways to log messages. In this short .NET post, I will show you these options and teach you how they can elevate your logging practices. 🔥
Traditional Logging
Most .NET developers are familiar with the standard approach, like the one below.
While pretty straightforward, this method can lead to performance issues due to the repeated parsing of message templates and the overhead of handling variable parameters. Modern .NET versions may even warn you about this, which is cool! ✌️
CA1848 - Use LoggerMessage delegates for improved performance
An error/warning you might encounter in your IDE (if enabled) would be this one.
If you don't have it but would like to enable this warning, you should update your
.csproj
file and change the analysis level tolatest-recommended
. That will automatically give you this warning.So how can we make this warning go away and improve our software? 🤓
Unlocking Performance with LoggerMessage Delegates
Wo what does that message mean? Let's break it apart a bit.
.NET offers
LoggerMessage
delegates to improve the performance. How? .NET is capable of pre-compiling message templates and strongly type parameters. Here’s how you can achieve just that.Step 1 - Define a new delegate
The first thing we would have to do in our application would be to define a new delegate. In the example below I have created a new
ProcessRequestLog
template that I will be using whenever I log some information about processing an event in my application.You can place it at any place in your application, but I would recommend you do it within the same project and inside a folder for all your delegates.
LoggerMessage
, delegates help pre-define logging methods to improve performance and enforce consistency.Step 2 - Wrap it
Now that we have a new delegate in place, we should wrap it inside an extension method for our convenience. Here is the code for that:
Step 3 - Use it
With the extension in place, we can now easily use it on the existing logger instance in our classes. Here how-to:
By following the above approach we can eliminate the need to parse the message template every time the log is invoked, improving performance in high-throughput applications. ⚡️
Taking It One Step Further
Beginning with .NET 6 we have the option to take advantage of source generators. What does that mean Christian and do I need it? Well if you want to make our logging even more efficient and developer-friendly then read along.
We are in such a lucky position that
LoggerMessage
is also an attribute 💪 In .NET we can use attributes to enable compile-time generation of our logging methods with little to minimal effort.Here is how you can achieve just that.
Step 1 - Declare a partial method
The first thing we have to do is declare a partial method for our
LogProcessRequest
. The code you need:With that in place, we can now continue in our business logic with the following as we did before:
Why do it this way compared to the first way I showed you? With this approach, the logging logic is generated at compile time, reducing runtime overhead and boilerplate code in your application.
Comparing The Two Approaches
Interested in a high-level comparison of the two approaches? Here is a quick comparison for you.
Pro Tips for Better Logging
Here are my top three tips for improved logging in .NET applications.
latest-recommended
analyzers help identify areas for improvement directly in your IDE.Summary
Modern .NET frameworks provide several tools for high-performance logging, from
LoggerMessage
delegates to source-generated logging.By using these built-in methods, you can write cleaner, faster, and more maintainable logging code. I am sure you and your colleagues will thank you. I hope you learned something new in this short post. Until next time - Happy coding! ✌️
Resources
My name is Christian. I am a 28-year-old Solution Architect & Software Engineer with a passion for .NET, Cloud, and Containers. I love to share my knowledge and teach other like-minded about tech.