Skip to content

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 with openTelemetryObserver()
  • log each request to console with LogProcessor (do not use for production).
csharp
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

sh
$ dotnet add package Uptrace.OpenTelemetry

And see the following example, especially the openTelemetryObserver()

csharp
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.

uptrace tracing

Released under the MIT License.