diff options
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/opentelemetry/metric-helpers/bittorrent-tracker-observers-builder.ts | 51 | ||||
-rw-r--r-- | server/lib/opentelemetry/metric-helpers/index.ts | 1 | ||||
-rw-r--r-- | server/lib/opentelemetry/metrics.ts | 6 | ||||
-rw-r--r-- | server/lib/plugins/plugin-helpers-builder.ts | 6 | ||||
-rw-r--r-- | server/lib/redis.ts | 15 | ||||
-rw-r--r-- | server/lib/sync-channel.ts | 2 | ||||
-rw-r--r-- | server/lib/video-tokens-manager.ts | 22 |
7 files changed, 81 insertions, 22 deletions
diff --git a/server/lib/opentelemetry/metric-helpers/bittorrent-tracker-observers-builder.ts b/server/lib/opentelemetry/metric-helpers/bittorrent-tracker-observers-builder.ts new file mode 100644 index 000000000..ef40c0fa9 --- /dev/null +++ b/server/lib/opentelemetry/metric-helpers/bittorrent-tracker-observers-builder.ts | |||
@@ -0,0 +1,51 @@ | |||
1 | import { Meter } from '@opentelemetry/api' | ||
2 | |||
3 | export class BittorrentTrackerObserversBuilder { | ||
4 | |||
5 | constructor (private readonly meter: Meter, private readonly trackerServer: any) { | ||
6 | |||
7 | } | ||
8 | |||
9 | buildObservers () { | ||
10 | const activeInfohashes = this.meter.createObservableGauge('peertube_bittorrent_tracker_active_infohashes_total', { | ||
11 | description: 'Total active infohashes in the PeerTube BitTorrent Tracker' | ||
12 | }) | ||
13 | const inactiveInfohashes = this.meter.createObservableGauge('peertube_bittorrent_tracker_inactive_infohashes_total', { | ||
14 | description: 'Total inactive infohashes in the PeerTube BitTorrent Tracker' | ||
15 | }) | ||
16 | const peers = this.meter.createObservableGauge('peertube_bittorrent_tracker_peers_total', { | ||
17 | description: 'Total peers in the PeerTube BitTorrent Tracker' | ||
18 | }) | ||
19 | |||
20 | this.meter.addBatchObservableCallback(observableResult => { | ||
21 | const infohashes = Object.keys(this.trackerServer.torrents) | ||
22 | |||
23 | const counters = { | ||
24 | activeInfohashes: 0, | ||
25 | inactiveInfohashes: 0, | ||
26 | peers: 0, | ||
27 | uncompletedPeers: 0 | ||
28 | } | ||
29 | |||
30 | for (const infohash of infohashes) { | ||
31 | const content = this.trackerServer.torrents[infohash] | ||
32 | |||
33 | const peers = content.peers | ||
34 | if (peers.keys.length !== 0) counters.activeInfohashes++ | ||
35 | else counters.inactiveInfohashes++ | ||
36 | |||
37 | for (const peerId of peers.keys) { | ||
38 | const peer = peers.peek(peerId) | ||
39 | if (peer == null) return | ||
40 | |||
41 | counters.peers++ | ||
42 | } | ||
43 | } | ||
44 | |||
45 | observableResult.observe(activeInfohashes, counters.activeInfohashes) | ||
46 | observableResult.observe(inactiveInfohashes, counters.inactiveInfohashes) | ||
47 | observableResult.observe(peers, counters.peers) | ||
48 | }, [ activeInfohashes, inactiveInfohashes, peers ]) | ||
49 | } | ||
50 | |||
51 | } | ||
diff --git a/server/lib/opentelemetry/metric-helpers/index.ts b/server/lib/opentelemetry/metric-helpers/index.ts index 775d954ba..47b24a54f 100644 --- a/server/lib/opentelemetry/metric-helpers/index.ts +++ b/server/lib/opentelemetry/metric-helpers/index.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | export * from './bittorrent-tracker-observers-builder' | ||
1 | export * from './lives-observers-builder' | 2 | export * from './lives-observers-builder' |
2 | export * from './job-queue-observers-builder' | 3 | export * from './job-queue-observers-builder' |
3 | export * from './nodejs-observers-builder' | 4 | export * from './nodejs-observers-builder' |
diff --git a/server/lib/opentelemetry/metrics.ts b/server/lib/opentelemetry/metrics.ts index 226d514c0..9cc067e4a 100644 --- a/server/lib/opentelemetry/metrics.ts +++ b/server/lib/opentelemetry/metrics.ts | |||
@@ -7,6 +7,7 @@ import { CONFIG } from '@server/initializers/config' | |||
7 | import { MVideoImmutable } from '@server/types/models' | 7 | import { MVideoImmutable } from '@server/types/models' |
8 | import { PlaybackMetricCreate } from '@shared/models' | 8 | import { PlaybackMetricCreate } from '@shared/models' |
9 | import { | 9 | import { |
10 | BittorrentTrackerObserversBuilder, | ||
10 | JobQueueObserversBuilder, | 11 | JobQueueObserversBuilder, |
11 | LivesObserversBuilder, | 12 | LivesObserversBuilder, |
12 | NodeJSObserversBuilder, | 13 | NodeJSObserversBuilder, |
@@ -41,7 +42,7 @@ class OpenTelemetryMetrics { | |||
41 | }) | 42 | }) |
42 | } | 43 | } |
43 | 44 | ||
44 | registerMetrics () { | 45 | registerMetrics (options: { trackerServer: any }) { |
45 | if (CONFIG.OPEN_TELEMETRY.METRICS.ENABLED !== true) return | 46 | if (CONFIG.OPEN_TELEMETRY.METRICS.ENABLED !== true) return |
46 | 47 | ||
47 | logger.info('Registering Open Telemetry metrics') | 48 | logger.info('Registering Open Telemetry metrics') |
@@ -80,6 +81,9 @@ class OpenTelemetryMetrics { | |||
80 | 81 | ||
81 | const viewersObserversBuilder = new ViewersObserversBuilder(this.meter) | 82 | const viewersObserversBuilder = new ViewersObserversBuilder(this.meter) |
82 | viewersObserversBuilder.buildObservers() | 83 | viewersObserversBuilder.buildObservers() |
84 | |||
85 | const bittorrentTrackerObserversBuilder = new BittorrentTrackerObserversBuilder(this.meter, options.trackerServer) | ||
86 | bittorrentTrackerObserversBuilder.buildObservers() | ||
83 | } | 87 | } |
84 | 88 | ||
85 | observePlaybackMetric (video: MVideoImmutable, metrics: PlaybackMetricCreate) { | 89 | observePlaybackMetric (video: MVideoImmutable, metrics: PlaybackMetricCreate) { |
diff --git a/server/lib/plugins/plugin-helpers-builder.ts b/server/lib/plugins/plugin-helpers-builder.ts index 7b1def6e3..66383af46 100644 --- a/server/lib/plugins/plugin-helpers-builder.ts +++ b/server/lib/plugins/plugin-helpers-builder.ts | |||
@@ -209,6 +209,10 @@ function buildConfigHelpers () { | |||
209 | return WEBSERVER.URL | 209 | return WEBSERVER.URL |
210 | }, | 210 | }, |
211 | 211 | ||
212 | getServerListeningConfig () { | ||
213 | return { hostname: CONFIG.LISTEN.HOSTNAME, port: CONFIG.LISTEN.PORT } | ||
214 | }, | ||
215 | |||
212 | getServerConfig () { | 216 | getServerConfig () { |
213 | return ServerConfigManager.Instance.getServerConfig() | 217 | return ServerConfigManager.Instance.getServerConfig() |
214 | } | 218 | } |
@@ -245,7 +249,7 @@ function buildUserHelpers () { | |||
245 | }, | 249 | }, |
246 | 250 | ||
247 | getAuthUser: (res: express.Response) => { | 251 | getAuthUser: (res: express.Response) => { |
248 | const user = res.locals.oauth?.token?.User | 252 | const user = res.locals.oauth?.token?.User || res.locals.videoFileToken?.user |
249 | if (!user) return undefined | 253 | if (!user) return undefined |
250 | 254 | ||
251 | return UserModel.loadByIdFull(user.id) | 255 | return UserModel.loadByIdFull(user.id) |
diff --git a/server/lib/redis.ts b/server/lib/redis.ts index c0e9aece7..451ddd0b6 100644 --- a/server/lib/redis.ts +++ b/server/lib/redis.ts | |||
@@ -8,7 +8,6 @@ import { | |||
8 | AP_CLEANER, | 8 | AP_CLEANER, |
9 | CONTACT_FORM_LIFETIME, | 9 | CONTACT_FORM_LIFETIME, |
10 | RESUMABLE_UPLOAD_SESSION_LIFETIME, | 10 | RESUMABLE_UPLOAD_SESSION_LIFETIME, |
11 | TRACKER_RATE_LIMITS, | ||
12 | TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME, | 11 | TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME, |
13 | USER_EMAIL_VERIFY_LIFETIME, | 12 | USER_EMAIL_VERIFY_LIFETIME, |
14 | USER_PASSWORD_CREATE_LIFETIME, | 13 | USER_PASSWORD_CREATE_LIFETIME, |
@@ -157,16 +156,6 @@ class Redis { | |||
157 | return this.exists(this.generateIPViewKey(ip, videoUUID)) | 156 | return this.exists(this.generateIPViewKey(ip, videoUUID)) |
158 | } | 157 | } |
159 | 158 | ||
160 | /* ************ Tracker IP block ************ */ | ||
161 | |||
162 | setTrackerBlockIP (ip: string) { | ||
163 | return this.setValue(this.generateTrackerBlockIPKey(ip), '1', TRACKER_RATE_LIMITS.BLOCK_IP_LIFETIME) | ||
164 | } | ||
165 | |||
166 | async doesTrackerBlockIPExist (ip: string) { | ||
167 | return this.exists(this.generateTrackerBlockIPKey(ip)) | ||
168 | } | ||
169 | |||
170 | /* ************ Video views stats ************ */ | 159 | /* ************ Video views stats ************ */ |
171 | 160 | ||
172 | addVideoViewStats (videoId: number) { | 161 | addVideoViewStats (videoId: number) { |
@@ -365,10 +354,6 @@ class Redis { | |||
365 | return `views-${videoUUID}-${ip}` | 354 | return `views-${videoUUID}-${ip}` |
366 | } | 355 | } |
367 | 356 | ||
368 | private generateTrackerBlockIPKey (ip: string) { | ||
369 | return `tracker-block-ip-${ip}` | ||
370 | } | ||
371 | |||
372 | private generateContactFormKey (ip: string) { | 357 | private generateContactFormKey (ip: string) { |
373 | return 'contact-form-' + ip | 358 | return 'contact-form-' + ip |
374 | } | 359 | } |
diff --git a/server/lib/sync-channel.ts b/server/lib/sync-channel.ts index 10167ee38..3a805a943 100644 --- a/server/lib/sync-channel.ts +++ b/server/lib/sync-channel.ts | |||
@@ -76,7 +76,7 @@ export async function synchronizeChannel (options: { | |||
76 | 76 | ||
77 | await JobQueue.Instance.createJobWithChildren(parent, children) | 77 | await JobQueue.Instance.createJobWithChildren(parent, children) |
78 | } catch (err) { | 78 | } catch (err) { |
79 | logger.error(`Failed to import channel ${channel.name}`, { err }) | 79 | logger.error(`Failed to import ${externalChannelUrl} in channel ${channel.name}`, { err }) |
80 | channelSync.state = VideoChannelSyncState.FAILED | 80 | channelSync.state = VideoChannelSyncState.FAILED |
81 | await channelSync.save() | 81 | await channelSync.save() |
82 | } | 82 | } |
diff --git a/server/lib/video-tokens-manager.ts b/server/lib/video-tokens-manager.ts index c43085d16..17aa29cdd 100644 --- a/server/lib/video-tokens-manager.ts +++ b/server/lib/video-tokens-manager.ts | |||
@@ -1,5 +1,7 @@ | |||
1 | import LRUCache from 'lru-cache' | 1 | import LRUCache from 'lru-cache' |
2 | import { LRU_CACHE } from '@server/initializers/constants' | 2 | import { LRU_CACHE } from '@server/initializers/constants' |
3 | import { MUserAccountUrl } from '@server/types/models' | ||
4 | import { pick } from '@shared/core-utils' | ||
3 | import { buildUUID } from '@shared/extra-utils' | 5 | import { buildUUID } from '@shared/extra-utils' |
4 | 6 | ||
5 | // --------------------------------------------------------------------------- | 7 | // --------------------------------------------------------------------------- |
@@ -10,19 +12,22 @@ class VideoTokensManager { | |||
10 | 12 | ||
11 | private static instance: VideoTokensManager | 13 | private static instance: VideoTokensManager |
12 | 14 | ||
13 | private readonly lruCache = new LRUCache<string, string>({ | 15 | private readonly lruCache = new LRUCache<string, { videoUUID: string, user: MUserAccountUrl }>({ |
14 | max: LRU_CACHE.VIDEO_TOKENS.MAX_SIZE, | 16 | max: LRU_CACHE.VIDEO_TOKENS.MAX_SIZE, |
15 | ttl: LRU_CACHE.VIDEO_TOKENS.TTL | 17 | ttl: LRU_CACHE.VIDEO_TOKENS.TTL |
16 | }) | 18 | }) |
17 | 19 | ||
18 | private constructor () {} | 20 | private constructor () {} |
19 | 21 | ||
20 | create (videoUUID: string) { | 22 | create (options: { |
23 | user: MUserAccountUrl | ||
24 | videoUUID: string | ||
25 | }) { | ||
21 | const token = buildUUID() | 26 | const token = buildUUID() |
22 | 27 | ||
23 | const expires = new Date(new Date().getTime() + LRU_CACHE.VIDEO_TOKENS.TTL) | 28 | const expires = new Date(new Date().getTime() + LRU_CACHE.VIDEO_TOKENS.TTL) |
24 | 29 | ||
25 | this.lruCache.set(token, videoUUID) | 30 | this.lruCache.set(token, pick(options, [ 'user', 'videoUUID' ])) |
26 | 31 | ||
27 | return { token, expires } | 32 | return { token, expires } |
28 | } | 33 | } |
@@ -34,7 +39,16 @@ class VideoTokensManager { | |||
34 | const value = this.lruCache.get(options.token) | 39 | const value = this.lruCache.get(options.token) |
35 | if (!value) return false | 40 | if (!value) return false |
36 | 41 | ||
37 | return value === options.videoUUID | 42 | return value.videoUUID === options.videoUUID |
43 | } | ||
44 | |||
45 | getUserFromToken (options: { | ||
46 | token: string | ||
47 | }) { | ||
48 | const value = this.lruCache.get(options.token) | ||
49 | if (!value) return undefined | ||
50 | |||
51 | return value.user | ||
38 | } | 52 | } |
39 | 53 | ||
40 | static get Instance () { | 54 | static get Instance () { |