diff options
Diffstat (limited to 'server/lib/opentelemetry')
4 files changed, 89 insertions, 9 deletions
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 @@ | |||
1 | export * from './lives-observers-builder' | 1 | export * from './lives-observers-builder' |
2 | export * from './job-queue-observers-builder' | 2 | export * from './job-queue-observers-builder' |
3 | export * from './nodejs-observers-builder' | 3 | export * from './nodejs-observers-builder' |
4 | export * from './playback-metrics' | ||
4 | export * from './stats-observers-builder' | 5 | export * from './stats-observers-builder' |
5 | export * from './viewers-observers-builder' | 6 | 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' | |||
2 | import { constants, PerformanceObserver } from 'perf_hooks' | 2 | import { constants, PerformanceObserver } from 'perf_hooks' |
3 | import * as process from 'process' | 3 | import * as process from 'process' |
4 | import { Meter, ObservableResult } from '@opentelemetry/api-metrics' | 4 | import { Meter, ObservableResult } from '@opentelemetry/api-metrics' |
5 | import { ExplicitBucketHistogramAggregation, MeterProvider } from '@opentelemetry/sdk-metrics-base' | 5 | import { ExplicitBucketHistogramAggregation } from '@opentelemetry/sdk-metrics-base' |
6 | import { View } from '@opentelemetry/sdk-metrics-base/build/src/view/View' | 6 | import { View } from '@opentelemetry/sdk-metrics-base/build/src/view/View' |
7 | import { logger } from '@server/helpers/logger' | 7 | import { logger } from '@server/helpers/logger' |
8 | 8 | ||
@@ -12,7 +12,16 @@ import { logger } from '@server/helpers/logger' | |||
12 | 12 | ||
13 | export class NodeJSObserversBuilder { | 13 | export class NodeJSObserversBuilder { |
14 | 14 | ||
15 | constructor (private readonly meter: Meter, private readonly meterProvider: MeterProvider) { | 15 | constructor (private readonly meter: Meter) { |
16 | } | ||
17 | |||
18 | static getViews () { | ||
19 | return [ | ||
20 | new View({ | ||
21 | aggregation: new ExplicitBucketHistogramAggregation([ 0.001, 0.01, 0.1, 1, 2, 5 ]), | ||
22 | instrumentName: 'nodejs_gc_duration_seconds' | ||
23 | }) | ||
24 | ] | ||
16 | } | 25 | } |
17 | 26 | ||
18 | buildObservers () { | 27 | buildObservers () { |
@@ -91,11 +100,6 @@ export class NodeJSObserversBuilder { | |||
91 | [constants.NODE_PERFORMANCE_GC_WEAKCB]: 'weakcb' | 100 | [constants.NODE_PERFORMANCE_GC_WEAKCB]: 'weakcb' |
92 | } | 101 | } |
93 | 102 | ||
94 | this.meterProvider.addView( | ||
95 | new View({ aggregation: new ExplicitBucketHistogramAggregation([ 0.001, 0.01, 0.1, 1, 2, 5 ]) }), | ||
96 | { instrument: { name: 'nodejs_gc_duration_seconds' } } | ||
97 | ) | ||
98 | |||
99 | const histogram = this.meter.createHistogram('nodejs_gc_duration_seconds', { | 103 | const histogram = this.meter.createHistogram('nodejs_gc_duration_seconds', { |
100 | description: 'Garbage collection duration by kind, one of major, minor, incremental or weakcb' | 104 | description: 'Garbage collection duration by kind, one of major, minor, incremental or weakcb' |
101 | }) | 105 | }) |
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 @@ | |||
1 | import { Counter, Meter } from '@opentelemetry/api-metrics' | ||
2 | import { MVideoImmutable } from '@server/types/models' | ||
3 | import { PlaybackMetricCreate } from '@shared/models' | ||
4 | |||
5 | export class PlaybackMetrics { | ||
6 | private errorsCounter: Counter | ||
7 | private resolutionChangesCounter: Counter | ||
8 | |||
9 | private downloadedBytesP2PCounter: Counter | ||
10 | private uploadedBytesP2PCounter: Counter | ||
11 | |||
12 | private downloadedBytesHTTPCounter: Counter | ||
13 | |||
14 | constructor (private readonly meter: Meter) { | ||
15 | |||
16 | } | ||
17 | |||
18 | buildCounters () { | ||
19 | this.errorsCounter = this.meter.createCounter('peertube_playback_errors_count', { | ||
20 | description: 'Errors collected from PeerTube player.' | ||
21 | }) | ||
22 | |||
23 | this.resolutionChangesCounter = this.meter.createCounter('peertube_playback_resolution_changes_count', { | ||
24 | description: 'Resolution changes collected from PeerTube player.' | ||
25 | }) | ||
26 | |||
27 | this.downloadedBytesHTTPCounter = this.meter.createCounter('peertube_playback_http_downloaded_bytes', { | ||
28 | description: 'Downloaded bytes with HTTP by PeerTube player.' | ||
29 | }) | ||
30 | this.downloadedBytesP2PCounter = this.meter.createCounter('peertube_playback_p2p_downloaded_bytes', { | ||
31 | description: 'Downloaded bytes with P2P by PeerTube player.' | ||
32 | }) | ||
33 | |||
34 | this.uploadedBytesP2PCounter = this.meter.createCounter('peertube_playback_p2p_uploaded_bytes', { | ||
35 | description: 'Uploaded bytes with P2P by PeerTube player.' | ||
36 | }) | ||
37 | } | ||
38 | |||
39 | observe (video: MVideoImmutable, metrics: PlaybackMetricCreate) { | ||
40 | const attributes = { | ||
41 | videoOrigin: video.remote | ||
42 | ? 'remote' | ||
43 | : 'local', | ||
44 | |||
45 | playerMode: metrics.playerMode, | ||
46 | |||
47 | resolution: metrics.resolution + '', | ||
48 | fps: metrics.fps + '' | ||
49 | } | ||
50 | |||
51 | this.errorsCounter.add(metrics.errors, attributes) | ||
52 | this.resolutionChangesCounter.add(metrics.resolutionChanges, attributes) | ||
53 | |||
54 | this.downloadedBytesHTTPCounter.add(metrics.downloadedBytesHTTP, attributes) | ||
55 | this.downloadedBytesP2PCounter.add(metrics.downloadedBytesP2P, attributes) | ||
56 | |||
57 | this.uploadedBytesP2PCounter.add(metrics.uploadedBytesP2P, attributes) | ||
58 | } | ||
59 | } | ||
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' | |||
4 | import { MeterProvider } from '@opentelemetry/sdk-metrics-base' | 4 | import { MeterProvider } from '@opentelemetry/sdk-metrics-base' |
5 | import { logger } from '@server/helpers/logger' | 5 | import { logger } from '@server/helpers/logger' |
6 | import { CONFIG } from '@server/initializers/config' | 6 | import { CONFIG } from '@server/initializers/config' |
7 | import { MVideoImmutable } from '@server/types/models' | ||
8 | import { PlaybackMetricCreate } from '@shared/models' | ||
7 | import { | 9 | import { |
8 | JobQueueObserversBuilder, | 10 | JobQueueObserversBuilder, |
9 | LivesObserversBuilder, | 11 | LivesObserversBuilder, |
10 | NodeJSObserversBuilder, | 12 | NodeJSObserversBuilder, |
13 | PlaybackMetrics, | ||
11 | StatsObserversBuilder, | 14 | StatsObserversBuilder, |
12 | ViewersObserversBuilder | 15 | ViewersObserversBuilder |
13 | } from './metric-helpers' | 16 | } from './metric-helpers' |
@@ -20,6 +23,8 @@ class OpenTelemetryMetrics { | |||
20 | 23 | ||
21 | private onRequestDuration: (req: Request, res: Response) => void | 24 | private onRequestDuration: (req: Request, res: Response) => void |
22 | 25 | ||
26 | private playbackMetrics: PlaybackMetrics | ||
27 | |||
23 | private constructor () {} | 28 | private constructor () {} |
24 | 29 | ||
25 | init (app: Application) { | 30 | init (app: Application) { |
@@ -41,7 +46,11 @@ class OpenTelemetryMetrics { | |||
41 | 46 | ||
42 | logger.info('Registering Open Telemetry metrics') | 47 | logger.info('Registering Open Telemetry metrics') |
43 | 48 | ||
44 | const provider = new MeterProvider() | 49 | const provider = new MeterProvider({ |
50 | views: [ | ||
51 | ...NodeJSObserversBuilder.getViews() | ||
52 | ] | ||
53 | }) | ||
45 | 54 | ||
46 | provider.addMetricReader(new PrometheusExporter({ port: CONFIG.OPEN_TELEMETRY.METRICS.PROMETHEUS_EXPORTER.PORT })) | 55 | provider.addMetricReader(new PrometheusExporter({ port: CONFIG.OPEN_TELEMETRY.METRICS.PROMETHEUS_EXPORTER.PORT })) |
47 | 56 | ||
@@ -51,7 +60,10 @@ class OpenTelemetryMetrics { | |||
51 | 60 | ||
52 | this.buildRequestObserver() | 61 | this.buildRequestObserver() |
53 | 62 | ||
54 | const nodeJSObserversBuilder = new NodeJSObserversBuilder(this.meter, provider) | 63 | this.playbackMetrics = new PlaybackMetrics(this.meter) |
64 | this.playbackMetrics.buildCounters() | ||
65 | |||
66 | const nodeJSObserversBuilder = new NodeJSObserversBuilder(this.meter) | ||
55 | nodeJSObserversBuilder.buildObservers() | 67 | nodeJSObserversBuilder.buildObservers() |
56 | 68 | ||
57 | const jobQueueObserversBuilder = new JobQueueObserversBuilder(this.meter) | 69 | const jobQueueObserversBuilder = new JobQueueObserversBuilder(this.meter) |
@@ -67,6 +79,10 @@ class OpenTelemetryMetrics { | |||
67 | viewersObserversBuilder.buildObservers() | 79 | viewersObserversBuilder.buildObservers() |
68 | } | 80 | } |
69 | 81 | ||
82 | observePlaybackMetric (video: MVideoImmutable, metrics: PlaybackMetricCreate) { | ||
83 | this.playbackMetrics.observe(video, metrics) | ||
84 | } | ||
85 | |||
70 | private buildRequestObserver () { | 86 | private buildRequestObserver () { |
71 | const requestDuration = this.meter.createHistogram('http_request_duration_ms', { | 87 | const requestDuration = this.meter.createHistogram('http_request_duration_ms', { |
72 | unit: 'milliseconds', | 88 | unit: 'milliseconds', |