Understanding .NET 8 Observability
Every developer and customer wants to understand their application or website’s performance and identify areas for improvement. To enhance user experience and pinpoint bottlenecks, the application should provide logs, metrics, and tracing data. By analysing this data, we can plan and implement necessary changes to our application.
Observability has three pillars.
Distributed Tracing
It helps to track requests and activities across components in a distributed setup, allowing you to identify time-consuming processes and locate specific failures.
Logs
A log typically includes details on how an application processes requests and any unusual occurrences, such as exceptions. System logs can be structured or unstructured. Microsoft.Extensions.Logging aids in monitoring application behavior and diagnosing issues. Various third-party logging frameworks are available in the market, such as NLog, Log4Net, and Serilog. Some of these frameworks offer semantic logging.
Metrics
The numerical representation of data logging allows us to identify various aspects of system performance. These include application performance, uptime, system processing power, and memory usage etc., This data is crucial in making informed decisions about system improvements and upgrades.
Implementing observability in .NET 8
There are various ways to implement observability.
- Using telemetry libraries in our code like OpenTelemetry.
- EventPipe
- Using a startup hook.
Implementing OpenTelemetry in our code.
The following repositories are available in OpenTelemetry.NET.
- OpenTelemetry.NET
- OpenTelemetry.NET.Contrib
- OpenTelemetry.NET.AutomaticInstrumentation
Applying OpenTelemetry in a .NET Console Application
Step 1: Create Console Application using .NET CLI
dotnet new console Example.Observability.Series.Console
cd Example.Observability.Series.Console
Step 2: Add NuGet Package
dotnet add package OpenTelemetry.Exporter.Console
Step 3: Add Extensions Directory
mkdir Extensions
Step 4: Add LoggerExtensions Class
public static partial class LoggerExtensions
{
//Log - Information
[LoggerMessage(
LogLevel.Information,
"Tracking #: {trackingNo} added in the Delivery Ticket")]
public static partial void TrackingNoAdded(
this ILogger logger,
string trackingNo);
//Log - Critical
[LoggerMessage(
LogLevel.Critical,
"Order has been cancelled #: {orderNo} for customer {customerId} , {customerName}, {cancelReason}")]
public static partial void OrderCancelled(
this ILogger logger,
string orderNo,
string customerId,
string customerName,
string cancelReason);
}
Step 5: Use LoggerExtension in Program.cs
using Example.Observability.Series.Console.Extensions;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Logs;
#region Initialize Logging
// Create Logger Factory
var loggerFactory = LoggerFactory.Create(
builder =>
{
builder.AddOpenTelemetry(log =>
{
log.AddConsoleExporter();
});
});
// Create Logger
var logger = loggerFactory.CreateLogger<Program>();
#endregion
#region Logging
logger.TrackingNoAdded("3939dkkd3993a-339934");
logger.OrderCancelled(
"CC-20240605121",
"388834CD223",
"ABC Technologies Inc",
"Customer wants different product!");
#endregion
//Dispose the Logger Factory
loggerFactory.Dispose();
Conclusion
Enhancing application visibility in .NET 8 involves understanding and implementing observability. Observability has three pillars: distributed tracing, logs, and metrics. Implementing observability can be achieved using telemetry libraries like OpenTelemetry, EventPipe, or a startup hook. The document also provides a step-by-step guide on applying OpenTelemetry in a .NET console application.