aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2020-12-15 13:34:58 +0100
committerChocobozzz <me@florianbigard.com>2020-12-15 13:34:58 +0100
commit99afa081bc6ae7f34b2105075bd43e3625434fa8 (patch)
tree0caea8591b3d3688a133cf33edcad616bf276375 /server/lib
parent48586fe070c2a59e9febb62a7f41ebb384e1d20e (diff)
downloadPeerTube-99afa081bc6ae7f34b2105075bd43e3625434fa8.tar.gz
PeerTube-99afa081bc6ae7f34b2105075bd43e3625434fa8.tar.zst
PeerTube-99afa081bc6ae7f34b2105075bd43e3625434fa8.zip
Add AP stats
Diffstat (limited to 'server/lib')
-rw-r--r--server/lib/activitypub/inbox-manager.ts55
-rw-r--r--server/lib/stat-manager.ts94
2 files changed, 149 insertions, 0 deletions
diff --git a/server/lib/activitypub/inbox-manager.ts b/server/lib/activitypub/inbox-manager.ts
new file mode 100644
index 000000000..19e112f91
--- /dev/null
+++ b/server/lib/activitypub/inbox-manager.ts
@@ -0,0 +1,55 @@
1import { AsyncQueue, queue } from 'async'
2import { logger } from '@server/helpers/logger'
3import { SCHEDULER_INTERVALS_MS } from '@server/initializers/constants'
4import { MActorDefault, MActorSignature } from '@server/types/models'
5import { Activity } from '@shared/models'
6import { processActivities } from './process'
7import { StatsManager } from '../stat-manager'
8
9type QueueParam = {
10 activities: Activity[]
11 signatureActor?: MActorSignature
12 inboxActor?: MActorDefault
13}
14
15class InboxManager {
16
17 private static instance: InboxManager
18
19 private readonly inboxQueue: AsyncQueue<QueueParam>
20
21 private messagesProcessed = 0
22
23 private constructor () {
24 this.inboxQueue = queue<QueueParam, Error>((task, cb) => {
25 const options = { signatureActor: task.signatureActor, inboxActor: task.inboxActor }
26
27 this.messagesProcessed++
28
29 processActivities(task.activities, options)
30 .then(() => cb())
31 .catch(err => {
32 logger.error('Error in process activities.', { err })
33 cb()
34 })
35 })
36
37 setInterval(() => {
38 StatsManager.Instance.updateInboxStats(this.messagesProcessed, this.inboxQueue.length())
39 }, SCHEDULER_INTERVALS_MS.updateInboxStats)
40 }
41
42 addInboxMessage (options: QueueParam) {
43 this.inboxQueue.push(options)
44 }
45
46 static get Instance () {
47 return this.instance || (this.instance = new this())
48 }
49}
50
51// ---------------------------------------------------------------------------
52
53export {
54 InboxManager
55}
diff --git a/server/lib/stat-manager.ts b/server/lib/stat-manager.ts
new file mode 100644
index 000000000..f9d69b0dc
--- /dev/null
+++ b/server/lib/stat-manager.ts
@@ -0,0 +1,94 @@
1import { CONFIG } from '@server/initializers/config'
2import { UserModel } from '@server/models/account/user'
3import { ActorFollowModel } from '@server/models/activitypub/actor-follow'
4import { VideoRedundancyModel } from '@server/models/redundancy/video-redundancy'
5import { VideoModel } from '@server/models/video/video'
6import { VideoCommentModel } from '@server/models/video/video-comment'
7import { VideoFileModel } from '@server/models/video/video-file'
8import { ServerStats, VideoRedundancyStrategyWithManual } from '@shared/models'
9
10class StatsManager {
11
12 private static instance: StatsManager
13
14 private readonly instanceStartDate = new Date()
15
16 private inboxMessagesProcessed = 0
17 private inboxMessagesWaiting = 0
18
19 private constructor () {}
20
21 updateInboxStats (inboxMessagesProcessed: number, inboxMessagesWaiting: number) {
22 this.inboxMessagesProcessed = inboxMessagesProcessed
23 this.inboxMessagesWaiting = inboxMessagesWaiting
24 }
25
26 async getStats () {
27 const { totalLocalVideos, totalLocalVideoViews, totalVideos } = await VideoModel.getStats()
28 const { totalLocalVideoComments, totalVideoComments } = await VideoCommentModel.getStats()
29 const { totalUsers, totalDailyActiveUsers, totalWeeklyActiveUsers, totalMonthlyActiveUsers } = await UserModel.getStats()
30 const { totalInstanceFollowers, totalInstanceFollowing } = await ActorFollowModel.getStats()
31 const { totalLocalVideoFilesSize } = await VideoFileModel.getStats()
32
33 const videosRedundancyStats = await this.buildRedundancyStats()
34
35 const data: ServerStats = {
36 totalLocalVideos,
37 totalLocalVideoViews,
38 totalLocalVideoFilesSize,
39 totalLocalVideoComments,
40 totalVideos,
41 totalVideoComments,
42
43 totalUsers,
44 totalDailyActiveUsers,
45 totalWeeklyActiveUsers,
46 totalMonthlyActiveUsers,
47
48 totalInstanceFollowers,
49 totalInstanceFollowing,
50
51 videosRedundancy: videosRedundancyStats,
52
53 totalActivityPubMessagesProcessed: this.inboxMessagesProcessed,
54 activityPubMessagesProcessedPerSecond: this.buildActivityPubMessagesProcessedPerSecond(),
55 totalActivityPubMessagesWaiting: this.inboxMessagesWaiting
56 }
57
58 return data
59 }
60
61 private buildActivityPubMessagesProcessedPerSecond () {
62 const now = new Date()
63 const startedSeconds = (now.getTime() - this.instanceStartDate.getTime()) / 1000
64
65 return this.inboxMessagesProcessed / startedSeconds
66 }
67
68 private buildRedundancyStats () {
69 const strategies = CONFIG.REDUNDANCY.VIDEOS.STRATEGIES
70 .map(r => ({
71 strategy: r.strategy as VideoRedundancyStrategyWithManual,
72 size: r.size
73 }))
74
75 strategies.push({ strategy: 'manual', size: null })
76
77 return Promise.all(
78 strategies.map(r => {
79 return VideoRedundancyModel.getStats(r.strategy)
80 .then(stats => Object.assign(stats, { strategy: r.strategy, totalSize: r.size }))
81 })
82 )
83 }
84
85 static get Instance () {
86 return this.instance || (this.instance = new this())
87 }
88}
89
90// ---------------------------------------------------------------------------
91
92export {
93 StatsManager
94}