70 lines
2.7 KiB
TypeScript
70 lines
2.7 KiB
TypeScript
import { type Counter, type Histogram, metrics } from "@opentelemetry/api";
|
|
|
|
/**
|
|
* Bundle of OpenTelemetry instruments emitted by the export plugin.
|
|
*
|
|
* - `jobsTotal` — incremented once per job outcome, labelled
|
|
* `{ outcome: "completed" | "failed" }`.
|
|
* - `rowsTotal` — total rows emitted across successful jobs.
|
|
* - `bytesTotal` — total bytes emitted across successful jobs.
|
|
* - `durationMs` — histogram of wall-clock duration of a single
|
|
* export, in milliseconds.
|
|
* - `downloadServed` — incremented once per successful download
|
|
* response, labelled `{ format: "csv" | "json" | "xlsx" }`.
|
|
* - `downloadFailed` — incremented once per failed download
|
|
* response, labelled `{ reason: "not-found" | "not-ready" |
|
|
* "provider-not-found" | "failed" }`.
|
|
*/
|
|
export interface ExportInstruments {
|
|
readonly jobsTotal: Counter;
|
|
readonly rowsTotal: Counter;
|
|
readonly bytesTotal: Counter;
|
|
readonly durationMs: Histogram;
|
|
readonly downloadServed: Counter;
|
|
readonly downloadFailed: Counter;
|
|
}
|
|
|
|
let cached: ExportInstruments | undefined;
|
|
|
|
/**
|
|
* Lazily build (and cache) the export instruments bundle against the
|
|
* current global `MeterProvider`. Tests call {@link resetExportInstruments}
|
|
* in setup to force a re-bind against a freshly-installed provider.
|
|
*/
|
|
export function getExportInstruments(): ExportInstruments {
|
|
if (cached !== undefined) return cached;
|
|
const meter = metrics.getMeter("@suaveplan/api-plugin-export");
|
|
cached = {
|
|
jobsTotal: meter.createCounter("export.jobs_total", {
|
|
description: "Total export jobs by outcome.",
|
|
}),
|
|
rowsTotal: meter.createCounter("export.rows_total", {
|
|
description: "Total rows successfully exported.",
|
|
}),
|
|
bytesTotal: meter.createCounter("export.bytes_total", {
|
|
description: "Total bytes successfully exported.",
|
|
}),
|
|
durationMs: meter.createHistogram("export.duration_ms", {
|
|
description: "Wall-clock duration of a single export, in ms.",
|
|
unit: "ms",
|
|
}),
|
|
downloadServed: meter.createCounter("export.download.served", {
|
|
description: "Total download responses served by format.",
|
|
}),
|
|
downloadFailed: meter.createCounter("export.download.failed", {
|
|
description: "Total download responses that failed by reason.",
|
|
}),
|
|
};
|
|
return cached;
|
|
}
|
|
|
|
/**
|
|
* Drop the cached instrument bundle so the next
|
|
* {@link getExportInstruments} call rebinds against the global
|
|
* `MeterProvider` in effect at that point. Tests call this after
|
|
* installing a fresh `MeterProvider`.
|
|
*/
|
|
export function resetExportInstruments(): void {
|
|
cached = undefined;
|
|
}
|