Add ability to customize views/playback interval

pull/6128/head
Chocobozzz 2023-12-13 10:06:25 +01:00
parent 49a4b8cb7d
commit fe37e5232b
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
15 changed files with 143 additions and 14 deletions

View File

@ -113,8 +113,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
private hotkeys: Hotkey[] = []
private static VIEW_VIDEO_INTERVAL_MS = 5000
constructor (
private route: ActivatedRoute,
private router: Router,
@ -625,9 +623,16 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
instanceName: this.serverConfig.instance.name,
language: this.localeId,
metricsUrl: environment.apiUrl + '/api/v1/metrics/playback',
videoViewIntervalMs: VideoWatchComponent.VIEW_VIDEO_INTERVAL_MS,
metricsUrl: this.serverConfig.openTelemetry.metrics.enabled
? environment.apiUrl + '/api/v1/metrics/playback'
: null,
metricsInterval: this.serverConfig.openTelemetry.metrics.playbackStatsInterval,
videoViewIntervalMs: this.isUserLoggedIn()
? this.serverConfig.views.videos.watchingInterval.users
: this.serverConfig.views.videos.watchingInterval.anonymous,
authorizationHeader: () => this.authService.getRequestHeaderValue(),
serverUrl: environment.originServerUrl || window.location.origin,

View File

@ -382,6 +382,7 @@ export class PeerTubePlayer {
mode: () => this.currentLoadOptions.mode,
metricsUrl: () => this.options.metricsUrl,
metricsInterval: () => this.options.metricsInterval,
videoUUID: () => this.currentLoadOptions.videoUUID
}
}

View File

@ -25,10 +25,6 @@ class MetricsPlugin extends Plugin {
private metricsInterval: any
private readonly CONSTANTS = {
METRICS_INTERVAL: 15000
}
constructor (player: videojs.Player, options: MetricsPluginOptions) {
super(player)
@ -74,6 +70,7 @@ class MetricsPlugin extends Plugin {
private runMetricsInterval () {
if (this.metricsInterval) clearInterval(this.metricsInterval)
if (!this.options_.metricsUrl()) return
this.metricsInterval = setInterval(() => {
let resolution: number
@ -135,7 +132,7 @@ class MetricsPlugin extends Plugin {
return fetch(this.options_.metricsUrl(), { method: 'POST', body: JSON.stringify(body), headers })
.catch(err => logger.error('Cannot send metrics to the server.', err))
}, this.CONSTANTS.METRICS_INTERVAL)
}, this.options_.metricsInterval())
}
private trackBytes () {

View File

@ -30,6 +30,8 @@ export type PeerTubePlayerContructorOptions = {
authorizationHeader: () => string
metricsUrl: string
metricsInterval: number
serverUrl: string
errorNotifier: (message: string) => void

View File

@ -135,6 +135,7 @@ type PeerTubePluginOptions = {
type MetricsPluginOptions = {
mode: () => PlayerMode
metricsUrl: () => string
metricsInterval: () => number
videoUUID: () => string
}

View File

@ -186,8 +186,13 @@ export class PlayerOptionsBuilder {
playbackRate: this.playbackRate,
inactivityTimeout: 2500,
videoViewIntervalMs: 5000,
metricsUrl: window.location.origin + '/api/v1/metrics/playback',
videoViewIntervalMs: serverConfig.views.videos.watchingInterval.anonymous,
metricsUrl: serverConfig.openTelemetry.metrics.enabled
? window.location.origin + '/api/v1/metrics/playback'
: null,
metricsInterval: serverConfig.openTelemetry.metrics.playbackStatsInterval,
authorizationHeader,

View File

@ -254,6 +254,9 @@ open_telemetry:
metrics:
enabled: false
# How often viewers send playback stats to server
playback_stats_interval: '15 seconds'
http_request_duration:
# You can disable HTTP request duration metric that can have a high tag cardinality
enabled: true
@ -362,6 +365,17 @@ views:
ip_view_expiration: '1 hour'
# How often the web browser sends "is watching" information to the server
# Increase the value or set null to disable it if you plan to have many viewers
watching_interval:
# Non logged-in viewers
anonymous: '5 seconds'
# Logged-in users of your instance
# Unlike anonymous viewers, this endpoint is also used to store the "last watched video timecode" for your users
# Increasing this value reduces the accuracy of the video resume
users: '5 seconds'
# Used to get country location of views of local videos
geo_ip:
enabled: true

View File

@ -38,6 +38,7 @@ log:
open_telemetry:
metrics:
enabled: true
playback_stats_interval: '13 seconds'
contact_form:
enabled: true
@ -118,6 +119,10 @@ views:
remote:
max_age: -1
watching_interval:
anonymous: '6 seconds'
users: '4 seconds'
geo_ip:
enabled: true

View File

@ -252,6 +252,9 @@ open_telemetry:
metrics:
enabled: false
# How often viewers send playback stats to server
playback_stats_interval: '15 seconds'
http_request_duration:
# You can disable HTTP request duration metric that can have a high tag cardinality
enabled: true
@ -360,6 +363,17 @@ views:
ip_view_expiration: '1 hour'
# How often the web browser sends "is watching" information to the server
# Increase the value or set null to disable it if you plan to have many viewers
watching_interval:
# Non logged-in viewers
anonymous: '5 seconds'
# Logged-in users of your instance
# Unlike anonymous viewers, this endpoint is also used to store the "last watched video timecode" for your users
# Increasing this value reduces the accuracy of the video resume
users: '5 seconds'
# Used to get country location of views of local videos
geo_ip:
enabled: true

View File

@ -300,6 +300,27 @@ export interface ServerConfig {
homepage: {
enabled: boolean
}
openTelemetry: {
metrics: {
enabled: boolean
// milliseconds
playbackStatsInterval: number
}
}
views: {
videos: {
watchingInterval: {
// milliseconds
anonymous: number
// milliseconds
users: number
}
}
}
}
export type HTMLServerConfig = Omit<ServerConfig, 'signup'>

View File

@ -498,6 +498,16 @@ describe('Test config', function () {
await setAccessTokensToServers([ server ])
})
it('Should have the correct default config', async function () {
const data = await server.config.getConfig()
expect(data.openTelemetry.metrics.enabled).to.be.false
expect(data.openTelemetry.metrics.playbackStatsInterval).to.equal(15000)
expect(data.views.videos.watchingInterval.anonymous).to.equal(5000)
expect(data.views.videos.watchingInterval.users).to.equal(5000)
})
it('Should have a correct config on a server with registration enabled', async function () {
const data = await server.config.getConfig()

View File

@ -19,8 +19,9 @@ function checkMissedConfig () {
'storage.redundancy', 'storage.tmp', 'storage.streaming_playlists', 'storage.plugins', 'storage.well_known',
'log.level', 'log.rotation.enabled', 'log.rotation.max_file_size', 'log.rotation.max_files', 'log.anonymize_ip',
'log.log_ping_requests', 'log.log_tracker_unknown_infohash', 'log.prettify_sql', 'log.accept_client_log',
'open_telemetry.metrics.enabled', 'open_telemetry.metrics.prometheus_exporter.hostname',
'open_telemetry.metrics.prometheus_exporter.port', 'open_telemetry.tracing.enabled', 'open_telemetry.tracing.jaeger_exporter.endpoint',
'open_telemetry.metrics.enabled', 'open_telemetry.metrics.playback_stats_interval',
'open_telemetry.metrics.prometheus_exporter.hostname', 'open_telemetry.metrics.prometheus_exporter.port',
'open_telemetry.tracing.enabled', 'open_telemetry.tracing.jaeger_exporter.endpoint',
'open_telemetry.metrics.http_request_duration.enabled',
'user.history.videos.enabled', 'user.video_quota', 'user.video_quota_daily',
'video_channels.max_per_user',
@ -54,6 +55,7 @@ function checkMissedConfig () {
'followers.instance.enabled', 'followers.instance.manual_approval',
'tracker.enabled', 'tracker.private', 'tracker.reject_too_many_announces',
'history.videos.max_age', 'views.videos.remote.max_age', 'views.videos.local_buffer_update_interval', 'views.videos.ip_view_expiration',
'views.videos.watching_interval.anonymous', 'views.videos.watching_interval.users',
'rates_limit.api.window', 'rates_limit.api.max', 'rates_limit.login.window', 'rates_limit.login.max',
'rates_limit.signup.window', 'rates_limit.signup.max', 'rates_limit.ask_send_email.window', 'rates_limit.ask_send_email.max',
'rates_limit.receive_client_log.window', 'rates_limit.receive_client_log.max', 'rates_limit.plugins.window', 'rates_limit.plugins.max',

View File

@ -228,6 +228,8 @@ const CONFIG = {
METRICS: {
ENABLED: config.get<boolean>('open_telemetry.metrics.enabled'),
PLAYBACK_STATS_INTERVAL: parseDurationToMs(config.get<string>('open_telemetry.metrics.playback_stats_interval')),
HTTP_REQUEST_DURATION: {
ENABLED: config.get<boolean>('open_telemetry.metrics.http_request_duration.enabled')
},
@ -294,7 +296,11 @@ const CONFIG = {
MAX_AGE: parseDurationToMs(config.get('views.videos.remote.max_age'))
},
LOCAL_BUFFER_UPDATE_INTERVAL: parseDurationToMs(config.get('views.videos.local_buffer_update_interval')),
IP_VIEW_EXPIRATION: parseDurationToMs(config.get('views.videos.ip_view_expiration'))
IP_VIEW_EXPIRATION: parseDurationToMs(config.get('views.videos.ip_view_expiration')),
WATCHING_INTERVAL: {
ANONYMOUS: parseDurationToMs(config.get<string>('views.videos.watching_interval.anonymous')),
USERS: parseDurationToMs(config.get<string>('views.videos.watching_interval.users'))
}
}
},
GEO_IP: {

View File

@ -274,6 +274,22 @@ class ServerConfigManager {
homepage: {
enabled: this.homepageEnabled
},
openTelemetry: {
metrics: {
enabled: CONFIG.OPEN_TELEMETRY.METRICS.ENABLED,
playbackStatsInterval: CONFIG.OPEN_TELEMETRY.METRICS.PLAYBACK_STATS_INTERVAL
}
},
views: {
videos: {
watchingInterval: {
anonymous: CONFIG.VIEWS.VIDEOS.WATCHING_INTERVAL.ANONYMOUS,
users: CONFIG.VIEWS.VIDEOS.WATCHING_INTERVAL.USERS
}
}
}
}
}

View File

@ -8126,6 +8126,36 @@ components:
enabled:
type: boolean
openTelemetry:
type: object
description: 'PeerTube >= 6.1'
properties:
metrics:
type: object
properties:
enabled:
type: boolean
playbackStatsInterval:
type: number
description: 'Milliseconds'
views:
type: object
description: 'PeerTube >= 6.1'
properties:
views:
type: object
properties:
watchingInterval:
type: object
properties:
anonymous:
type: number
description: 'Milliseconds'
users:
type: number
description: 'Milliseconds'
SendClientLog:
properties:
message: