diff --git a/packages/bitswap/src/network.ts b/packages/bitswap/src/network.ts index 6c9c688ec..8e53b6282 100644 --- a/packages/bitswap/src/network.ts +++ b/packages/bitswap/src/network.ts @@ -15,7 +15,7 @@ import type { WantOptions } from './bitswap.js' import type { MultihashHasherLoader } from './index.js' import type { Block } from './pb/message.js' import type { Provider, Routing } from '@helia/interface/routing' -import type { Libp2p, AbortOptions, Connection, PeerId, IncomingStreamData, Topology, ComponentLogger, IdentifyResult, Counter } from '@libp2p/interface' +import type { Libp2p, AbortOptions, Connection, PeerId, IncomingStreamData, Topology, ComponentLogger, IdentifyResult, Counter, Metrics } from '@libp2p/interface' import type { Logger } from '@libp2p/logger' import type { CID } from 'multiformats/cid' import type { ProgressEvent, ProgressOptions } from 'progress-events' @@ -49,6 +49,7 @@ export interface NetworkComponents { routing: Routing logger: ComponentLogger libp2p: Libp2p + metrics?: Metrics } export interface BitswapMessageEventDetail { @@ -101,13 +102,13 @@ export class Network extends TypedEventEmitter { this.maxIncomingMessageSize = init.maxIncomingMessageSize ?? DEFAULT_MAX_OUTGOING_MESSAGE_SIZE this.maxOutgoingMessageSize = init.maxOutgoingMessageSize ?? init.maxIncomingMessageSize ?? DEFAULT_MAX_INCOMING_MESSAGE_SIZE this.metrics = { - blocksSent: components.libp2p.metrics?.registerCounter('helia_bitswap_sent_blocks_total'), - dataSent: components.libp2p.metrics?.registerCounter('helia_bitswap_sent_data_bytes_total') + blocksSent: components.metrics?.registerCounter('helia_bitswap_sent_blocks_total'), + dataSent: components.metrics?.registerCounter('helia_bitswap_sent_data_bytes_total') } this.sendQueue = new PeerQueue({ concurrency: init.messageSendConcurrency ?? DEFAULT_MESSAGE_SEND_CONCURRENCY, - metrics: components.libp2p.metrics, + metrics: components.metrics, metricName: 'helia_bitswap_message_send_queue' }) this.sendQueue.addEventListener('error', (evt) => { diff --git a/packages/bitswap/src/peer-want-lists/index.ts b/packages/bitswap/src/peer-want-lists/index.ts index 2fce81ac4..661fe5ae8 100644 --- a/packages/bitswap/src/peer-want-lists/index.ts +++ b/packages/bitswap/src/peer-want-lists/index.ts @@ -6,7 +6,7 @@ import { Ledger } from './ledger.js' import type { BitswapNotifyProgressEvents, WantListEntry } from '../index.js' import type { Network } from '../network.js' import type { BitswapMessage } from '../pb/message.js' -import type { ComponentLogger, Libp2p, Logger, PeerId } from '@libp2p/interface' +import type { ComponentLogger, Libp2p, Logger, Metrics, PeerId } from '@libp2p/interface' import type { PeerMap } from '@libp2p/peer-collections' import type { Blockstore } from 'interface-blockstore' import type { AbortOptions } from 'it-length-prefixed-stream' @@ -21,6 +21,7 @@ export interface PeerWantListsComponents { network: Network libp2p: Libp2p logger: ComponentLogger + metrics?: Metrics } export interface PeerLedger { @@ -48,7 +49,7 @@ export class PeerWantLists { this.ledgerMap = trackedPeerMap({ name: 'helia_bitswap_ledger_map', - metrics: components.libp2p.metrics + metrics: components.metrics }) this.network.addEventListener('bitswap:message', (evt) => { diff --git a/packages/bitswap/src/stats.ts b/packages/bitswap/src/stats.ts index f45fd7ea1..7b2880f64 100644 --- a/packages/bitswap/src/stats.ts +++ b/packages/bitswap/src/stats.ts @@ -1,7 +1,8 @@ -import type { Libp2p, MetricGroup, PeerId } from '@libp2p/interface' +import type { Libp2p, MetricGroup, Metrics, PeerId } from '@libp2p/interface' export interface StatsComponents { libp2p: Libp2p + metrics?: Metrics } export class Stats { @@ -11,10 +12,10 @@ export class Stats { private readonly duplicateDataReceived?: MetricGroup constructor (components: StatsComponents) { - this.blocksReceived = components.libp2p.metrics?.registerMetricGroup('helia_bitswap_received_blocks') - this.duplicateBlocksReceived = components.libp2p.metrics?.registerMetricGroup('helia_bitswap_duplicate_received_blocks') - this.dataReceived = components.libp2p.metrics?.registerMetricGroup('helia_bitswap_data_received_bytes') - this.duplicateDataReceived = components.libp2p.metrics?.registerMetricGroup('helia_bitswap_duplicate_data_received_bytes') + this.blocksReceived = components.metrics?.registerMetricGroup('helia_bitswap_received_blocks') + this.duplicateBlocksReceived = components.metrics?.registerMetricGroup('helia_bitswap_duplicate_received_blocks') + this.dataReceived = components.metrics?.registerMetricGroup('helia_bitswap_data_received_bytes') + this.duplicateDataReceived = components.metrics?.registerMetricGroup('helia_bitswap_duplicate_data_received_bytes') } updateBlocksReceived (count: number = 1, peerId?: PeerId): void { diff --git a/packages/bitswap/src/want-list.ts b/packages/bitswap/src/want-list.ts index 34d2023dd..1aacaea6e 100644 --- a/packages/bitswap/src/want-list.ts +++ b/packages/bitswap/src/want-list.ts @@ -17,7 +17,7 @@ import vd from './utils/varint-decoder.js' import type { BitswapNotifyProgressEvents, MultihashHasherLoader } from './index.js' import type { BitswapNetworkWantProgressEvents, Network } from './network.js' import type { BitswapMessage } from './pb/message.js' -import type { ComponentLogger, PeerId, Startable, AbortOptions, Libp2p, TypedEventTarget } from '@libp2p/interface' +import type { ComponentLogger, PeerId, Startable, AbortOptions, Libp2p, TypedEventTarget, Metrics } from '@libp2p/interface' import type { Logger } from '@libp2p/logger' import type { PeerMap } from '@libp2p/peer-collections' import type { DeferredPromise } from 'p-defer' @@ -27,6 +27,7 @@ export interface WantListComponents { network: Network logger: ComponentLogger libp2p: Libp2p + metrics?: Metrics } export interface WantListInit { @@ -114,11 +115,11 @@ export class WantList extends TypedEventEmitter implements Start setMaxListeners(Infinity, this) this.peers = trackedPeerMap({ name: 'helia_bitswap_peers', - metrics: components.libp2p.metrics + metrics: components.metrics }) this.wants = trackedMap({ name: 'helia_bitswap_wantlist', - metrics: components.libp2p.metrics + metrics: components.metrics }) this.network = components.network this.sendMessagesDelay = init.sendMessagesDelay ?? DEFAULT_MESSAGE_SEND_DELAY diff --git a/packages/bitswap/test/stats.spec.ts b/packages/bitswap/test/stats.spec.ts index 923f6dfa2..19c37cfe0 100644 --- a/packages/bitswap/test/stats.spec.ts +++ b/packages/bitswap/test/stats.spec.ts @@ -6,6 +6,7 @@ import type { Libp2p, MetricGroup, Metrics } from '@libp2p/interface' interface StubbedStatsComponents { libp2p: StubbedInstance + metrics: StubbedInstance } describe('stats', () => { @@ -15,15 +16,14 @@ describe('stats', () => { beforeEach(() => { components = { - libp2p: stubInterface({ - metrics: stubInterface() - }) + libp2p: stubInterface(), + metrics: stubInterface() } metricGroup = stubInterface() // @ts-expect-error tsc does not select correct method overload sig - components.libp2p.metrics?.registerMetricGroup.returns(metricGroup) + components.metrics?.registerMetricGroup.returns(metricGroup) stats = new Stats(components) }) diff --git a/packages/helia/src/index.ts b/packages/helia/src/index.ts index cb4ed8b79..4e5050453 100644 --- a/packages/helia/src/index.ts +++ b/packages/helia/src/index.ts @@ -122,7 +122,8 @@ export async function createHelia (init: Partial = {}): Promise public hashers: Record public dns: DNS + public metrics?: Metrics private readonly log: Logger constructor (init: HeliaInit) { @@ -161,6 +169,7 @@ export class Helia implements HeliaInterface { this.hashers = defaultHashers(init.hashers) this.dagWalkers = defaultDagWalkers(init.dagWalkers) this.dns = init.dns ?? dns() + this.metrics = init.metrics // @ts-expect-error routing is not set const components: Components = { @@ -171,6 +180,7 @@ export class Helia implements HeliaInterface { logger: this.logger, blockBrokers: [], dns: this.dns, + metrics: this.metrics, ...(init.components ?? {}) } diff --git a/packages/utils/test/index.spec.ts b/packages/utils/test/index.spec.ts index 17b69d341..60c3a5634 100644 --- a/packages/utils/test/index.spec.ts +++ b/packages/utils/test/index.spec.ts @@ -4,7 +4,7 @@ import Sinon from 'sinon' import { stubInterface } from 'sinon-ts' import { createHelia } from './fixtures/create-helia.js' import type { Helia, Routing } from '@helia/interface' -import type { Startable } from '@libp2p/interface' +import type { Startable, Metrics } from '@libp2p/interface' describe('helia', () => { let helia: Helia @@ -19,7 +19,8 @@ describe('helia', () => { start: false, routers: [ routing - ] + ], + metrics: stubInterface() }) }) @@ -49,4 +50,8 @@ describe('helia', () => { it('should have a datastore', async () => { expect(helia).to.have.property('datastore').that.is.ok() }) + + it('supports metrics', async () => { + expect(helia).to.have.property('metrics').that.is.ok() + }) })