]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/lib/stat-manager.ts
add channel and playlist stats to server stats endpoint (#3747)
[github/Chocobozzz/PeerTube.git] / server / lib / stat-manager.ts
1 import { CONFIG } from '@server/initializers/config'
2 import { UserModel } from '@server/models/account/user'
3 import { ActorFollowModel } from '@server/models/activitypub/actor-follow'
4 import { VideoRedundancyModel } from '@server/models/redundancy/video-redundancy'
5 import { VideoModel } from '@server/models/video/video'
6 import { VideoChannelModel } from '@server/models/video/video-channel'
7 import { VideoCommentModel } from '@server/models/video/video-comment'
8 import { VideoFileModel } from '@server/models/video/video-file'
9 import { VideoPlaylistModel } from '@server/models/video/video-playlist'
10 import { ActivityType, ServerStats, VideoRedundancyStrategyWithManual } from '@shared/models'
11
12 class StatsManager {
13
14 private static instance: StatsManager
15
16 private readonly instanceStartDate = new Date()
17
18 private inboxMessages = {
19 processed: 0,
20 errors: 0,
21 successes: 0,
22 waiting: 0,
23 errorsPerType: this.buildAPPerType(),
24 successesPerType: this.buildAPPerType()
25 }
26
27 private constructor () {}
28
29 updateInboxWaiting (inboxMessagesWaiting: number) {
30 this.inboxMessages.waiting = inboxMessagesWaiting
31 }
32
33 addInboxProcessedSuccess (type: ActivityType) {
34 this.inboxMessages.processed++
35 this.inboxMessages.successes++
36 this.inboxMessages.successesPerType[type]++
37 }
38
39 addInboxProcessedError (type: ActivityType) {
40 this.inboxMessages.processed++
41 this.inboxMessages.errors++
42 this.inboxMessages.errorsPerType[type]++
43 }
44
45 async getStats () {
46 const { totalLocalVideos, totalLocalVideoViews, totalVideos } = await VideoModel.getStats()
47 const { totalLocalVideoComments, totalVideoComments } = await VideoCommentModel.getStats()
48 const { totalUsers, totalDailyActiveUsers, totalWeeklyActiveUsers, totalMonthlyActiveUsers } = await UserModel.getStats()
49 const { totalInstanceFollowers, totalInstanceFollowing } = await ActorFollowModel.getStats()
50 const { totalLocalVideoFilesSize } = await VideoFileModel.getStats()
51 const {
52 totalLocalVideoChannels,
53 totalLocalDailyActiveVideoChannels,
54 totalLocalWeeklyActiveVideoChannels,
55 totalLocalMonthlyActiveVideoChannels
56 } = await VideoChannelModel.getStats()
57 const { totalLocalPlaylists } = await VideoPlaylistModel.getStats()
58
59 const videosRedundancyStats = await this.buildRedundancyStats()
60
61 const data: ServerStats = {
62 totalUsers,
63 totalDailyActiveUsers,
64 totalWeeklyActiveUsers,
65 totalMonthlyActiveUsers,
66
67 totalLocalVideos,
68 totalLocalVideoViews,
69 totalLocalVideoComments,
70 totalLocalVideoFilesSize,
71
72 totalVideos,
73 totalVideoComments,
74
75 totalLocalVideoChannels,
76 totalLocalDailyActiveVideoChannels,
77 totalLocalWeeklyActiveVideoChannels,
78 totalLocalMonthlyActiveVideoChannels,
79
80 totalLocalPlaylists,
81
82 totalInstanceFollowers,
83 totalInstanceFollowing,
84
85 videosRedundancy: videosRedundancyStats,
86
87 ...this.buildAPStats()
88 }
89
90 return data
91 }
92
93 private buildActivityPubMessagesProcessedPerSecond () {
94 const now = new Date()
95 const startedSeconds = (now.getTime() - this.instanceStartDate.getTime()) / 1000
96
97 return this.inboxMessages.processed / startedSeconds
98 }
99
100 private buildRedundancyStats () {
101 const strategies = CONFIG.REDUNDANCY.VIDEOS.STRATEGIES
102 .map(r => ({
103 strategy: r.strategy as VideoRedundancyStrategyWithManual,
104 size: r.size
105 }))
106
107 strategies.push({ strategy: 'manual', size: null })
108
109 return Promise.all(
110 strategies.map(r => {
111 return VideoRedundancyModel.getStats(r.strategy)
112 .then(stats => Object.assign(stats, { strategy: r.strategy, totalSize: r.size }))
113 })
114 )
115 }
116
117 private buildAPPerType () {
118 return {
119 Create: 0,
120 Update: 0,
121 Delete: 0,
122 Follow: 0,
123 Accept: 0,
124 Reject: 0,
125 Announce: 0,
126 Undo: 0,
127 Like: 0,
128 Dislike: 0,
129 Flag: 0,
130 View: 0
131 }
132 }
133
134 private buildAPStats () {
135 return {
136 totalActivityPubMessagesProcessed: this.inboxMessages.processed,
137
138 totalActivityPubMessagesSuccesses: this.inboxMessages.successes,
139
140 // Dirty, but simpler and with type checking
141 totalActivityPubCreateMessagesSuccesses: this.inboxMessages.successesPerType.Create,
142 totalActivityPubUpdateMessagesSuccesses: this.inboxMessages.successesPerType.Update,
143 totalActivityPubDeleteMessagesSuccesses: this.inboxMessages.successesPerType.Delete,
144 totalActivityPubFollowMessagesSuccesses: this.inboxMessages.successesPerType.Follow,
145 totalActivityPubAcceptMessagesSuccesses: this.inboxMessages.successesPerType.Accept,
146 totalActivityPubRejectMessagesSuccesses: this.inboxMessages.successesPerType.Reject,
147 totalActivityPubAnnounceMessagesSuccesses: this.inboxMessages.successesPerType.Announce,
148 totalActivityPubUndoMessagesSuccesses: this.inboxMessages.successesPerType.Undo,
149 totalActivityPubLikeMessagesSuccesses: this.inboxMessages.successesPerType.Like,
150 totalActivityPubDislikeMessagesSuccesses: this.inboxMessages.successesPerType.Dislike,
151 totalActivityPubFlagMessagesSuccesses: this.inboxMessages.successesPerType.Flag,
152 totalActivityPubViewMessagesSuccesses: this.inboxMessages.successesPerType.View,
153
154 totalActivityPubCreateMessagesErrors: this.inboxMessages.errorsPerType.Create,
155 totalActivityPubUpdateMessagesErrors: this.inboxMessages.errorsPerType.Update,
156 totalActivityPubDeleteMessagesErrors: this.inboxMessages.errorsPerType.Delete,
157 totalActivityPubFollowMessagesErrors: this.inboxMessages.errorsPerType.Follow,
158 totalActivityPubAcceptMessagesErrors: this.inboxMessages.errorsPerType.Accept,
159 totalActivityPubRejectMessagesErrors: this.inboxMessages.errorsPerType.Reject,
160 totalActivityPubAnnounceMessagesErrors: this.inboxMessages.errorsPerType.Announce,
161 totalActivityPubUndoMessagesErrors: this.inboxMessages.errorsPerType.Undo,
162 totalActivityPubLikeMessagesErrors: this.inboxMessages.errorsPerType.Like,
163 totalActivityPubDislikeMessagesErrors: this.inboxMessages.errorsPerType.Dislike,
164 totalActivityPubFlagMessagesErrors: this.inboxMessages.errorsPerType.Flag,
165 totalActivityPubViewMessagesErrors: this.inboxMessages.errorsPerType.View,
166
167 totalActivityPubMessagesErrors: this.inboxMessages.errors,
168
169 activityPubMessagesProcessedPerSecond: this.buildActivityPubMessagesProcessedPerSecond(),
170 totalActivityPubMessagesWaiting: this.inboxMessages.waiting
171 }
172 }
173
174 static get Instance () {
175 return this.instance || (this.instance = new this())
176 }
177 }
178
179 // ---------------------------------------------------------------------------
180
181 export {
182 StatsManager
183 }