@libp2p/interface
Version:
The interface implemented by a libp2p node
549 lines (491 loc) • 15.7 kB
text/typescript
import type { MultiaddrConnection, Stream } from './index.js'
/**
* Create tracked metrics with these options. Loosely based on the
* interfaces exposed by the prom-client module
*/
export interface MetricOptions {
/**
* Optional label for the metric
*/
label?: string
/**
* Optional help for the metric
*/
help?: string
}
/**
* A function that returns a tracked metric which may be expensive
* to calculate so it is only invoked when metrics are being scraped
*/
export type CalculateMetric<T = number> = (() => T) | (() => Promise<T>)
/**
* Create tracked metrics that are expensive to calculate by passing
* a function that is only invoked when metrics are being scraped
*/
export interface CalculatedMetricOptions<T = number> extends MetricOptions {
/**
* An optional function invoked to calculate the component metric instead of
* using `.update`, `.increment`, and `.decrement`
*/
calculate: CalculateMetric<T>
}
/**
* Call this function to stop the timer returned from the `.timer` method
* on the metric
*/
export interface StopTimer { (): void }
/**
* A tracked metric loosely based on the interfaces exposed by the
* prom-client module
*/
export interface Metric {
/**
* Update the stored metric to the passed value
*/
update(value: number): void
/**
* Increment the metric by the passed value or 1
*/
increment(value?: number): void
/**
* Decrement the metric by the passed value or 1
*/
decrement(value?: number): void
/**
* Reset this metric to its default value
*/
reset(): void
/**
* Start a timed metric, call the returned function to
* stop the timer
*/
timer(): StopTimer
}
/**
* A group of related metrics loosely based on the interfaces exposed by the
* prom-client module
*/
export interface MetricGroup<T extends string = any> {
/**
* Update the stored metric group to the passed value
*/
update(values: Partial<Record<T, number>>): void
/**
* Increment the metric group keys by the passed number or
* `true` to increment by 1
*/
increment(values: Partial<Record<T, number | true>>): void
/**
* Decrement the metric group keys by the passed number or
* `true` to decrement by 1
*/
decrement(values: Partial<Record<T, number | true>>): void
/**
* Reset the passed key in this metric group to its default value
* or all keys if no key is passed
*/
reset(): void
/**
* Start a timed metric for the named key in the group, call
* the returned function to stop the timer
*/
timer(key: string): StopTimer
}
/**
* A tracked counter loosely based on the Counter interface exposed
* by the prom-client module - counters are metrics that only go up
*/
export interface Counter {
/**
* Increment the metric by the passed value or 1
*/
increment(value?: number): void
/**
* Reset this metric to its default value
*/
reset(): void
}
/**
* A group of tracked counters loosely based on the Counter interface
* exposed by the prom-client module - counters are metrics that only
* go up
*/
export interface CounterGroup<T extends string = any> {
/**
* Increment the metric group keys by the passed number or
* any non-numeric value to increment by 1
*/
increment(values: Partial<Record<T, number | true>>): void
/**
* Reset the passed key in this metric group to its default value
* or all keys if no key is passed
*/
reset(): void
}
export interface HistogramOptions extends MetricOptions {
/**
* Buckets for the histogram
*/
buckets?: number[]
}
/**
* Create tracked metrics that are expensive to calculate by passing
* a function that is only invoked when metrics are being scraped
*/
export interface CalculatedHistogramOptions<T = number> extends HistogramOptions {
/**
* An optional function invoked to calculate the component metric instead of
* using `.observe`
*/
calculate: CalculateMetric<T>
}
export interface Histogram {
/**
* Observe the passed value
*/
observe(value: number): void
/**
* Reset this histogram to its default value
*/
reset(): void
/**
* Start a timed metric, call the returned function to
* stop the timer
*/
timer(): StopTimer
}
export interface HistogramGroup<T extends string = any> {
/**
* Observe the passed value for the named key in the group
*/
observe(values: Partial<Record<T, number>>): void
/**
* Reset the passed key in this histogram group to its default value
* or all keys if no key is passed
*/
reset(): void
/**
* Start a timed metric for the named key in the group, call
* the returned function to stop the timer
*/
timer(key: string): StopTimer
}
export interface SummaryOptions extends MetricOptions {
/**
* Percentiles for the summary
*/
percentiles?: number[]
/**
* Configure how old a bucket can be before it is reset for sliding window
*/
maxAgeSeconds?: number
/**
* Configure how many buckets in the sliding window
*/
ageBuckets?: number
/**
* Remove entries without any new values in the last `maxAgeSeconds`
*/
pruneAgedBuckets?: boolean
/**
* Control compression of data in t-digest
*/
compressCount?: number
}
/**
* Create tracked metrics that are expensive to calculate by passing
* a function that is only invoked when metrics are being scraped
*/
export interface CalculatedSummaryOptions<T = number> extends SummaryOptions {
/**
* An optional function invoked to calculate the component metric instead of
* using `.observe`
*/
calculate: CalculateMetric<T>
}
/**
* A tracked summary loosely based on the Summary interface exposed
* by the prom-client module
*/
export interface Summary {
/**
* Observe the passed value
*/
observe(value: number): void
/**
* Reset this summary to its default value
*/
reset(): void
/**
* Start a timed metric, call the returned function to
* stop the timer
*/
timer(): StopTimer
}
/**
* A group of tracked summaries loosely based on the Summary interface
* exposed by the prom-client module
*/
export interface SummaryGroup<T extends string = any> {
/**
* Observe the passed value for the named key in the group
*/
observe(values: Partial<Record<T, number>>): void
/**
* Reset the passed key in this summary group to its default value
* or all keys if no key is passed
*/
reset(): void
/**
* Start a timed metric for the named key in the group, call
* the returned function to stop the timer
*/
timer(key: string): StopTimer
}
/**
* The libp2p metrics tracking object. This interface is only concerned
* with the collection of metrics, please see the individual implementations
* for how to extract metrics for viewing.
*
* @example How to register a simple metric
*
* ```typescript
* import { Metrics, Metric } from '@libp2p/interface/metrics'
*
* interface MyServiceComponents {
* metrics: Metrics
* }
*
* class MyService {
* private readonly myMetric: Metric
*
* constructor (components: MyServiceComponents) {
* this.myMetric = components.metrics.registerMetric({
* name: 'my_metric',
* label: 'my_label',
* help: 'my help text'
* })
* }
*
* // later
* doSomething () {
* this.myMetric.update(1)
* }
* }
* ```
*
* @example How to register a dynamically calculated metric
*
* A metric that is expensive to calculate can be created by passing a `calculate` function that will only be invoked when metrics are being scraped:
*
* ```typescript
* import { Metrics, Metric } from '@libp2p/interface/metrics'
*
* interface MyServiceComponents {
* metrics: Metrics
* }
*
* class MyService {
* private readonly myMetric: Metric
*
* constructor (components: MyServiceComponents) {
* this.myMetric = components.metrics.registerMetric({
* name: 'my_metric',
* label: 'my_label',
* help: 'my help text',
* calculate: async () => {
* // do something expensive
* return 1
* }
* })
* }
* }
* ```
*
* @example How to register a group of metrics
*
* If several metrics should be grouped together (e.g. for graphing purposes) `registerMetricGroup` can be used instead:
*
* ```typescript
* import { Metrics, MetricGroup } from '@libp2p/interface/metrics'
*
* interface MyServiceComponents {
* metrics: Metrics
* }
*
* class MyService {
* private readonly myMetricGroup: MetricGroup
*
* constructor (components: MyServiceComponents) {
* this.myMetricGroup = components.metrics.registerMetricGroup({
* name: 'my_metric_group',
* label: 'my_label',
* help: 'my help text'
* })
* }
*
* // later
* doSomething () {
* this.myMetricGroup.increment({ my_label: 'my_value' })
* }
* }
* ```
*
* There are specific metric groups for tracking libp2p connections and streams:
*
* @example How to track multiaddr connections
*
* This is something only libp2p transports need to do.
*
* ```typescript
* import { Metrics } from '@libp2p/interface/metrics'
*
* interface MyServiceComponents {
* metrics: Metrics
* }
*
* class MyService {
* private readonly metrics: Metrics
*
* constructor (components: MyServiceComponents) {
* this.metrics = components.metrics
* }
*
* // later
* doSomething () {
* const connection = {} // create a connection
* this.metrics.trackMultiaddrConnection(connection)
* }
* }
* ```
*
* @example How to track protocol streams
*
* This is something only libp2p connections need to do.
*
* ```typescript
* import { Metrics } from '@libp2p/interface/metrics'
*
* interface MyServiceComponents {
* metrics: Metrics
* }
*
* class MyService {
* private readonly metrics: Metrics
*
* constructor (components: MyServiceComponents) {
* this.metrics = components.metrics
* }
*
* // later
* doSomething () {
* const stream = {} // create a stream
* this.metrics.trackProtocolStream(stream)
* }
* }
* ```
*/
export interface Metrics {
/**
* Track a newly opened multiaddr connection
*/
trackMultiaddrConnection(maConn: MultiaddrConnection): void
/**
* Track a newly opened protocol stream
*/
trackProtocolStream(stream: Stream): void
/**
* Register an arbitrary metric. Call this to set help/labels for metrics
* and update/increment/decrement/etc them by calling methods on the returned
* metric object
*/
registerMetric: ((name: string, options?: MetricOptions) => Metric) & ((name: string, options: CalculatedMetricOptions) => void)
/**
* Register a a group of related metrics. Call this to set help/labels for
* groups of related metrics that will be updated with by calling `.update`,
* `.increment` and/or `.decrement` methods on the returned metric group object
*/
registerMetricGroup: ((name: string, options?: MetricOptions) => MetricGroup) & ((name: string, options: CalculatedMetricOptions<Record<string, number>>) => void)
/**
* Register an arbitrary counter. Call this to set help/labels for counters
* and increment them by calling methods on the returned counter object
*/
registerCounter: ((name: string, options?: MetricOptions) => Counter) & ((name: string, options: CalculatedMetricOptions) => void)
/**
* Register a a group of related counters. Call this to set help/labels for
* groups of related counters that will be updated with by calling the `.increment`
* method on the returned counter group object
*/
registerCounterGroup: ((name: string, options?: MetricOptions) => CounterGroup) & ((name: string, options: CalculatedMetricOptions<Record<string, number>>) => void)
/**
* Register an arbitrary histogram. Call this to set help/labels for histograms
* and observe them by calling methods on the returned histogram object
*/
registerHistogram: ((name: string, options?: HistogramOptions) => Histogram) & ((name: string, options: CalculatedHistogramOptions) => void)
/**
* Register a a group of related histograms. Call this to set help/labels for
* groups of related histograms that will be updated with by calling the `.observe`
* method on the returned histogram group object
*/
registerHistogramGroup: ((name: string, options?: HistogramOptions) => HistogramGroup) & ((name: string, options: CalculatedHistogramOptions<Record<string, number>>) => void)
/**
* Register an arbitrary summary. Call this to set help/labels for summaries
* and observe them by calling methods on the returned summary object
*/
registerSummary: ((name: string, options?: SummaryOptions) => Summary) & ((name: string, options: CalculatedSummaryOptions) => void)
/**
* Register a a group of related summaries. Call this to set help/labels for
* groups of related summaries that will be updated with by calling the `.observe`
* method on the returned summary group object
*/
registerSummaryGroup: ((name: string, options?: SummaryOptions) => SummaryGroup) & ((name: string, options: CalculatedSummaryOptions<Record<string, number>>) => void)
/**
* Wrap a function for tracing purposes.
*
* All functions wrapped like this should accept a final optional options arg.
*
* In order to pass an execution context along to create a multi-layered
* trace, the index of the options arg must be specified.
*/
traceFunction <F extends (...args: any[]) => AsyncIterator<any>> (name: string, fn: F, options?: TraceGeneratorFunctionOptions<Parameters<F>, ReturnType<F>, YieldType<ReturnType<F>>>): F
traceFunction <F extends (...args: any[]) => Iterator<any>> (name: string, fn: F, options?: TraceGeneratorFunctionOptions<Parameters<F>, ReturnType<F>, YieldType<ReturnType<F>>>): F
traceFunction <F extends (...args: any[]) => any = (...args: any[]) => any> (name: string, fn: F, options?: TraceFunctionOptions<Parameters<F>, ReturnType<F>>): F
/**
* Creates a tracing context that can be used to trace a method call
*/
createTrace(): any
}
/**
* Infer the yielded type of an (async)iterable
*/
export type YieldType<T extends AsyncIterator<any> | Iterator<any>> = T extends AsyncIterator<infer Y> ? Y : T extends Iterator<infer Y, any, any> ? Y : never
export type TraceAttributes = Record<string, number | string | boolean | number[] | string[] | boolean[]>
export interface TraceFunctionOptions<A, B> {
/**
* To construct a trace that spans multiple method invocations, it's necessary
* to pass the trace context onwards as part of the options object.
*
* Specify the index of the options object in the args array here.
*
* @default 0
*/
optionsIndex?: number
/**
* Set attributes on the trace by modifying the passed attributes object.
*/
getAttributesFromArgs?(args: A, attributes: TraceAttributes): TraceAttributes
/**
* Set attributes on the trace by modifying the passed attributes object. The
* object will have previously been passed to `appendAttributesFromArgs`
* and/or `appendAttributesFromYieldedValue` (if defined)
*/
getAttributesFromReturnValue?(value: B, attributes: TraceAttributes): TraceAttributes
}
export interface TraceGeneratorFunctionOptions<A, B, C = any> extends TraceFunctionOptions<A, B> {
/**
* Set attributes on the trace by modifying the passed attributes object. The
* object will have previously been passed to `appendAttributesFromArgs` (if
* defined)
*/
getAttributesFromYieldedValue? (value: C, attributes: TraceAttributes, index: number): TraceAttributes
}