Initial Commit
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import { type Counter, type Histogram, metrics } from "@opentelemetry/api";
|
||||
|
||||
/** Low-cardinality `mode` enum for the histograms below. */
|
||||
export type GenerateMode = "random" | "pronounceable" | "passphrase" | "pin";
|
||||
|
||||
let _generateDurationMs: Histogram | undefined;
|
||||
let _entropyBits: Histogram | undefined;
|
||||
let _errorsTotal: Counter | undefined;
|
||||
|
||||
function getInstruments(): {
|
||||
generateDurationMs: Histogram;
|
||||
entropyBits: Histogram;
|
||||
errorsTotal: Counter;
|
||||
} {
|
||||
const meter = metrics.getMeter("@suaveplan/password-generator");
|
||||
_generateDurationMs ??= meter.createHistogram(
|
||||
"pwgen.generate_duration_ms",
|
||||
{
|
||||
description:
|
||||
"Wall-clock duration of a single successful password / passphrase / PIN generation",
|
||||
unit: "ms",
|
||||
}
|
||||
);
|
||||
_entropyBits ??= meter.createHistogram("pwgen.entropy_bits", {
|
||||
description: "Estimated entropy of the generated secret",
|
||||
unit: "bit",
|
||||
});
|
||||
_errorsTotal ??= meter.createCounter("pwgen.errors_total", {
|
||||
description:
|
||||
"Count of typed errors thrown from @suaveplan/password-generator",
|
||||
});
|
||||
return {
|
||||
generateDurationMs: _generateDurationMs,
|
||||
entropyBits: _entropyBits,
|
||||
errorsTotal: _errorsTotal,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Record a successful generation. Threading every production path through
|
||||
* a single helper keeps the attribute key set ("mode") consistent and the
|
||||
* cardinality bounded.
|
||||
*/
|
||||
export function recordGeneration(
|
||||
mode: GenerateMode,
|
||||
durationMs: number,
|
||||
bits: number
|
||||
): void {
|
||||
const { generateDurationMs, entropyBits } = getInstruments();
|
||||
generateDurationMs.record(durationMs, { mode });
|
||||
entropyBits.record(bits, { mode });
|
||||
}
|
||||
|
||||
/** Record a typed error by stable code. */
|
||||
export function recordError(code: string): void {
|
||||
const { errorsTotal } = getInstruments();
|
||||
errorsTotal.add(1, { code });
|
||||
}
|
||||
|
||||
/** Reset the cached instruments (test-only). */
|
||||
export function _resetInstruments(): void {
|
||||
_generateDurationMs = undefined;
|
||||
_entropyBits = undefined;
|
||||
_errorsTotal = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public-facing accessors so callers (and tests) can inspect the
|
||||
* underlying instruments. Lazy-evaluated so the active MeterProvider is
|
||||
* always honoured.
|
||||
*/
|
||||
export const generateDurationMs = {
|
||||
record(value: number, attrs: { mode: GenerateMode }): void {
|
||||
getInstruments().generateDurationMs.record(value, attrs);
|
||||
},
|
||||
};
|
||||
|
||||
export const entropyBits = {
|
||||
record(value: number, attrs: { mode: GenerateMode }): void {
|
||||
getInstruments().entropyBits.record(value, attrs);
|
||||
},
|
||||
};
|
||||
|
||||
export const errorsTotal = {
|
||||
add(value: number, attrs: { code: string }): void {
|
||||
getInstruments().errorsTotal.add(value, attrs);
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user