diff options
author | Chocobozzz <me@florianbigard.com> | 2023-07-21 11:42:52 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2023-07-21 11:42:52 +0200 |
commit | c6867725fb8e3dfbc2018a37ed5a963103587cb6 (patch) | |
tree | 92e00e551c95553c6090e26a7502593e72bdcfd7 /server | |
parent | b63c607b92fd3ec62e370b73e398062bcf317738 (diff) | |
download | PeerTube-c6867725fb8e3dfbc2018a37ed5a963103587cb6.tar.gz PeerTube-c6867725fb8e3dfbc2018a37ed5a963103587cb6.tar.zst PeerTube-c6867725fb8e3dfbc2018a37ed5a963103587cb6.zip |
Add p2p info to metrics
Diffstat (limited to 'server')
-rw-r--r-- | server/lib/opentelemetry/metric-helpers/playback-metrics.ts | 22 | ||||
-rw-r--r-- | server/middlewares/validators/metrics.ts | 3 | ||||
-rw-r--r-- | server/tests/api/check-params/metrics.ts | 11 | ||||
-rw-r--r-- | server/tests/api/server/open-telemetry.ts | 39 |
4 files changed, 65 insertions, 10 deletions
diff --git a/server/lib/opentelemetry/metric-helpers/playback-metrics.ts b/server/lib/opentelemetry/metric-helpers/playback-metrics.ts index 41a5dd640..1eb08b5a6 100644 --- a/server/lib/opentelemetry/metric-helpers/playback-metrics.ts +++ b/server/lib/opentelemetry/metric-helpers/playback-metrics.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { Counter, Histogram, Meter } from '@opentelemetry/api' | 1 | import { Counter, Meter } from '@opentelemetry/api' |
2 | import { MVideoImmutable } from '@server/types/models' | 2 | import { MVideoImmutable } from '@server/types/models' |
3 | import { PlaybackMetricCreate } from '@shared/models' | 3 | import { PlaybackMetricCreate } from '@shared/models' |
4 | 4 | ||
@@ -11,7 +11,10 @@ export class PlaybackMetrics { | |||
11 | 11 | ||
12 | private downloadedBytesHTTPCounter: Counter | 12 | private downloadedBytesHTTPCounter: Counter |
13 | 13 | ||
14 | private peersP2PPeers: Histogram | 14 | private peersP2PPeersGaugeBuffer: { |
15 | value: number | ||
16 | attributes: any | ||
17 | }[] = [] | ||
15 | 18 | ||
16 | constructor (private readonly meter: Meter) { | 19 | constructor (private readonly meter: Meter) { |
17 | 20 | ||
@@ -37,8 +40,14 @@ export class PlaybackMetrics { | |||
37 | description: 'Uploaded bytes with P2P by PeerTube player.' | 40 | description: 'Uploaded bytes with P2P by PeerTube player.' |
38 | }) | 41 | }) |
39 | 42 | ||
40 | this.peersP2PPeers = this.meter.createHistogram('peertube_playback_p2p_peers', { | 43 | this.meter.createObservableGauge('peertube_playback_p2p_peers', { |
41 | description: 'Total P2P peers connected to the PeerTube player.' | 44 | description: 'Total P2P peers connected to the PeerTube player.' |
45 | }).addCallback(observableResult => { | ||
46 | for (const gauge of this.peersP2PPeersGaugeBuffer) { | ||
47 | observableResult.observe(gauge.value, gauge.attributes) | ||
48 | } | ||
49 | |||
50 | this.peersP2PPeersGaugeBuffer = [] | ||
42 | }) | 51 | }) |
43 | } | 52 | } |
44 | 53 | ||
@@ -66,6 +75,11 @@ export class PlaybackMetrics { | |||
66 | 75 | ||
67 | this.uploadedBytesP2PCounter.add(metrics.uploadedBytesP2P, attributes) | 76 | this.uploadedBytesP2PCounter.add(metrics.uploadedBytesP2P, attributes) |
68 | 77 | ||
69 | if (metrics.totalPeers) this.peersP2PPeers.record(metrics.totalPeers, attributes) | 78 | if (metrics.p2pPeers) { |
79 | this.peersP2PPeersGaugeBuffer.push({ | ||
80 | value: metrics.p2pPeers, | ||
81 | attributes | ||
82 | }) | ||
83 | } | ||
70 | } | 84 | } |
71 | } | 85 | } |
diff --git a/server/middlewares/validators/metrics.ts b/server/middlewares/validators/metrics.ts index ced9afc69..986b30a19 100644 --- a/server/middlewares/validators/metrics.ts +++ b/server/middlewares/validators/metrics.ts | |||
@@ -13,12 +13,11 @@ const addPlaybackMetricValidator = [ | |||
13 | .optional() | 13 | .optional() |
14 | .isInt({ min: 0 }), | 14 | .isInt({ min: 0 }), |
15 | 15 | ||
16 | body('totalPeers') | 16 | body('p2pPeers') |
17 | .optional() | 17 | .optional() |
18 | .isInt({ min: 0 }), | 18 | .isInt({ min: 0 }), |
19 | 19 | ||
20 | body('p2pEnabled') | 20 | body('p2pEnabled') |
21 | .optional() | ||
22 | .isBoolean(), | 21 | .isBoolean(), |
23 | 22 | ||
24 | body('playerMode') | 23 | body('playerMode') |
diff --git a/server/tests/api/check-params/metrics.ts b/server/tests/api/check-params/metrics.ts index 25443401d..302bef4f5 100644 --- a/server/tests/api/check-params/metrics.ts +++ b/server/tests/api/check-params/metrics.ts | |||
@@ -38,6 +38,7 @@ describe('Test metrics API validators', function () { | |||
38 | fps: 30, | 38 | fps: 30, |
39 | resolutionChanges: 1, | 39 | resolutionChanges: 1, |
40 | errors: 2, | 40 | errors: 2, |
41 | p2pEnabled: true, | ||
41 | downloadedBytesP2P: 0, | 42 | downloadedBytesP2P: 0, |
42 | downloadedBytesHTTP: 0, | 43 | downloadedBytesHTTP: 0, |
43 | uploadedBytesP2P: 0, | 44 | uploadedBytesP2P: 0, |
@@ -145,7 +146,13 @@ describe('Test metrics API validators', function () { | |||
145 | }) | 146 | }) |
146 | }) | 147 | }) |
147 | 148 | ||
148 | it('Should fail with an invalid p2pEnabled', async function () { | 149 | it('Should fail with a missing/invalid p2pEnabled', async function () { |
150 | await makePostBodyRequest({ | ||
151 | url: server.url, | ||
152 | path, | ||
153 | fields: omit(baseParams, [ 'p2pEnabled' ]) | ||
154 | }) | ||
155 | |||
149 | await makePostBodyRequest({ | 156 | await makePostBodyRequest({ |
150 | url: server.url, | 157 | url: server.url, |
151 | path, | 158 | path, |
@@ -157,7 +164,7 @@ describe('Test metrics API validators', function () { | |||
157 | await makePostBodyRequest({ | 164 | await makePostBodyRequest({ |
158 | url: server.url, | 165 | url: server.url, |
159 | path, | 166 | path, |
160 | fields: { ...baseParams, totalPeers: 'toto' } | 167 | fields: { ...baseParams, p2pPeers: 'toto' } |
161 | }) | 168 | }) |
162 | }) | 169 | }) |
163 | 170 | ||
diff --git a/server/tests/api/server/open-telemetry.ts b/server/tests/api/server/open-telemetry.ts index 0bd0b5e86..508e9d649 100644 --- a/server/tests/api/server/open-telemetry.ts +++ b/server/tests/api/server/open-telemetry.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { expectLogContain, expectLogDoesNotContain, MockHTTP } from '@server/tests/shared' | 4 | import { expectLogContain, expectLogDoesNotContain, MockHTTP } from '@server/tests/shared' |
5 | import { HttpStatusCode, VideoPrivacy, VideoResolution } from '@shared/models' | 5 | import { HttpStatusCode, PlaybackMetricCreate, VideoPrivacy, VideoResolution } from '@shared/models' |
6 | import { cleanupTests, createSingleServer, makeRawRequest, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' | 6 | import { cleanupTests, createSingleServer, makeRawRequest, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' |
7 | 7 | ||
8 | describe('Open Telemetry', function () { | 8 | describe('Open Telemetry', function () { |
@@ -62,14 +62,49 @@ describe('Open Telemetry', function () { | |||
62 | downloadedBytesP2P: 0, | 62 | downloadedBytesP2P: 0, |
63 | downloadedBytesHTTP: 0, | 63 | downloadedBytesHTTP: 0, |
64 | uploadedBytesP2P: 5, | 64 | uploadedBytesP2P: 5, |
65 | totalPeers: 1, | 65 | p2pPeers: 1, |
66 | p2pEnabled: false, | 66 | p2pEnabled: false, |
67 | videoId: video.uuid | 67 | videoId: video.uuid |
68 | } | 68 | } |
69 | }) | 69 | }) |
70 | 70 | ||
71 | const res = await makeRawRequest({ url: metricsUrl, expectedStatus: HttpStatusCode.OK_200 }) | 71 | const res = await makeRawRequest({ url: metricsUrl, expectedStatus: HttpStatusCode.OK_200 }) |
72 | |||
72 | expect(res.text).to.contain('peertube_playback_http_downloaded_bytes_total{') | 73 | expect(res.text).to.contain('peertube_playback_http_downloaded_bytes_total{') |
74 | expect(res.text).to.contain('peertube_playback_p2p_peers{') | ||
75 | expect(res.text).to.contain('p2pEnabled="false"') | ||
76 | }) | ||
77 | |||
78 | it('Should take the last playback metric', async function () { | ||
79 | await setAccessTokensToServers([ server ]) | ||
80 | |||
81 | const video = await server.videos.quickUpload({ name: 'video' }) | ||
82 | |||
83 | const metrics = { | ||
84 | playerMode: 'p2p-media-loader', | ||
85 | resolution: VideoResolution.H_1080P, | ||
86 | fps: 30, | ||
87 | resolutionChanges: 1, | ||
88 | errors: 2, | ||
89 | downloadedBytesP2P: 0, | ||
90 | downloadedBytesHTTP: 0, | ||
91 | uploadedBytesP2P: 5, | ||
92 | p2pPeers: 7, | ||
93 | p2pEnabled: false, | ||
94 | videoId: video.uuid | ||
95 | } as PlaybackMetricCreate | ||
96 | |||
97 | await server.metrics.addPlaybackMetric({ metrics }) | ||
98 | |||
99 | metrics.p2pPeers = 42 | ||
100 | await server.metrics.addPlaybackMetric({ metrics }) | ||
101 | |||
102 | const res = await makeRawRequest({ url: metricsUrl, expectedStatus: HttpStatusCode.OK_200 }) | ||
103 | |||
104 | // eslint-disable-next-line max-len | ||
105 | const label = `{videoOrigin="local",playerMode="p2p-media-loader",resolution="1080",fps="30",p2pEnabled="false",videoUUID="${video.uuid}"}` | ||
106 | expect(res.text).to.contain(`peertube_playback_p2p_peers${label} 42`) | ||
107 | expect(res.text).to.not.contain(`peertube_playback_p2p_peers${label} 7`) | ||
73 | }) | 108 | }) |
74 | 109 | ||
75 | it('Should disable http request duration metrics', async function () { | 110 | it('Should disable http request duration metrics', async function () { |