From fd3c2e87051f5029cdec39d877b576a62f48e219 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 12 Aug 2022 16:41:29 +0200 Subject: Add playback metric endpoint sent to OTEL --- server/lib/opentelemetry/metric-helpers/index.ts | 1 + .../metric-helpers/nodejs-observers-builder.ts | 18 ++++--- .../metric-helpers/playback-metrics.ts | 59 ++++++++++++++++++++++ server/lib/opentelemetry/metrics.ts | 20 +++++++- 4 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 server/lib/opentelemetry/metric-helpers/playback-metrics.ts (limited to 'server/lib/opentelemetry') diff --git a/server/lib/opentelemetry/metric-helpers/index.ts b/server/lib/opentelemetry/metric-helpers/index.ts index 1b3813743..775d954ba 100644 --- a/server/lib/opentelemetry/metric-helpers/index.ts +++ b/server/lib/opentelemetry/metric-helpers/index.ts @@ -1,5 +1,6 @@ export * from './lives-observers-builder' export * from './job-queue-observers-builder' export * from './nodejs-observers-builder' +export * from './playback-metrics' export * from './stats-observers-builder' export * from './viewers-observers-builder' diff --git a/server/lib/opentelemetry/metric-helpers/nodejs-observers-builder.ts b/server/lib/opentelemetry/metric-helpers/nodejs-observers-builder.ts index 766cbe03b..473015e91 100644 --- a/server/lib/opentelemetry/metric-helpers/nodejs-observers-builder.ts +++ b/server/lib/opentelemetry/metric-helpers/nodejs-observers-builder.ts @@ -2,7 +2,7 @@ import { readdir } from 'fs-extra' import { constants, PerformanceObserver } from 'perf_hooks' import * as process from 'process' import { Meter, ObservableResult } from '@opentelemetry/api-metrics' -import { ExplicitBucketHistogramAggregation, MeterProvider } from '@opentelemetry/sdk-metrics-base' +import { ExplicitBucketHistogramAggregation } from '@opentelemetry/sdk-metrics-base' import { View } from '@opentelemetry/sdk-metrics-base/build/src/view/View' import { logger } from '@server/helpers/logger' @@ -12,7 +12,16 @@ import { logger } from '@server/helpers/logger' export class NodeJSObserversBuilder { - constructor (private readonly meter: Meter, private readonly meterProvider: MeterProvider) { + constructor (private readonly meter: Meter) { + } + + static getViews () { + return [ + new View({ + aggregation: new ExplicitBucketHistogramAggregation([ 0.001, 0.01, 0.1, 1, 2, 5 ]), + instrumentName: 'nodejs_gc_duration_seconds' + }) + ] } buildObservers () { @@ -91,11 +100,6 @@ export class NodeJSObserversBuilder { [constants.NODE_PERFORMANCE_GC_WEAKCB]: 'weakcb' } - this.meterProvider.addView( - new View({ aggregation: new ExplicitBucketHistogramAggregation([ 0.001, 0.01, 0.1, 1, 2, 5 ]) }), - { instrument: { name: 'nodejs_gc_duration_seconds' } } - ) - const histogram = this.meter.createHistogram('nodejs_gc_duration_seconds', { description: 'Garbage collection duration by kind, one of major, minor, incremental or weakcb' }) diff --git a/server/lib/opentelemetry/metric-helpers/playback-metrics.ts b/server/lib/opentelemetry/metric-helpers/playback-metrics.ts new file mode 100644 index 000000000..d2abdee62 --- /dev/null +++ b/server/lib/opentelemetry/metric-helpers/playback-metrics.ts @@ -0,0 +1,59 @@ +import { Counter, Meter } from '@opentelemetry/api-metrics' +import { MVideoImmutable } from '@server/types/models' +import { PlaybackMetricCreate } from '@shared/models' + +export class PlaybackMetrics { + private errorsCounter: Counter + private resolutionChangesCounter: Counter + + private downloadedBytesP2PCounter: Counter + private uploadedBytesP2PCounter: Counter + + private downloadedBytesHTTPCounter: Counter + + constructor (private readonly meter: Meter) { + + } + + buildCounters () { + this.errorsCounter = this.meter.createCounter('peertube_playback_errors_count', { + description: 'Errors collected from PeerTube player.' + }) + + this.resolutionChangesCounter = this.meter.createCounter('peertube_playback_resolution_changes_count', { + description: 'Resolution changes collected from PeerTube player.' + }) + + this.downloadedBytesHTTPCounter = this.meter.createCounter('peertube_playback_http_downloaded_bytes', { + description: 'Downloaded bytes with HTTP by PeerTube player.' + }) + this.downloadedBytesP2PCounter = this.meter.createCounter('peertube_playback_p2p_downloaded_bytes', { + description: 'Downloaded bytes with P2P by PeerTube player.' + }) + + this.uploadedBytesP2PCounter = this.meter.createCounter('peertube_playback_p2p_uploaded_bytes', { + description: 'Uploaded bytes with P2P by PeerTube player.' + }) + } + + observe (video: MVideoImmutable, metrics: PlaybackMetricCreate) { + const attributes = { + videoOrigin: video.remote + ? 'remote' + : 'local', + + playerMode: metrics.playerMode, + + resolution: metrics.resolution + '', + fps: metrics.fps + '' + } + + this.errorsCounter.add(metrics.errors, attributes) + this.resolutionChangesCounter.add(metrics.resolutionChanges, attributes) + + this.downloadedBytesHTTPCounter.add(metrics.downloadedBytesHTTP, attributes) + this.downloadedBytesP2PCounter.add(metrics.downloadedBytesP2P, attributes) + + this.uploadedBytesP2PCounter.add(metrics.uploadedBytesP2P, attributes) + } +} diff --git a/server/lib/opentelemetry/metrics.ts b/server/lib/opentelemetry/metrics.ts index ffe493670..ba33c9505 100644 --- a/server/lib/opentelemetry/metrics.ts +++ b/server/lib/opentelemetry/metrics.ts @@ -4,10 +4,13 @@ import { PrometheusExporter } from '@opentelemetry/exporter-prometheus' import { MeterProvider } from '@opentelemetry/sdk-metrics-base' import { logger } from '@server/helpers/logger' import { CONFIG } from '@server/initializers/config' +import { MVideoImmutable } from '@server/types/models' +import { PlaybackMetricCreate } from '@shared/models' import { JobQueueObserversBuilder, LivesObserversBuilder, NodeJSObserversBuilder, + PlaybackMetrics, StatsObserversBuilder, ViewersObserversBuilder } from './metric-helpers' @@ -20,6 +23,8 @@ class OpenTelemetryMetrics { private onRequestDuration: (req: Request, res: Response) => void + private playbackMetrics: PlaybackMetrics + private constructor () {} init (app: Application) { @@ -41,7 +46,11 @@ class OpenTelemetryMetrics { logger.info('Registering Open Telemetry metrics') - const provider = new MeterProvider() + const provider = new MeterProvider({ + views: [ + ...NodeJSObserversBuilder.getViews() + ] + }) provider.addMetricReader(new PrometheusExporter({ port: CONFIG.OPEN_TELEMETRY.METRICS.PROMETHEUS_EXPORTER.PORT })) @@ -51,7 +60,10 @@ class OpenTelemetryMetrics { this.buildRequestObserver() - const nodeJSObserversBuilder = new NodeJSObserversBuilder(this.meter, provider) + this.playbackMetrics = new PlaybackMetrics(this.meter) + this.playbackMetrics.buildCounters() + + const nodeJSObserversBuilder = new NodeJSObserversBuilder(this.meter) nodeJSObserversBuilder.buildObservers() const jobQueueObserversBuilder = new JobQueueObserversBuilder(this.meter) @@ -67,6 +79,10 @@ class OpenTelemetryMetrics { viewersObserversBuilder.buildObservers() } + observePlaybackMetric (video: MVideoImmutable, metrics: PlaybackMetricCreate) { + this.playbackMetrics.observe(video, metrics) + } + private buildRequestObserver () { const requestDuration = this.meter.createHistogram('http_request_duration_ms', { unit: 'milliseconds', -- cgit v1.2.3