Initial Commit
This commit is contained in:
82
packages/api/api-plugin-banking/src/otel/instruments.ts
Normal file
82
packages/api/api-plugin-banking/src/otel/instruments.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { type Counter, type Histogram, metrics } from "@opentelemetry/api";
|
||||
|
||||
/**
|
||||
* Bundle of OpenTelemetry instruments emitted by the banking plugin.
|
||||
*
|
||||
* - `banksTotal{op}` — bank lifecycle transitions. `op ∈
|
||||
* "create" | "soft-delete" | "update"`.
|
||||
* - `accountsTotal{op}` — account lifecycle transitions. `op ∈
|
||||
* "create" | "delete" | "update" | "status-change"`.
|
||||
* - `transfersTotal{outcome}` — `transferFunds` call counter.
|
||||
* `outcome ∈ "success" | "insufficient_funds" | "error"`.
|
||||
* - `transferAmount` — histogram of transfer amounts (units: currency
|
||||
* minor units, treated as a unitless float for genericity).
|
||||
* - `fundOperationsTotal{op,outcome}` — `addFunds` / `subtractFunds`.
|
||||
* `op ∈ "add" | "subtract"`, `outcome ∈ "success" | "error" |
|
||||
* "insufficient_funds"`.
|
||||
* - `queryDurationMs{op}` — histogram of repository query wall-clock
|
||||
* duration in ms, partitioned by op (`"bank.list"`, `"account.list"`,
|
||||
* `"transfer"`, etc.).
|
||||
*/
|
||||
export interface BankingInstruments {
|
||||
readonly banksTotal: Counter;
|
||||
readonly accountsTotal: Counter;
|
||||
readonly transfersTotal: Counter;
|
||||
readonly transferAmount: Histogram;
|
||||
readonly fundOperationsTotal: Counter;
|
||||
readonly queryDurationMs: Histogram;
|
||||
}
|
||||
|
||||
let cached: BankingInstruments | undefined;
|
||||
|
||||
/**
|
||||
* Lazily build (and cache) the banking instruments bundle against the
|
||||
* current global `MeterProvider`. Call {@link resetBankingInstruments}
|
||||
* in test setup to force a re-bind against a freshly-installed
|
||||
* provider.
|
||||
*/
|
||||
export function getBankingInstruments(): BankingInstruments {
|
||||
if (cached !== undefined) return cached;
|
||||
const meter = metrics.getMeter("@suaveplan/api-plugin-banking");
|
||||
cached = {
|
||||
banksTotal: meter.createCounter("banking.banks_total", {
|
||||
description:
|
||||
"Total bank lifecycle transitions, partitioned by op label",
|
||||
}),
|
||||
accountsTotal: meter.createCounter("banking.accounts_total", {
|
||||
description:
|
||||
"Total bank-account lifecycle transitions, partitioned by op label",
|
||||
}),
|
||||
transfersTotal: meter.createCounter("banking.transfers_total", {
|
||||
description:
|
||||
"Total transferFunds() calls, partitioned by outcome label",
|
||||
}),
|
||||
transferAmount: meter.createHistogram("banking.transfer_amount", {
|
||||
description:
|
||||
"Histogram of transfer amounts (unitless float; treat as minor currency units)",
|
||||
}),
|
||||
fundOperationsTotal: meter.createCounter(
|
||||
"banking.fund_operations_total",
|
||||
{
|
||||
description:
|
||||
"Total addFunds/subtractFunds calls, partitioned by op + outcome",
|
||||
}
|
||||
),
|
||||
queryDurationMs: meter.createHistogram("banking.query_duration_ms", {
|
||||
description:
|
||||
"Wall-clock duration of banking repository queries in ms",
|
||||
unit: "ms",
|
||||
}),
|
||||
};
|
||||
return cached;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop the cached instrument bundle so the next
|
||||
* {@link getBankingInstruments} call rebinds against the global
|
||||
* `MeterProvider` in effect at that point. Tests call this after
|
||||
* installing a fresh `MeterProvider`.
|
||||
*/
|
||||
export function resetBankingInstruments(): void {
|
||||
cached = undefined;
|
||||
}
|
||||
Reference in New Issue
Block a user