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