]>
Commit | Line | Data |
---|---|---|
99afa081 C |
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' | |
fe19f600 | 6 | import { VideoChannelModel } from '@server/models/video/video-channel' |
99afa081 C |
7 | import { VideoCommentModel } from '@server/models/video/video-comment' |
8 | import { VideoFileModel } from '@server/models/video/video-file' | |
fe19f600 | 9 | import { VideoPlaylistModel } from '@server/models/video/video-playlist' |
543442a3 | 10 | import { ActivityType, ServerStats, VideoRedundancyStrategyWithManual } from '@shared/models' |
99afa081 C |
11 | |
12 | class StatsManager { | |
13 | ||
14 | private static instance: StatsManager | |
15 | ||
16 | private readonly instanceStartDate = new Date() | |
17 | ||
543442a3 C |
18 | private inboxMessages = { |
19 | processed: 0, | |
20 | errors: 0, | |
21 | successes: 0, | |
22 | waiting: 0, | |
23 | errorsPerType: this.buildAPPerType(), | |
24 | successesPerType: this.buildAPPerType() | |
25 | } | |
99afa081 C |
26 | |
27 | private constructor () {} | |
28 | ||
543442a3 C |
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]++ | |
99afa081 C |
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() | |
fe19f600 RK |
51 | const { |
52 | totalLocalVideoChannels, | |
53 | totalLocalDailyActiveVideoChannels, | |
54 | totalLocalWeeklyActiveVideoChannels, | |
55 | totalLocalMonthlyActiveVideoChannels | |
56 | } = await VideoChannelModel.getStats() | |
57 | const { totalLocalPlaylists } = await VideoPlaylistModel.getStats() | |
99afa081 C |
58 | |
59 | const videosRedundancyStats = await this.buildRedundancyStats() | |
60 | ||
61 | const data: ServerStats = { | |
fe19f600 RK |
62 | totalUsers, |
63 | totalDailyActiveUsers, | |
64 | totalWeeklyActiveUsers, | |
65 | totalMonthlyActiveUsers, | |
66 | ||
99afa081 C |
67 | totalLocalVideos, |
68 | totalLocalVideoViews, | |
99afa081 | 69 | totalLocalVideoComments, |
fe19f600 RK |
70 | totalLocalVideoFilesSize, |
71 | ||
99afa081 C |
72 | totalVideos, |
73 | totalVideoComments, | |
74 | ||
fe19f600 RK |
75 | totalLocalVideoChannels, |
76 | totalLocalDailyActiveVideoChannels, | |
77 | totalLocalWeeklyActiveVideoChannels, | |
78 | totalLocalMonthlyActiveVideoChannels, | |
79 | ||
80 | totalLocalPlaylists, | |
99afa081 C |
81 | |
82 | totalInstanceFollowers, | |
83 | totalInstanceFollowing, | |
84 | ||
85 | videosRedundancy: videosRedundancyStats, | |
86 | ||
543442a3 | 87 | ...this.buildAPStats() |
99afa081 C |
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 | ||
543442a3 | 97 | return this.inboxMessages.processed / startedSeconds |
99afa081 C |
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 | ||
543442a3 C |
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 | ||
99afa081 C |
174 | static get Instance () { |
175 | return this.instance || (this.instance = new this()) | |
176 | } | |
177 | } | |
178 | ||
179 | // --------------------------------------------------------------------------- | |
180 | ||
181 | export { | |
182 | StatsManager | |
183 | } |