Telemetry and monitoring are two important techniques in software development to get more details about the workflow and resources used by the application during the execution.
Using this information we can perform the following actions:
- Analyze issues in production where it could be difficult to debug the code.
- Get details about the interaction between components.
- Track duration time in processes to improve performance.
- Identify internal issues
- Collect information to analyze user behavior.
There are many ways for monitoring and logging in .NET Applications. We can use the following namespaces:
- Diagnostics.Trace
- Diagnostics.Debug
- Diagnostics.EventSource
- Diagnostics.Activity
- Diagnostics.EventLog (Only for Windows)
We can potentialize and extend all these features using libraries. In the following list you can find many options to use for logging and monitoring:
- Serilog
- Log4Net
- Nlog
- Elmah.io
- Gelf4Net
Even though all these tools are petty good and valid options for many scenarios we need to mention some challenges or disadvantages:
- Compatibility with other technologies (.NET Oriented)
- Only windows support
- Performance affectations
- No standard in the formats (different format for each library)
Here is where OpenTelemetry helps us to resolve these challenges.
OpenTelemetry
OpenTelemetry is a set of tools to collect telemetry data to analyze behavior and performance. It supports logs, metrics, and traces, which means all the activities related to observability.
OpenTelemetry is completely open source, free, and also a standard across different technologies.
You can find more information from the official webpage: https://opentelemetry.io/
To start using OpenTelemetry we need to perform the following steps:
1. Create a console project
dotnet new consoleĀ
2. Add the last version of Microsoft.Extensions.Logging package
dotnet add package Microsoft.Extensions.Logging
3. Add OpenTelemetry exporter library
dotnet add package OpenTelemetry.Exporter.Console
4. Update Program.cs with the following example:
using Microsoft.Extensions.Logging;
using OpenTelemetry.Logs;
using
var loggerFactory = LoggerFactory.Create(builder => {
builder.AddOpenTelemetry(options => {
options.AddConsoleExporter();
});
});
var logger = loggerFactory.CreateLogger < Program > ();
logger.LogInformation("Hello from OpenTelemetry");
For this example, we will get the following result:
Now we can see another example related to metrics. Metrics is related to data calculated that give us more details about user behavior.
// See https://aka.ms/new-console-template for more information
using Microsoft.Extensions.Logging;
using System.Diagnostics.Metrics;
using OpenTelemetry;
using OpenTelemetry.Metrics;
Meter MyMeter = new("ConsoleDemo.Metrics", "1.0");
Counter<long> RequestCounter = MyMeter.CreateCounter<long>("RequestCounter");
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter("ConsoleDemo.Metrics")
.AddConsoleExporter()
.Build();
RequestCounter.Add(1, new KeyValuePair<string, object?>("POST Request", HttpMethod.Post));
RequestCounter.Add(1, new KeyValuePair<string, object?>("GET Request", HttpMethod.Get));
RequestCounter.Add(1, new KeyValuePair<string, object?>("GET Request", HttpMethod.Get));
RequestCounter.Add(1, new KeyValuePair<string, object?>("POST Request", HttpMethod.Post));
RequestCounter.Add(1, new KeyValuePair<string, object?>("PUT Request", HttpMethod.Put));
In the following result we can see the number of POST, GET and PUT request
Trace is another tool that we can use to get information about how the components interact and the performance in some specific scenarios. We can add tags to include the values used in the process or workflow.
using OpenTelemetry;
using OpenTelemetry.Trace;
using System.Diagnostics;
ActivitySource MyActivitySource = new("ConsoleDemo.Trace");
using
var tracerProvider = Sdk.CreateTracerProviderBuilder().AddSource("ConsoleDemo.Trace").AddConsoleExporter().Build();
using(var activity = MyActivitySource.StartActivity("ActivityStarted")) {
int StartNumber = 10000;
activity?.SetTag("StartNumber", StartNumber);
for (int i = 0; i < StartNumber; i++) {
DoProcess(i);
}
activity?.SetStatus(ActivityStatusCode.Ok);
}
void DoProcess(int currentNumber) {
var doubleValue = currentNumber * 2;
}
For this example, we will get the following output:
With these examples, we have an idea about how to start with OpenTelemetry in .NET. You access the repo via the following link:
https://github.com/Mteheran/OpenTelemetrydotnet