Skip to content

Registration

Register Wolverine.CritterWatch inside your UseWolverine() configuration block. The call must come after transport configuration so the observer can use the transport to publish telemetry.

Simple Registration

The shortest form takes a transport URI and service name:

csharp
builder.Host.UseWolverine(opts =>
{
    opts.UseRabbitMq(new Uri("amqp://localhost")).AutoProvision();

    opts.AddCritterWatchMonitoring("amqp://localhost", "my-service");
});

Full Options

cs
builder.Host.UseWolverine(opts =>
{
    opts.AddCritterWatchMonitoring(
        // URI of the queue CritterWatch listens on for telemetry
        critterWatchUri: new Uri("rabbitmq://critterwatch"),

        // URI of the queue this service listens on for incoming commands
        systemControlUri: new Uri("rabbitmq://trip-service-control"),

        // How this service exports metrics (default: Hybrid)
        metricsMode: WolverineMetricsMode.Hybrid
    );
});

Declared Baselines

configureBaselines is an optional callback used to seed CritterWatch's metrics-based alert thresholds at the moment your service first connects. It exists because CritterWatch's "this service is suddenly running 10x above normal" alerts need something to compare against — and a brand-new service has no history yet.

csharp
configureBaselines: baselines => baselines
    // Service-wide defaults (apply to any message type that doesn't have
    // its own declaration).
    .ForService(throughputPerHour: 200, avgExecTimeMs: 25)

    // Per-message-type override.
    .For<TripBooked>(throughputPerHour: 50, avgExecTimeMs: 40)
;

Either argument can be omitted (null) when only one of the two figures is known. The values:

  • are forwarded to CritterWatch on first contact (alongside ServiceCapabilities);
  • are written into the service's alert-overrides record on the CritterWatch side and emitted as ThroughputBaselineChanged / ExecTimeBaselineChanged events with Source = ServiceCapabilities;
  • become the declared branch of the baseline cascade. They yield to observed history once enough samples accumulate, and are themselves editable through the CritterWatch UI (the UI-edited value is identified with Source = Operator so audit history makes the provenance clear).

See Alerts › Editing Thresholds for the full cascade and editing model.

What the call wires up

A single AddCritterWatchMonitoring(...) call wires up:

  1. The runtime hook that observes Wolverine state changes and publishes telemetry once per second.
  2. Handlers for every inbound command the console can send — DLQ replay/discard, listener pause/drain/restart, projection lifecycle, tenant management, and the rest. See Inbound Commands.
  3. Transport routing — the queue this service listens on for commands, and the queue it publishes telemetry to.

What you don't need to add

  • No changes to your handlers, aggregates, or domain code.
  • No changes to your database schema.
  • No additional database connections.
  • No additional processes.

The integration uses the Wolverine transport you already have.

Multiple Services

Each service must have a unique ServiceName. CritterWatch uses this as the primary key for all service data. Two services with the same name will appear as a single entry in CritterWatch, with state from both processes intermixed.

csharp
// TripService/Program.cs
opts.AddCritterWatchMonitoring("amqp://localhost", "trip-service");

// RepairShop/Program.cs
opts.AddCritterWatchMonitoring("amqp://localhost", "repair-shop");

Non-RabbitMQ Transports

The first argument to AddCritterWatchMonitoring() is used to configure the publishing destination. For non-RabbitMQ transports, use the full options form and configure accordingly.

TIP

RabbitMQ is strongly recommended for production use because it provides reliable message delivery between services and CritterWatch. In-memory transport is suitable for development but does not persist messages if either process restarts.

Released under the MIT License.