Browse the documentation

Diagnostics

Diagnostic codes, query explanation, safety limits and the audit trail.

Diagnosable from outside the process

Every correctness-critical state is visible from outside the process, and no diagnostic surface carries a document value, a credential or key material. The second property is checked by a test harness that seeds sentinel values and asserts that none of them appear in any diagnostic output.

Diagnostic codes

Every classified outcome has a stable code carrying its meaning and the operator action. Codes are grouped by area: NDB-LIFE (lifecycle), NDB-WAL, NDB-REC (recovery), NDB-SNAP, NDB-IDX, NDB-REPL, NDB-STOR, NDB-STAT and NDB-OBS.

The catalogue is an append-only published contract: once released, a code's meaning never changes, because alert rules and runbooks are keyed on it. The same holds for metric names, units and labels; see Health & metrics.

Explaining a query

var collection = host.Services.GetRequiredService<IDocumentCollection<Order>>();

var result = await collection.WhereAsync("Country == \"BE\" && Total >= 500");

var explanation = result.Explanation;
// Which index answered it, which indexes were refused and why,
// whether it fell back to a scan, whether any part ran approximately.
// Index names and plan shape only - never a literal or a document value.

// Over REST:
// POST /Collections/Order/explain   body: "Country == \"BE\" && Total >= 500"

Query safety limits

QueryBounds limits parser depth, token count, path depth, literal length, in-list size and result-set size. The recent-query history keeps query shapes, not literal values, unless you opt in.

builder.Services.AddNetlyDB(o =>
{
    o.QueryBounds = o.QueryBounds with { MaxInListSize = 1_000, MaxResultSetSize = 50_000 };

    // Recent-query history keeps query shapes, not literals, unless you opt in.
    o.QueryHistoryRetention = QueryHistoryRetention.ShapeOnly;
});

Audit trail

Destructive operations are recorded in an append-only, checksum-chained audit log kept separately from the diagnostic log. The current release records WAL torn-tail repair, collection deletion, collection truncation and index drop.

From code

MemberPurpose
GetMutationStatusAsync(Guid)What happened to one write, by mutation id, including after a restart. On IDocumentCollection<T> and IFileCollection.
QueryResult.ExplanationHow a query was answered: the index used, indexes refused and why, scan fallback, approximate execution.
GetIndexDefinitions / IndexInfoEach index's kind, lifecycle state, generation, definition version and property paths.
NodeReplicationStatusQueue depth, active peers, retrying work, bootstraps in progress, negotiated guarantees, last error.
RecoveryReport / SnapshotReportWhat the last recovery concluded, and what each snapshot attempt published.

In the Management UI Enterprise

The Diagnostics page shows engine state and degradation scope, recovery and snapshot reports, and mutation lookup by id; Indexes shows each index's lifecycle state and degradation reason; Nodes shows peer state and replication backlog. The UI offers no repair actions.

An unhandled error has occurred. Reload X

Reconnecting

Restoring the connection to the server...

Still trying

Next attempt in seconds

Connection lost

We could not reach the server.