26
26
27
27
from prometheus_client import Gauge
28
28
29
- from synapse .metrics .background_process_metrics import wrap_as_background_process
29
+ from twisted .internet import defer
30
+
31
+ from synapse .metrics .background_process_metrics import (
32
+ run_as_background_process ,
33
+ )
30
34
from synapse .types import JsonDict
31
35
from synapse .util .constants import ONE_HOUR_SECONDS , ONE_MINUTE_SECONDS
32
36
66
70
)
67
71
68
72
69
- @wrap_as_background_process ("phone_stats_home" )
70
- async def phone_stats_home (
73
+ def phone_stats_home (
71
74
hs : "HomeServer" ,
72
75
stats : JsonDict ,
73
76
stats_process : List [Tuple [int , "resource.struct_rusage" ]] = _stats_process ,
74
- ) -> None :
75
- """Collect usage statistics and send them to the configured endpoint.
76
-
77
- Args:
78
- hs: the HomeServer object to use for gathering usage data.
79
- stats: the dict in which to store the statistics sent to the configured
80
- endpoint. Mostly used in tests to figure out the data that is supposed to
81
- be sent.
82
- stats_process: statistics about resource usage of the process.
83
- """
77
+ ) -> "defer.Deferred[None]" :
78
+ server_name = hs .hostname
79
+
80
+ async def _phone_stats_home (
81
+ hs : "HomeServer" ,
82
+ stats : JsonDict ,
83
+ stats_process : List [Tuple [int , "resource.struct_rusage" ]] = _stats_process ,
84
+ ) -> None :
85
+ """Collect usage statistics and send them to the configured endpoint.
86
+
87
+ Args:
88
+ hs: the HomeServer object to use for gathering usage data.
89
+ stats: the dict in which to store the statistics sent to the configured
90
+ endpoint. Mostly used in tests to figure out the data that is supposed to
91
+ be sent.
92
+ stats_process: statistics about resource usage of the process.
93
+ """
94
+
95
+ logger .info ("Gathering stats for reporting" )
96
+ now = int (hs .get_clock ().time ())
97
+ # Ensure the homeserver has started.
98
+ assert hs .start_time is not None
99
+ uptime = int (now - hs .start_time )
100
+ if uptime < 0 :
101
+ uptime = 0
102
+
103
+ #
104
+ # Performance statistics. Keep this early in the function to maintain reliability of `test_performance_100` test.
105
+ #
106
+ old = stats_process [0 ]
107
+ new = (now , resource .getrusage (resource .RUSAGE_SELF ))
108
+ stats_process [0 ] = new
109
+
110
+ # Get RSS in bytes
111
+ stats ["memory_rss" ] = new [1 ].ru_maxrss
112
+
113
+ # Get CPU time in % of a single core, not % of all cores
114
+ used_cpu_time = (new [1 ].ru_utime + new [1 ].ru_stime ) - (
115
+ old [1 ].ru_utime + old [1 ].ru_stime
116
+ )
117
+ if used_cpu_time == 0 or new [0 ] == old [0 ]:
118
+ stats ["cpu_average" ] = 0
119
+ else :
120
+ stats ["cpu_average" ] = math .floor (used_cpu_time / (new [0 ] - old [0 ]) * 100 )
84
121
85
- logger .info ("Gathering stats for reporting" )
86
- now = int (hs .get_clock ().time ())
87
- # Ensure the homeserver has started.
88
- assert hs .start_time is not None
89
- uptime = int (now - hs .start_time )
90
- if uptime < 0 :
91
- uptime = 0
92
-
93
- #
94
- # Performance statistics. Keep this early in the function to maintain reliability of `test_performance_100` test.
95
- #
96
- old = stats_process [0 ]
97
- new = (now , resource .getrusage (resource .RUSAGE_SELF ))
98
- stats_process [0 ] = new
99
-
100
- # Get RSS in bytes
101
- stats ["memory_rss" ] = new [1 ].ru_maxrss
102
-
103
- # Get CPU time in % of a single core, not % of all cores
104
- used_cpu_time = (new [1 ].ru_utime + new [1 ].ru_stime ) - (
105
- old [1 ].ru_utime + old [1 ].ru_stime
106
- )
107
- if used_cpu_time == 0 or new [0 ] == old [0 ]:
108
- stats ["cpu_average" ] = 0
109
- else :
110
- stats ["cpu_average" ] = math .floor (used_cpu_time / (new [0 ] - old [0 ]) * 100 )
111
-
112
- #
113
- # General statistics
114
- #
115
-
116
- store = hs .get_datastores ().main
117
- common_metrics = await hs .get_common_usage_metrics_manager ().get_metrics ()
118
-
119
- stats ["homeserver" ] = hs .config .server .server_name
120
- stats ["server_context" ] = hs .config .server .server_context
121
- stats ["timestamp" ] = now
122
- stats ["uptime_seconds" ] = uptime
123
- version = sys .version_info
124
- stats ["python_version" ] = "{}.{}.{}" .format (
125
- version .major , version .minor , version .micro
126
- )
127
- stats ["total_users" ] = await store .count_all_users ()
128
-
129
- total_nonbridged_users = await store .count_nonbridged_users ()
130
- stats ["total_nonbridged_users" ] = total_nonbridged_users
131
-
132
- daily_user_type_results = await store .count_daily_user_type ()
133
- for name , count in daily_user_type_results .items ():
134
- stats ["daily_user_type_" + name ] = count
135
-
136
- room_count = await store .get_room_count ()
137
- stats ["total_room_count" ] = room_count
138
-
139
- stats ["daily_active_users" ] = common_metrics .daily_active_users
140
- stats ["monthly_active_users" ] = await store .count_monthly_users ()
141
- daily_active_e2ee_rooms = await store .count_daily_active_e2ee_rooms ()
142
- stats ["daily_active_e2ee_rooms" ] = daily_active_e2ee_rooms
143
- stats ["daily_e2ee_messages" ] = await store .count_daily_e2ee_messages ()
144
- daily_sent_e2ee_messages = await store .count_daily_sent_e2ee_messages ()
145
- stats ["daily_sent_e2ee_messages" ] = daily_sent_e2ee_messages
146
- stats ["daily_active_rooms" ] = await store .count_daily_active_rooms ()
147
- stats ["daily_messages" ] = await store .count_daily_messages ()
148
- daily_sent_messages = await store .count_daily_sent_messages ()
149
- stats ["daily_sent_messages" ] = daily_sent_messages
150
-
151
- r30v2_results = await store .count_r30v2_users ()
152
- for name , count in r30v2_results .items ():
153
- stats ["r30v2_users_" + name ] = count
154
-
155
- stats ["cache_factor" ] = hs .config .caches .global_factor
156
- stats ["event_cache_size" ] = hs .config .caches .event_cache_size
157
-
158
- #
159
- # Database version
160
- #
161
-
162
- # This only reports info about the *main* database.
163
- stats ["database_engine" ] = store .db_pool .engine .module .__name__
164
- stats ["database_server_version" ] = store .db_pool .engine .server_version
165
-
166
- #
167
- # Logging configuration
168
- #
169
- synapse_logger = logging .getLogger ("synapse" )
170
- log_level = synapse_logger .getEffectiveLevel ()
171
- stats ["log_level" ] = logging .getLevelName (log_level )
172
-
173
- logger .info (
174
- "Reporting stats to %s: %s" , hs .config .metrics .report_stats_endpoint , stats
175
- )
176
- try :
177
- await hs .get_proxied_http_client ().put_json (
178
- hs .config .metrics .report_stats_endpoint , stats
122
+ #
123
+ # General statistics
124
+ #
125
+
126
+ store = hs .get_datastores ().main
127
+ common_metrics = await hs .get_common_usage_metrics_manager ().get_metrics ()
128
+
129
+ stats ["homeserver" ] = hs .config .server .server_name
130
+ stats ["server_context" ] = hs .config .server .server_context
131
+ stats ["timestamp" ] = now
132
+ stats ["uptime_seconds" ] = uptime
133
+ version = sys .version_info
134
+ stats ["python_version" ] = "{}.{}.{}" .format (
135
+ version .major , version .minor , version .micro
179
136
)
180
- except Exception as e :
181
- logger .warning ("Error reporting stats: %s" , e )
137
+ stats ["total_users" ] = await store .count_all_users ()
138
+
139
+ total_nonbridged_users = await store .count_nonbridged_users ()
140
+ stats ["total_nonbridged_users" ] = total_nonbridged_users
141
+
142
+ daily_user_type_results = await store .count_daily_user_type ()
143
+ for name , count in daily_user_type_results .items ():
144
+ stats ["daily_user_type_" + name ] = count
145
+
146
+ room_count = await store .get_room_count ()
147
+ stats ["total_room_count" ] = room_count
148
+
149
+ stats ["daily_active_users" ] = common_metrics .daily_active_users
150
+ stats ["monthly_active_users" ] = await store .count_monthly_users ()
151
+ daily_active_e2ee_rooms = await store .count_daily_active_e2ee_rooms ()
152
+ stats ["daily_active_e2ee_rooms" ] = daily_active_e2ee_rooms
153
+ stats ["daily_e2ee_messages" ] = await store .count_daily_e2ee_messages ()
154
+ daily_sent_e2ee_messages = await store .count_daily_sent_e2ee_messages ()
155
+ stats ["daily_sent_e2ee_messages" ] = daily_sent_e2ee_messages
156
+ stats ["daily_active_rooms" ] = await store .count_daily_active_rooms ()
157
+ stats ["daily_messages" ] = await store .count_daily_messages ()
158
+ daily_sent_messages = await store .count_daily_sent_messages ()
159
+ stats ["daily_sent_messages" ] = daily_sent_messages
160
+
161
+ r30v2_results = await store .count_r30v2_users ()
162
+ for name , count in r30v2_results .items ():
163
+ stats ["r30v2_users_" + name ] = count
164
+
165
+ stats ["cache_factor" ] = hs .config .caches .global_factor
166
+ stats ["event_cache_size" ] = hs .config .caches .event_cache_size
167
+
168
+ #
169
+ # Database version
170
+ #
171
+
172
+ # This only reports info about the *main* database.
173
+ stats ["database_engine" ] = store .db_pool .engine .module .__name__
174
+ stats ["database_server_version" ] = store .db_pool .engine .server_version
175
+
176
+ #
177
+ # Logging configuration
178
+ #
179
+ synapse_logger = logging .getLogger ("synapse" )
180
+ log_level = synapse_logger .getEffectiveLevel ()
181
+ stats ["log_level" ] = logging .getLevelName (log_level )
182
+
183
+ logger .info (
184
+ "Reporting stats to %s: %s" , hs .config .metrics .report_stats_endpoint , stats
185
+ )
186
+ try :
187
+ await hs .get_proxied_http_client ().put_json (
188
+ hs .config .metrics .report_stats_endpoint , stats
189
+ )
190
+ except Exception as e :
191
+ logger .warning ("Error reporting stats: %s" , e )
192
+
193
+ return run_as_background_process (
194
+ "phone_stats_home" , server_name , _phone_stats_home , hs , stats , stats_process
195
+ )
182
196
183
197
184
198
def start_phone_stats_home (hs : "HomeServer" ) -> None :
185
199
"""
186
200
Start the background tasks which report phone home stats.
187
201
"""
202
+ server_name = hs .hostname
188
203
clock = hs .get_clock ()
189
204
190
205
stats : JsonDict = {}
@@ -210,25 +225,31 @@ def performance_stats_init() -> None:
210
225
)
211
226
hs .get_datastores ().main .reap_monthly_active_users ()
212
227
213
- @wrap_as_background_process ("generate_monthly_active_users" )
214
- async def generate_monthly_active_users () -> None :
215
- current_mau_count = 0
216
- current_mau_count_by_service : Mapping [str , int ] = {}
217
- reserved_users : Sized = ()
218
- store = hs .get_datastores ().main
219
- if hs .config .server .limit_usage_by_mau or hs .config .server .mau_stats_only :
220
- current_mau_count = await store .get_monthly_active_count ()
221
- current_mau_count_by_service = (
222
- await store .get_monthly_active_count_by_service ()
223
- )
224
- reserved_users = await store .get_registered_reserved_users ()
225
- current_mau_gauge .set (float (current_mau_count ))
226
-
227
- for app_service , count in current_mau_count_by_service .items ():
228
- current_mau_by_service_gauge .labels (app_service ).set (float (count ))
229
-
230
- registered_reserved_users_mau_gauge .set (float (len (reserved_users )))
231
- max_mau_gauge .set (float (hs .config .server .max_mau_value ))
228
+ def generate_monthly_active_users () -> "defer.Deferred[None]" :
229
+ async def _generate_monthly_active_users () -> None :
230
+ current_mau_count = 0
231
+ current_mau_count_by_service : Mapping [str , int ] = {}
232
+ reserved_users : Sized = ()
233
+ store = hs .get_datastores ().main
234
+ if hs .config .server .limit_usage_by_mau or hs .config .server .mau_stats_only :
235
+ current_mau_count = await store .get_monthly_active_count ()
236
+ current_mau_count_by_service = (
237
+ await store .get_monthly_active_count_by_service ()
238
+ )
239
+ reserved_users = await store .get_registered_reserved_users ()
240
+ current_mau_gauge .set (float (current_mau_count ))
241
+
242
+ for app_service , count in current_mau_count_by_service .items ():
243
+ current_mau_by_service_gauge .labels (app_service ).set (float (count ))
244
+
245
+ registered_reserved_users_mau_gauge .set (float (len (reserved_users )))
246
+ max_mau_gauge .set (float (hs .config .server .max_mau_value ))
247
+
248
+ return run_as_background_process (
249
+ "generate_monthly_active_users" ,
250
+ server_name ,
251
+ _generate_monthly_active_users ,
252
+ )
232
253
233
254
if hs .config .server .limit_usage_by_mau or hs .config .server .mau_stats_only :
234
255
generate_monthly_active_users ()
0 commit comments