2022-07-05 08:43:21 -05:00
|
|
|
import memoizee from 'memoizee'
|
|
|
|
import { Meter } from '@opentelemetry/api-metrics'
|
|
|
|
import { MEMOIZE_TTL } from '@server/initializers/constants'
|
|
|
|
import { buildAvailableActivities } from '@server/lib/activitypub/activity'
|
|
|
|
import { StatsManager } from '@server/lib/stat-manager'
|
|
|
|
|
2022-07-19 04:58:19 -05:00
|
|
|
export class StatsObserversBuilder {
|
2022-07-05 08:43:21 -05:00
|
|
|
|
|
|
|
private readonly getInstanceStats = memoizee(() => {
|
|
|
|
return StatsManager.Instance.getStats()
|
|
|
|
}, { maxAge: MEMOIZE_TTL.GET_STATS_FOR_OPEN_TELEMETRY_METRICS })
|
|
|
|
|
|
|
|
constructor (private readonly meter: Meter) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
buildObservers () {
|
|
|
|
this.buildUserStatsObserver()
|
|
|
|
this.buildVideoStatsObserver()
|
|
|
|
this.buildCommentStatsObserver()
|
|
|
|
this.buildPlaylistStatsObserver()
|
|
|
|
this.buildChannelStatsObserver()
|
|
|
|
this.buildInstanceFollowsStatsObserver()
|
|
|
|
this.buildRedundancyStatsObserver()
|
|
|
|
this.buildActivityPubStatsObserver()
|
|
|
|
}
|
|
|
|
|
|
|
|
private buildUserStatsObserver () {
|
|
|
|
this.meter.createObservableGauge('peertube_users_total', {
|
|
|
|
description: 'Total users on the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalUsers)
|
|
|
|
})
|
|
|
|
|
|
|
|
this.meter.createObservableGauge('peertube_active_users_total', {
|
|
|
|
description: 'Total active users on the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalDailyActiveUsers, { activeInterval: 'daily' })
|
|
|
|
observableResult.observe(stats.totalWeeklyActiveUsers, { activeInterval: 'weekly' })
|
|
|
|
observableResult.observe(stats.totalMonthlyActiveUsers, { activeInterval: 'monthly' })
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
private buildChannelStatsObserver () {
|
|
|
|
this.meter.createObservableGauge('peertube_channels_total', {
|
|
|
|
description: 'Total channels on the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalLocalVideoChannels, { channelOrigin: 'local' })
|
|
|
|
})
|
|
|
|
|
|
|
|
this.meter.createObservableGauge('peertube_active_channels_total', {
|
|
|
|
description: 'Total active channels on the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalLocalDailyActiveVideoChannels, { channelOrigin: 'local', activeInterval: 'daily' })
|
|
|
|
observableResult.observe(stats.totalLocalWeeklyActiveVideoChannels, { channelOrigin: 'local', activeInterval: 'weekly' })
|
|
|
|
observableResult.observe(stats.totalLocalMonthlyActiveVideoChannels, { channelOrigin: 'local', activeInterval: 'monthly' })
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
private buildVideoStatsObserver () {
|
|
|
|
this.meter.createObservableGauge('peertube_videos_total', {
|
|
|
|
description: 'Total videos on the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalLocalVideos, { videoOrigin: 'local' })
|
|
|
|
observableResult.observe(stats.totalVideos - stats.totalLocalVideos, { videoOrigin: 'remote' })
|
|
|
|
})
|
|
|
|
|
|
|
|
this.meter.createObservableGauge('peertube_video_views_total', {
|
|
|
|
description: 'Total video views made on the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalLocalVideoViews, { viewOrigin: 'local' })
|
|
|
|
})
|
|
|
|
|
|
|
|
this.meter.createObservableGauge('peertube_video_bytes_total', {
|
|
|
|
description: 'Total bytes of videos'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalLocalVideoFilesSize, { videoOrigin: 'local' })
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
private buildCommentStatsObserver () {
|
|
|
|
this.meter.createObservableGauge('peertube_comments_total', {
|
|
|
|
description: 'Total comments on the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalLocalVideoComments, { accountOrigin: 'local' })
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
private buildPlaylistStatsObserver () {
|
|
|
|
this.meter.createObservableGauge('peertube_playlists_total', {
|
|
|
|
description: 'Total playlists on the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalLocalPlaylists, { playlistOrigin: 'local' })
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
private buildInstanceFollowsStatsObserver () {
|
|
|
|
this.meter.createObservableGauge('peertube_instance_followers_total', {
|
|
|
|
description: 'Total followers of the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalInstanceFollowers)
|
|
|
|
})
|
|
|
|
|
|
|
|
this.meter.createObservableGauge('peertube_instance_following_total', {
|
|
|
|
description: 'Total following of the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalInstanceFollowing)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
private buildRedundancyStatsObserver () {
|
|
|
|
this.meter.createObservableGauge('peertube_redundancy_used_bytes_total', {
|
|
|
|
description: 'Total redundancy used of the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
for (const r of stats.videosRedundancy) {
|
|
|
|
observableResult.observe(r.totalUsed, { strategy: r.strategy })
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
this.meter.createObservableGauge('peertube_redundancy_available_bytes_total', {
|
|
|
|
description: 'Total redundancy available of the instance'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
for (const r of stats.videosRedundancy) {
|
|
|
|
observableResult.observe(r.totalSize, { strategy: r.strategy })
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
private buildActivityPubStatsObserver () {
|
|
|
|
const availableActivities = buildAvailableActivities()
|
|
|
|
|
|
|
|
this.meter.createObservableGauge('peertube_ap_inbox_success_total', {
|
|
|
|
description: 'Total inbox messages processed with success'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
for (const type of availableActivities) {
|
|
|
|
observableResult.observe(stats[`totalActivityPub${type}MessagesSuccesses`], { activityType: type })
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
this.meter.createObservableGauge('peertube_ap_inbox_error_total', {
|
|
|
|
description: 'Total inbox messages processed with error'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
for (const type of availableActivities) {
|
|
|
|
observableResult.observe(stats[`totalActivityPub${type}MessagesErrors`], { activityType: type })
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
this.meter.createObservableGauge('peertube_ap_inbox_waiting_total', {
|
|
|
|
description: 'Total inbox messages waiting for being processed'
|
|
|
|
}).addCallback(async observableResult => {
|
|
|
|
const stats = await this.getInstanceStats()
|
|
|
|
|
|
|
|
observableResult.observe(stats.totalActivityPubMessagesWaiting)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|