diff --git a/src/metrics.ts b/src/metrics.ts index cb329662..28b12f27 100644 --- a/src/metrics.ts +++ b/src/metrics.ts @@ -19,58 +19,45 @@ export enum MessageSource { publish = 'publish' } -type LabelsGeneric = Record +type NoLabels = Record +type LabelsGeneric = Record +type LabelKeys = Extract interface CollectFn { (metric: Gauge): void } -export interface Gauge { - // Sorry for this mess, `prom-client` API choices are not great - // If the function signature was `inc(value: number, labels?: Labels)`, this would be simpler - inc(value?: number): void - inc(labels: Labels, value?: number): void - inc(arg1?: Labels | number, arg2?: number): void - - set(value: number): void - set(labels: Labels, value: number): void - set(arg1?: Labels | number, arg2?: number): void +export interface Gauge { + inc: NoLabels extends Labels ? (value?: number) => void : (labels: Labels, value?: number) => void + set: NoLabels extends Labels ? (value: number) => void : (labels: Labels, value: number) => void addCollect(collectFn: CollectFn): void } -export interface Histogram { +export interface Histogram { startTimer(): () => void - observe(value: number): void - observe(labels: Labels, values: number): void - observe(arg1: Labels | number, arg2?: number): void + observe: NoLabels extends Labels ? (value: number) => void : (labels: Labels, value: number) => void reset(): void } -export interface AvgMinMax { - set(values: number[]): void - set(labels: Labels, values: number[]): void - set(arg1?: Labels | number[], arg2?: number[]): void +export interface AvgMinMax { + set: NoLabels extends Labels ? (values: number[]) => void : (labels: Labels, values: number[]) => void } -export interface GaugeConfig { +export type GaugeConfig = { name: string help: string - labelNames?: keyof Labels extends string ? Array : undefined -} +} & (NoLabels extends Labels ? { labelNames?: never } : { labelNames: [LabelKeys, ...Array>] }) -export interface HistogramConfig { - name: string - help: string - labelNames?: Array +export type HistogramConfig = GaugeConfig & { buckets?: number[] } export type AvgMinMaxConfig = GaugeConfig export interface MetricsRegister { - gauge(config: GaugeConfig): Gauge - histogram(config: HistogramConfig): Histogram - avgMinMax(config: AvgMinMaxConfig): AvgMinMax + gauge(config: GaugeConfig): Gauge + histogram(config: HistogramConfig): Histogram + avgMinMax(config: AvgMinMaxConfig): AvgMinMax } export enum InclusionReason { @@ -328,10 +315,9 @@ export function getMetrics ( labelNames: ['hit'] }), - asyncValidationDelayFromFirstSeenSec: register.histogram<{ topic: TopicLabel }>({ + asyncValidationDelayFromFirstSeenSec: register.histogram({ name: 'gossipsub_async_validation_delay_from_first_seen', help: 'Async validation report delay from first seen in second', - labelNames: ['topic'], buckets: [0.01, 0.03, 0.1, 0.3, 1, 3, 10] }), @@ -482,7 +468,7 @@ export function getMetrics ( labelNames: ['topic'] }), /** Track duplicate message delivery time */ - duplicateMsgDeliveryDelay: register.histogram({ + duplicateMsgDeliveryDelay: register.histogram<{ topic: TopicLabel }>({ name: 'gossisub_duplicate_msg_delivery_delay_seconds', help: 'Time since the 1st duplicated message validated', labelNames: ['topic'], @@ -883,9 +869,9 @@ export function getMetrics ( }, onDuplicateMsgDelivery (topicStr: TopicStr, deliveryDelayMs: number, isLateDelivery: boolean): void { - this.duplicateMsgDeliveryDelay.observe(deliveryDelayMs / 1000) + const topic = this.toTopic(topicStr) + this.duplicateMsgDeliveryDelay.observe({ topic }, deliveryDelayMs / 1000) if (isLateDelivery) { - const topic = this.toTopic(topicStr) this.duplicateMsgLateDelivery.inc({ topic }, 1) } },