Skip to documentation
Heimdall Docs
Heimdall Docs

Observability

Trace content actions and monitor Bifrost with Heimdall's built-in ActivitySource and System.Diagnostics.Metrics instruments.

The Server package emits diagnostics without requiring an exporter. Your application chooses OpenTelemetry, sampling, retention, and alerting.

1. Register the Source and Meter

Use the public constants so configuration, dashboards, and tests do not repeat framework string literals.

C#
using Heimdall.Server;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing => tracing
        .AddSource(HeimdallDiagnostics.ActivitySourceName))
    .WithMetrics(metrics => metrics
        .AddMeter(HeimdallDiagnostics.MeterName));

2. Activities

Content actions include the resolved action ID, status, outcome, exception type, or cancellation reason as appropriate. Bifrost exposes connection and publish activities.

Text
heimdall.content_action
heimdall.bifrost.connection
heimdall.bifrost.publish

// Public constants:
HeimdallDiagnostics.ContentActionActivityName
HeimdallDiagnostics.BifrostConnectionActivityName
HeimdallDiagnostics.BifrostPublishActivityName

3. Content-Action Metrics

The action pipeline records volume, latency, sizes, failures, and cancellation independently so expected replacement cancellation does not look like an application exception.

Text
heimdall.server.content_action.requests
heimdall.server.content_action.duration
heimdall.server.content_action.request.body.size
heimdall.server.content_action.response.body.size
heimdall.server.content_action.exceptions
heimdall.server.content_action.cancellations

4. Bifrost Metrics

Connection and subscriber gauges show current load. Message counters distinguish publication, delivery, expiry, and drops so slow subscribers or undersized buffers are visible.

Text
heimdall.server.bifrost.connections.active
heimdall.server.bifrost.subscribers.active
heimdall.server.bifrost.messages.published
heimdall.server.bifrost.messages.delivered
heimdall.server.bifrost.messages.expired
heimdall.server.bifrost.messages.dropped

5. Tags and Cardinality

Stable dimensions include action ID, outcome, status, error type, cancellation reason, Bifrost event name, and drop reason. Action IDs and event names should come from bounded application-defined sets.

Text
Intentionally excluded:
- action payloads
- user identities
- Bifrost topic names
- selectors and request URLs

Do not add sensitive or unbounded values back as tags.

6. Read Outcomes Correctly

Timeout, replacement, external cancellation, and errors are different operational signals. A Bifrost no-subscribers outcome can be normal for best-effort live UI. Aggregate active counts across instances in the telemetry backend when the service is scaled out.

Text
Suggested dashboards:
- action rate, p50/p95/p99 duration, and error ratio
- cancellations by reason
- request/response size distributions
- active Bifrost connections and subscribers
- published vs delivered vs expired/dropped messages

7. HasSubscribers Is Not Telemetry

Bifrost.HasSubscribers(topic) is an instantaneous local-instance hint for skipping optional expensive work. It is not a delivery guarantee, a distributed presence query, or a substitute for metrics.

Text
if (bifrost.HasSubscribers("orders"))
{
    var html = await RenderExpensiveOrderUpdate(ct);
    await bifrost.PublishAsync("orders", html,
        TimeSpan.FromSeconds(5), ct);
}