Skip to content

Settings

The Settings page (/settings) is the control surface for everything that's about CritterWatch itself rather than about a specific monitored service — refresh cadence, theme, notification channels, trace providers, license, connection behaviour, retention.

The page is laid out as a vertical stack of cards. Each card owns one setting area and has its own Save semantics; nothing on this page mutates a monitored service.

Auto-Refresh Intervals
Theme
Notification Channels
Trace Providers
Metrics Data Sources
License Info
Connection Settings
Data Retention

Auto-Refresh Intervals

The polling cadence for views that aren't covered by SignalR push (the Settings page itself, license info, audit log when auto-refresh is on, etc.).

FieldOptions
Global Default Interval5s · 10s · 30s · 60s

The dashboard, services list, projections, listeners, durability, DLQ, and alerts pages do not poll — they live-update via SignalR. The interval here applies only to fallback polling.


Theme

FieldEffect
Dark ModeToggle between light + dark themes. Persists in localStorage.

The toggle drives the global theme provider. All Element Plus components, the DDL syntax-highlighting (highlight.js), and the mermaid diagrams in the docs pick up the theme automatically.


Notification Channels

External delivery destinations for alerts. Each channel has a name, a type, a webhook URL, an enabled flag, and an alert-severity allowlist (which severities should fan out to this channel).

Channel types

TypeDelivery
SlackSlack Incoming Webhook URL
DiscordDiscord Webhook URL
MS TeamsMicrosoft Teams Incoming Webhook URL

Email, PagerDuty, and generic webhook channels are planned but not currently implemented.

Per-channel actions

ActionEffect
TestSends a synthetic alert through the channel. Result (Sent / error) appears below the row.
EditOpens the channel form for editing
DeleteRemoves the channel (no confirmation popconfirm — the side effect is recoverable)
Add Channel (header)Opens the channel form for a new channel

The channel form takes the name, type, webhook URL (rendered as a password field — webhook URLs are secrets), enabled toggle, and a checkbox group of alert severities (critical / warning / info). Only severities in the allowlist trigger a delivery.


Trace Providers

External OpenTelemetry trace stores that CritterWatch queries when surfacing trace data on per-instance saga replay, handler-source-code views, and the Topology page. Nothing is stored locally — every render fetches.

Provider types

TypeStatus
JaegerAvailable now
DatadogAvailable now
AppInsightsPlanned

Multiple instances of the same type are supported (e.g. one Jaeger for dev, one for prod). Each provider has a stable runtime id used as the foreign key for per-service bindings.

How the catalog gets populated

Providers are declared at host startup through DI, not from the UI. The Settings page surfaces what's wired up; it cannot add or edit a provider on its own.

csharp
services.AddCritterWatchTraceProvider<JaegerTraceProvider, JaegerTraceProviderOptions>(
    "jaeger-dev",
    opts => opts.BaseUrl = "http://localhost:16686");

services.AddCritterWatchTraceProvider<DataDogTraceProvider, DataDogTraceProviderOptions>(
    "datadog",
    opts =>
    {
        opts.ApiKey = builder.Configuration["Datadog:ApiKey"]!;
        opts.AppKey = builder.Configuration["Datadog:AppKey"]!;
        opts.Site = "us1";
    });

services.SetDefaultCritterWatchTraceProvider("jaeger-dev");

This pattern moves endpoint URLs + credentials into strongly-typed options classes that bind from configuration / secret stores — the operator UI never sees the secrets. To add or remove a provider, edit the host startup and redeploy; the Settings page picks up the change on next load.

Registered providers (read-only)

ColumnMeaning
IdStable runtime id (e.g. jaeger-dev)
TypeProvider type (Jaeger, Datadog, …)
Default"default" tag if this provider serves services without an explicit binding
StatusOne-shot reachability probe — Reachable, Unreachable, Not yet tested

The Test button per row hits POST /providers/{id}/health and updates the status in place.

Per-service bindings

The bindings table below the catalog is the routing layer — one row per monitored service that has either pushed a preferred provider (via the Wolverine.CritterWatch push API on the service side) or been overridden by the operator from this page.

ColumnMeaning
ServiceService id (matches what shows up on the Services page)
PushedThe provider id the service declared in its CritterWatch wire-up; if the service has never declared one
ActiveDropdown of registered providers — what CritterWatch actually uses for this service
StatusSingle chip rolling up the four cases below
Actions"Use pushed value" button — only visible when the row is overridden

Status chips

ChipColourWhen
Matches requestgreenActive provider == pushed provider; the operator has not overridden
Overridden by operatoramberActive provider ≠ pushed provider; tooltip shows both ids
Provider not registeredredActive provider id is not in the DI catalog; either the service is asking for a provider that nobody registered, or the operator picked one then removed the registration
No bindinggreyNo provider id on the row (rare — only happens on bindings whose id was blanked out manually)

Operator override flow

To route a service's traces to a different provider than the one it declared:

  1. Pick the new provider from the Active dropdown — PUT /bindings/{serviceId} fires immediately, no save button.
  2. The chip flips to amber "Overridden by operator". The dropdown stays editable so further changes overwrite the active value.
  3. To clear the override, click Use pushed valueDELETE /bindings/{serviceId} resets Active = Pushed. If the service has never pushed (row was operator-only), the entire row disappears.

The service-side push value is preserved across operator edits, so a service redeploying and re-declaring its preferred provider does not clobber the operator's pick.

The same Active dropdown is available on each service's Overview tab (Services → pick service → Overview → Trace provider). The Settings page is the cross-service view; the per-service tab is the single-service view. Either one writes to the same backend.


Metrics Data Sources

Metrics-data-source bindings mirror the trace-provider section: the catalog is declarative at host startup, and the Settings page surfaces a read-only listing plus a mutable per-service routing table.

Source types

TypeStatus
PostgreSQLBuilt-in (always available)
PrometheusAvailable now
VictoriaMetricsAvailable now
DatadogAvailable now

The PostgreSQL source is registered automatically by AddCritterWatchServices — services with no binding and no operator-declared default land on it. Additional sources are declared in host startup the same way trace providers are:

csharp
services.AddCritterWatchMetricsDataSource<PrometheusMetricsDataSource, PrometheusMetricsDataSourceOptions>(
    "prometheus",
    opts => opts.BaseUrl = "http://prometheus:9090");

services.SetDefaultCritterWatchMetricsDataSource("prometheus");

Registered data sources (read-only)

ColumnMeaning
IdStable runtime id
TypeSource type discriminator
Default"default" tag if this source serves services without an explicit binding

Per-service bindings

Same shape as the trace bindings table:

ColumnMeaning
ServiceService id
PushedThe data-source id the service declared, or
ActiveDropdown of registered data sources
StatusOne of the four chips (same semantics as trace bindings: match / overridden / not registered / no binding)
Actions"Use pushed value" reset, visible on overrides only

Status chip rules and operator override flow are identical to trace providers — see above. The wire endpoints are GET/PUT/DELETE /api/critterwatch/metrics/data-source-bindings/{serviceId}.


License Info

Read-only. Pulled from GET /api/critterwatch/license.

FieldMeaning
TierOpen · Professional · Enterprise — colour-coded
OrganizationLicense-bearing organization
ExpiresExpiry date; "EXPIRED" tag in red if past due
Max ServicesCap on monitored services; "Unlimited" if effectively uncapped

Below the descriptions block, a Feature Availability table lists every gated feature with a Yes / No tag derived from the license tier. The table reflects exactly what the running BFF will let you do.

If license info is unavailable (no license endpoint, network error), the card renders an empty state.


Connection Settings

Tunables for the SignalR connection between the BFF and the monitored services.

FieldRangeDefault
Reconnection Interval (s)1–605
Connection Timeout (s)5–12030
Auto-Reconnecttoggleon

Lower reconnection intervals make CritterWatch recover faster from blips at the cost of more reconnect chatter; the defaults are fine for most deploys.

There is also a global "Operations Enabled" flag (set elsewhere in deploy config or via Aspire host) that switches CritterWatch into a read-only mode. When disabled, every action button on a service detail page renders disabled with a hover tooltip explaining why. This is the recommended way to lock the production console down during a freeze.


Data Retention

How long CritterWatch keeps its own bookkeeping data. These settings drive the per-document-store retention policies on CritterWatch's Marten store.

FieldRangeDefault
Timeline Entry Retention (days)1–36530
Audit Log Retention (days)1–36530
Metrics Bucket Retention (count)100–10000 (step 100)1000

Timeline + audit log retention are absolute (days). Metrics bucket retention is a count of buckets per service per message-type — tune up if you need longer-history charts on the Metrics tab; tune down if your CritterWatch database is ballooning.

Save semantics: each card has its own implicit save (the values are watched in the settings store and persisted on change). Changes here don't write directly to the monitored services — these are CritterWatch-side knobs only.


Roadmap

Currently planned settings additions:

  • OAuth / SSO — single-sign-on for the CritterWatch console
  • Per-environment colour-banding — visual differentiation between dev / staging / prod CritterWatch instances
  • Webhook channel — generic webhook delivery for alerts
  • Backup + restore — export/import of CritterWatch's own configuration (thresholds, channels, providers) for environment promotion

Released under the MIT License.