Observability
Observability is integrated through support for OpenTelemetry, the open standard for distributed tracing and metrics collection.
Logging
Logs are very useful for developer when coding. The following example shows how to :
- subscribe to all SimpleW
Event
withopenTelemetryObserver()
- log each request to console with
LogProcessor
(do not use for production).
using System;
using System.Net;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using SimpleW;
namespace Sample {
class Program {
static void Main() {
// subscribe to all SimpleW events
openTelemetryObserver("SimpleW");
var server = new SimpleWServer(IPAddress.Any, 2015);
server.AddDynamicContent("/api");
server.Start();
Console.WriteLine("server started at http://localhost:2015/");
Console.ReadKey();
}
static TracerProvider openTelemetryObserver(string source) {
return Sdk.CreateTracerProviderBuilder()
.AddSource(source)
.AddProcessor(new LogProcessor()) // custom log processor
.SetResourceBuilder(
ResourceBuilder
.CreateEmpty()
.AddService(serviceName: "Sample", serviceVersion: "0.1")
).Build();
}
// custom log processor for opentelemetry
class LogProcessor : BaseProcessor<Activity> {
// write log to console
public override void OnEnd(Activity activity) {
// WARNING : use for local debug only not production
Console.WriteLine($"{activity.GetTagItem("http.request.method")} \"{activity.GetTagItem("url.full")}\" {activity.GetTagItem("http.response.status_code")} {(int)activity.Duration.TotalMilliseconds}ms session-{activity.GetTagItem("session")} {activity.GetTagItem("client.address")} \"{activity.GetTagItem("user_agent.original")}\"");
}
}
}
public class SomeController : Controller {
[Route("GET", "/test")]
public object SomePublicMethod() {
return new {
message = "Hello World !"
};
}
}
}
Open browser to http://localhost:2015/api/test and console will show log.
Traces
For production, logs alone aren't enougth - we need a full trace for every Event
. The most reliable approach is to leverage battle-tested solutions for collecting and managing telemetry data.
The team behind Uptrace has built an impressive open-source, self-hosted observability platform. They offer a helper extension for the .NET OpenTelemetry exporter as a NuGet package, making it effortless to integrate end-to-end tracing into your .NET services.
So add their package
$ dotnet add package Uptrace.OpenTelemetry
And see the following example, especially the openTelemetryObserver()
using System;
using System.Net;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using OpenTelemetry;
using OpenTelemetry.Trace;
using Uptrace.OpenTelemetry;
using SimpleW;
namespace Sample {
class Program {
static void Main() {
// subscribe to all SimpleW events
openTelemetryObserver("SimpleW");
var server = new SimpleWServer(IPAddress.Any, 2015);
server.AddDynamicContent("/api");
server.Start();
Console.WriteLine("server started at http://localhost:2015/");
Console.ReadKey();
}
static TracerProvider openTelemetryObserver(string source) {
return Sdk.CreateTracerProviderBuilder()
.AddSource(source)
// see https://uptrace.dev/get/get-started.html#dsn
.AddUptrace("uptrace_connection_string_api_key")
.SetResourceBuilder(
ResourceBuilder
.CreateEmpty()
.AddService(serviceName: "Sample", serviceVersion: "0.1")
).Build();
}
}
public class SomeController : Controller {
[Route("GET", "/test")]
public object SomePublicMethod() {
return new {
message = "Hello World !"
};
}
}
}
A screenshot of Uptrace Traces & Logs
SimpleW export many informations (Request, Response, Exception...) and you can view hit, monitor response time or error and searching specific data.