aboutsummaryrefslogtreecommitdiff
path: root/pkg/api/api0/metrics.go
blob: d9fa16d29a420419422bfaf633257895eaf3f730 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
package api0

import (
	"fmt"
	"io"
	"reflect"

	"github.com/VictoriaMetrics/metrics"
)

// note: for results, fail_ prefix is for errors which are likely a problem with the backend, and reject_ are for client errors

type apiMetrics struct {
	set                      *metrics.Set
	request_panics_total     *metrics.Counter
	versiongate_checks_total struct {
		success_ok     *metrics.Counter
		success_dev    *metrics.Counter
		reject_old     *metrics.Counter
		reject_invalid *metrics.Counter
		reject_notns   *metrics.Counter
	}
	accounts_writepersistence_extradata_size_bytes *metrics.Histogram // only includes successful updates
	accounts_writepersistence_stored_size_bytes    *metrics.Histogram
	accounts_writepersistence_requests_total       struct {
		success                    *metrics.Counter
		reject_too_much_extradata  *metrics.Counter
		reject_too_large           *metrics.Counter
		reject_invalid_pdata       *metrics.Counter
		reject_bad_request         *metrics.Counter
		reject_player_not_found    *metrics.Counter
		reject_unauthorized        *metrics.Counter
		fail_storage_error_account *metrics.Counter
		fail_storage_error_pdata   *metrics.Counter
		fail_other_error           *metrics.Counter
		http_method_not_allowed    *metrics.Counter
	}
	accounts_lookupuid_requests_total struct {
		success_singlematch        *metrics.Counter
		success_multimatch         *metrics.Counter
		success_nomatch            *metrics.Counter
		reject_bad_request         *metrics.Counter
		fail_storage_error_account *metrics.Counter
		http_method_not_allowed    *metrics.Counter
	}
	accounts_getusername_requests_total struct {
		success_match              *metrics.Counter
		success_missing            *metrics.Counter
		reject_bad_request         *metrics.Counter
		reject_player_not_found    *metrics.Counter
		fail_storage_error_account *metrics.Counter
		http_method_not_allowed    *metrics.Counter
	}
	client_mainmenupromos_requests_total struct {
		success                 func(version string) *metrics.Counter
		http_method_not_allowed *metrics.Counter
	}
	client_originauth_requests_total struct {
		success                     *metrics.Counter
		reject_bad_request          *metrics.Counter
		reject_versiongate          *metrics.Counter
		reject_stryder_invalidgame  *metrics.Counter
		reject_stryder_invalidtoken *metrics.Counter
		reject_stryder_mpnotallowed *metrics.Counter
		reject_stryder_other        *metrics.Counter
		fail_storage_error_account  *metrics.Counter
		fail_stryder_error          *metrics.Counter
		fail_other_error            *metrics.Counter
		http_method_not_allowed     *metrics.Counter
	}
	client_originauth_stryder_auth_duration_seconds           *metrics.Histogram
	client_originauth_origin_username_lookup_duration_seconds *metrics.Histogram
	client_originauth_origin_username_lookup_calls_total      struct {
		success              *metrics.Counter
		notfound             *metrics.Counter
		fail_authtok_refresh *metrics.Counter
		fail_other_error     *metrics.Counter
	}
	client_authwithserver_requests_total struct {
		success                    *metrics.Counter
		reject_bad_request         *metrics.Counter
		reject_versiongate         *metrics.Counter
		reject_player_not_found    *metrics.Counter
		reject_masterserver_token  *metrics.Counter
		reject_password            *metrics.Counter
		reject_gameserverauth      *metrics.Counter
		fail_gameserverauth        *metrics.Counter
		fail_storage_error_account *metrics.Counter
		fail_storage_error_pdata   *metrics.Counter
		fail_other_error           *metrics.Counter
		http_method_not_allowed    *metrics.Counter
	}
	client_authwithserver_gameserverauth_duration_seconds *metrics.Histogram
	client_authwithself_requests_total                    struct {
		success                    *metrics.Counter
		reject_bad_request         *metrics.Counter
		reject_versiongate         *metrics.Counter
		reject_player_not_found    *metrics.Counter
		reject_masterserver_token  *metrics.Counter
		fail_storage_error_account *metrics.Counter
		fail_storage_error_pdata   *metrics.Counter
		fail_other_error           *metrics.Counter
		http_method_not_allowed    *metrics.Counter
	}
	client_servers_requests_total struct {
		success                 func(version string) *metrics.Counter
		http_method_not_allowed *metrics.Counter
	}
	client_servers_response_size_bytes struct {
		gzip *metrics.Histogram
		none *metrics.Histogram
	}
	server_upsert_requests_total struct {
		success_updated            func(action string) *metrics.Counter
		success_verified           func(action string) *metrics.Counter
		reject_versiongate         func(action string) *metrics.Counter
		reject_ipv6                func(action string) *metrics.Counter
		reject_bad_request         func(action string) *metrics.Counter
		reject_unauthorized_ip     func(action string) *metrics.Counter
		reject_server_not_found    func(action string) *metrics.Counter
		reject_duplicate_auth_addr func(action string) *metrics.Counter
		reject_limits_exceeded     func(action string) *metrics.Counter
		reject_verify_authtimeout  func(action string) *metrics.Counter
		reject_verify_authresp     func(action string) *metrics.Counter
		reject_verify_autherr      func(action string) *metrics.Counter
		reject_verify_udptimeout   func(action string) *metrics.Counter
		reject_verify_udperr       func(action string) *metrics.Counter
		fail_other_error           func(action string) *metrics.Counter
		fail_serverlist_error      func(action string) *metrics.Counter
		http_method_not_allowed    func(action string) *metrics.Counter
	}
	server_upsert_modinfo_parse_errors_total func(action string) *metrics.Counter
	server_upsert_verify_time_seconds        struct {
		success *metrics.Histogram
		failure *metrics.Histogram
	}
	server_remove_requests_total struct {
		success                 *metrics.Counter
		reject_unauthorized_ip  *metrics.Counter
		reject_bad_request      *metrics.Counter
		reject_server_not_found *metrics.Counter
		fail_other_error        *metrics.Counter
		http_method_not_allowed *metrics.Counter
	}
	player_pdata_requests_total struct {
		success                  func(filter string) *metrics.Counter
		reject_bad_request       *metrics.Counter
		reject_player_not_found  *metrics.Counter
		fail_storage_error_pdata *metrics.Counter
		fail_pdata_invalid       *metrics.Counter
		fail_other_error         *metrics.Counter
		http_method_not_allowed  *metrics.Counter
	}
}

func (h *Handler) Metrics() *metrics.Set {
	return h.m().set
}

func (h *Handler) WritePrometheus(w io.Writer) {
	h.m().set.WritePrometheus(w)
}

// m gets metrics objects for h.
//
// We use it instead of using a *metrics.Set directly because:
//   - It means we don't need to keep checking if a set is nil.
//   - It means we don't have the overhead of checking/creating each individual metric during requests.
//   - It makes typos less likely.
//   - It means that metrics still get included in the output instead of being undefined even if they start at zero.
func (h *Handler) m() *apiMetrics {
	h.metricsInit.Do(func() {
		mo := &h.metricsObj
		mo.set = metrics.NewSet()
		mo.request_panics_total = mo.set.NewCounter(`atlas_api0_request_panics_total`)
		mo.versiongate_checks_total.success_ok = mo.set.NewCounter(`atlas_api0_versiongate_checks_total{result="success_ok"}`)
		mo.versiongate_checks_total.success_dev = mo.set.NewCounter(`atlas_api0_versiongate_checks_total{result="success_dev"}`)
		mo.versiongate_checks_total.reject_old = mo.set.NewCounter(`atlas_api0_versiongate_checks_total{result="reject_old"}`)
		mo.versiongate_checks_total.reject_invalid = mo.set.NewCounter(`atlas_api0_versiongate_checks_total{result="reject_invalid"}`)
		mo.versiongate_checks_total.reject_notns = mo.set.NewCounter(`atlas_api0_versiongate_checks_total{result="reject_notns"}`)
		mo.accounts_writepersistence_extradata_size_bytes = mo.set.NewHistogram(`atlas_api0_accounts_writepersistence_extradata_size_bytes`)
		mo.accounts_writepersistence_stored_size_bytes = mo.set.NewHistogram(`atlas_api0_accounts_writepersistence_stored_size_bytes`)
		mo.accounts_writepersistence_requests_total.success = mo.set.NewCounter(`atlas_api0_accounts_writepersistence_requests_total{result="success"}`)
		mo.accounts_writepersistence_requests_total.reject_too_much_extradata = mo.set.NewCounter(`atlas_api0_accounts_writepersistence_requests_total{result="reject_too_much_extradata"}`)
		mo.accounts_writepersistence_requests_total.reject_too_large = mo.set.NewCounter(`atlas_api0_accounts_writepersistence_requests_total{result="reject_too_large"}`)
		mo.accounts_writepersistence_requests_total.reject_invalid_pdata = mo.set.NewCounter(`atlas_api0_accounts_writepersistence_requests_total{result="reject_invalid_pdata"}`)
		mo.accounts_writepersistence_requests_total.reject_bad_request = mo.set.NewCounter(`atlas_api0_accounts_writepersistence_requests_total{result="reject_bad_request"}`)
		mo.accounts_writepersistence_requests_total.reject_player_not_found = mo.set.NewCounter(`atlas_api0_accounts_writepersistence_requests_total{result="reject_player_not_found"}`)
		mo.accounts_writepersistence_requests_total.reject_unauthorized = mo.set.NewCounter(`atlas_api0_accounts_writepersistence_requests_total{result="reject_unauthorized"}`)
		mo.accounts_writepersistence_requests_total.fail_storage_error_account = mo.set.NewCounter(`atlas_api0_accounts_writepersistence_requests_total{result="fail_storage_error_account"}`)
		mo.accounts_writepersistence_requests_total.fail_storage_error_pdata = mo.set.NewCounter(`atlas_api0_accounts_writepersistence_requests_total{result="fail_storage_error_pdata"}`)
		mo.accounts_writepersistence_requests_total.fail_other_error = mo.set.NewCounter(`atlas_api0_accounts_writepersistence_requests_total{result="fail_other_error"}`)
		mo.accounts_writepersistence_requests_total.http_method_not_allowed = mo.set.NewCounter(`atlas_api0_accounts_writepersistence_requests_total{result="http_method_not_allowed"}`)
		mo.accounts_lookupuid_requests_total.success_singlematch = mo.set.NewCounter(`atlas_api0_accounts_lookupuid_requests_total{result="success_singlematch"}`)
		mo.accounts_lookupuid_requests_total.success_multimatch = mo.set.NewCounter(`atlas_api0_accounts_lookupuid_requests_total{result="success_multimatch"}`)
		mo.accounts_lookupuid_requests_total.success_nomatch = mo.set.NewCounter(`atlas_api0_accounts_lookupuid_requests_total{result="success_nomatch"}`)
		mo.accounts_lookupuid_requests_total.reject_bad_request = mo.set.NewCounter(`atlas_api0_accounts_lookupuid_requests_total{result="reject_bad_request"}`)
		mo.accounts_lookupuid_requests_total.fail_storage_error_account = mo.set.NewCounter(`atlas_api0_accounts_lookupuid_requests_total{result="fail_storage_error_account"}`)
		mo.accounts_lookupuid_requests_total.http_method_not_allowed = mo.set.NewCounter(`atlas_api0_accounts_lookupuid_requests_total{result="http_method_not_allowed"}`)
		mo.accounts_getusername_requests_total.success_match = mo.set.NewCounter(`atlas_api0_accounts_getusername_requests_total{result="success_match"}`)
		mo.accounts_getusername_requests_total.success_missing = mo.set.NewCounter(`atlas_api0_accounts_getusername_requests_total{result="success_missing"}`)
		mo.accounts_getusername_requests_total.reject_bad_request = mo.set.NewCounter(`atlas_api0_accounts_getusername_requests_total{result="reject_bad_request"}`)
		mo.accounts_getusername_requests_total.reject_player_not_found = mo.set.NewCounter(`atlas_api0_accounts_getusername_requests_total{result="reject_player_not_found"}`)
		mo.accounts_getusername_requests_total.fail_storage_error_account = mo.set.NewCounter(`atlas_api0_accounts_getusername_requests_total{result="fail_storage_error_account"}`)
		mo.accounts_getusername_requests_total.http_method_not_allowed = mo.set.NewCounter(`atlas_api0_accounts_getusername_requests_total{result="http_method_not_allowed"}`)
		mo.client_mainmenupromos_requests_total.success = func(launcher_version string) *metrics.Counter {
			if launcher_version == "" {
				launcher_version = "unknown"
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_client_mainmenupromos_requests_total{result="success",launcher_version="` + launcher_version + `"}`)
		}
		mo.client_mainmenupromos_requests_total.success("unknown")
		mo.client_mainmenupromos_requests_total.http_method_not_allowed = mo.set.NewCounter(`atlas_api0_client_servers_response_size_bytes{result="http_method_not_allowed"}`)
		mo.client_originauth_requests_total.success = mo.set.NewCounter(`atlas_api0_client_originauth_requests_total{result="success"}`)
		mo.client_originauth_requests_total.reject_bad_request = mo.set.NewCounter(`atlas_api0_client_originauth_requests_total{result="reject_bad_request"}`)
		mo.client_originauth_requests_total.reject_versiongate = mo.set.NewCounter(`atlas_api0_client_originauth_requests_total{result="reject_versiongate"}`)
		mo.client_originauth_requests_total.reject_stryder_invalidgame = mo.set.NewCounter(`atlas_api0_client_originauth_requests_total{result="reject_stryder_invalidgame"}`)
		mo.client_originauth_requests_total.reject_stryder_invalidtoken = mo.set.NewCounter(`atlas_api0_client_originauth_requests_total{result="reject_stryder_invalidtoken"}`)
		mo.client_originauth_requests_total.reject_stryder_mpnotallowed = mo.set.NewCounter(`atlas_api0_client_originauth_requests_total{result="reject_stryder_mpnotallowed"}`)
		mo.client_originauth_requests_total.reject_stryder_other = mo.set.NewCounter(`atlas_api0_client_originauth_requests_total{result="reject_stryder_other"}`)
		mo.client_originauth_requests_total.fail_storage_error_account = mo.set.NewCounter(`atlas_api0_client_originauth_requests_total{result="fail_storage_error_account"}`)
		mo.client_originauth_requests_total.fail_stryder_error = mo.set.NewCounter(`atlas_api0_client_originauth_requests_total{result="fail_stryder_error"}`)
		mo.client_originauth_requests_total.fail_other_error = mo.set.NewCounter(`atlas_api0_client_originauth_requests_total{result="fail_other_error"}`)
		mo.client_originauth_requests_total.http_method_not_allowed = mo.set.NewCounter(`atlas_api0_client_originauth_requests_total{result="http_method_not_allowed"}`)
		mo.client_originauth_stryder_auth_duration_seconds = mo.set.NewHistogram(`atlas_api0_client_originauth_stryder_auth_duration_seconds`)
		mo.client_originauth_origin_username_lookup_duration_seconds = mo.set.NewHistogram(`atlas_api0_client_originauth_origin_username_lookup_duration_seconds`)
		mo.client_originauth_origin_username_lookup_calls_total.success = mo.set.NewCounter(`atlas_api0_client_originauth_origin_username_lookup_calls_total{result="success"}`)
		mo.client_originauth_origin_username_lookup_calls_total.notfound = mo.set.NewCounter(`atlas_api0_client_originauth_origin_username_lookup_calls_total{result="notfound"}`)
		mo.client_originauth_origin_username_lookup_calls_total.fail_authtok_refresh = mo.set.NewCounter(`atlas_api0_client_originauth_origin_username_lookup_calls_total{result="fail_authtok_refresh"}`)
		mo.client_originauth_origin_username_lookup_calls_total.fail_other_error = mo.set.NewCounter(`atlas_api0_client_originauth_origin_username_lookup_calls_total{result="fail_other_error"}`)
		mo.client_authwithserver_requests_total.success = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="success"}`)
		mo.client_authwithserver_requests_total.reject_bad_request = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="reject_bad_request"}`)
		mo.client_authwithserver_requests_total.reject_versiongate = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="reject_versiongate"}`)
		mo.client_authwithserver_requests_total.reject_player_not_found = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="reject_player_not_found"}`)
		mo.client_authwithserver_requests_total.reject_masterserver_token = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="reject_masterserver_token"}`)
		mo.client_authwithserver_requests_total.reject_password = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="reject_password"}`)
		mo.client_authwithserver_requests_total.reject_gameserverauth = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="reject_gameserverauth"}`)
		mo.client_authwithserver_requests_total.fail_gameserverauth = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="fail_gameserverauth"}`)
		mo.client_authwithserver_requests_total.fail_storage_error_account = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="fail_storage_error_account"}`)
		mo.client_authwithserver_requests_total.fail_storage_error_pdata = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="fail_storage_error_pdata"}`)
		mo.client_authwithserver_requests_total.fail_other_error = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="fail_other_error"}`)
		mo.client_authwithserver_requests_total.http_method_not_allowed = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="http_method_not_allowed"}`)
		mo.client_authwithserver_gameserverauth_duration_seconds = mo.set.NewHistogram(`atlas_api0_client_authwithserver_gameserverauth_duration_seconds`)
		mo.client_authwithself_requests_total.success = mo.set.NewCounter(`atlas_api0_client_authwithself_requests_total{result="success"}`)
		mo.client_authwithself_requests_total.reject_bad_request = mo.set.NewCounter(`atlas_api0_client_authwithself_requests_total{result="reject_bad_request"}`)
		mo.client_authwithself_requests_total.reject_versiongate = mo.set.NewCounter(`atlas_api0_client_authwithself_requests_total{result="reject_versiongate"}`)
		mo.client_authwithself_requests_total.reject_player_not_found = mo.set.NewCounter(`atlas_api0_client_authwithself_requests_total{result="reject_player_not_found"}`)
		mo.client_authwithself_requests_total.reject_masterserver_token = mo.set.NewCounter(`atlas_api0_client_authwithself_requests_total{result="reject_masterserver_token"}`)
		mo.client_authwithself_requests_total.fail_storage_error_account = mo.set.NewCounter(`atlas_api0_client_authwithself_requests_total{result="fail_storage_error_account"}`)
		mo.client_authwithself_requests_total.fail_storage_error_pdata = mo.set.NewCounter(`atlas_api0_client_authwithself_requests_total{result="fail_storage_error_pdata"}`)
		mo.client_authwithself_requests_total.fail_other_error = mo.set.NewCounter(`atlas_api0_client_authwithself_requests_total{result="fail_other_error"}`)
		mo.client_authwithself_requests_total.http_method_not_allowed = mo.set.NewCounter(`atlas_api0_client_authwithself_requests_total{result="http_method_not_allowed"}`)
		mo.client_servers_requests_total.success = func(launcher_version string) *metrics.Counter {
			if launcher_version == "" {
				launcher_version = "unknown"
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_client_servers_requests_total{result="success",launcher_version="` + launcher_version + `"}`)
		}
		mo.client_servers_requests_total.success("unknown")
		mo.client_servers_requests_total.http_method_not_allowed = mo.set.NewCounter(`atlas_api0_client_servers_requests_total{result="http_method_not_allowed"}`)
		mo.client_servers_response_size_bytes.gzip = mo.set.NewHistogram(`atlas_api0_client_servers_response_size_bytes{compression="gzip"}`)
		mo.client_servers_response_size_bytes.none = mo.set.NewHistogram(`atlas_api0_client_servers_response_size_bytes{compression="none"}`)
		mo.server_upsert_requests_total.success_updated = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="success_updated",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.success_verified = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="success_verified",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_versiongate = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_versiongate",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_ipv6 = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_ipv6",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_bad_request = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_bad_request",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_unauthorized_ip = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_unauthorized_ip",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_server_not_found = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_server_not_found",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_duplicate_auth_addr = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_duplicate_auth_addr",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_limits_exceeded = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_limits_exceeded",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_verify_authtimeout = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_verify_authtimeout",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_verify_authresp = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_verify_authresp",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_verify_autherr = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_verify_autherr",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_verify_udptimeout = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_verify_udptimeout",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.reject_verify_udperr = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="reject_verify_udperr",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.fail_other_error = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="fail_other_error",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.fail_serverlist_error = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="fail_serverlist_error",action="` + action + `"}`)
		}
		mo.server_upsert_requests_total.http_method_not_allowed = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_requests_total{result="http_method_not_allowed",action="` + action + `"}`)
		}
		mo.server_upsert_modinfo_parse_errors_total = func(action string) *metrics.Counter {
			if action == "" {
				panic("invalid action")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_server_upsert_modinfo_parse_errors_total{action="` + action + `"}`)
		}
		for _, action := range []string{"add_server", "update_values", "heartbeat"} {
			mo.server_upsert_requests_total.success_updated(action)
			mo.server_upsert_requests_total.success_verified(action)
			mo.server_upsert_requests_total.reject_versiongate(action)
			mo.server_upsert_requests_total.reject_ipv6(action)
			mo.server_upsert_requests_total.reject_bad_request(action)
			mo.server_upsert_requests_total.reject_unauthorized_ip(action)
			mo.server_upsert_requests_total.reject_server_not_found(action)
			mo.server_upsert_requests_total.reject_duplicate_auth_addr(action)
			mo.server_upsert_requests_total.reject_limits_exceeded(action)
			mo.server_upsert_requests_total.reject_verify_authtimeout(action)
			mo.server_upsert_requests_total.reject_verify_authresp(action)
			mo.server_upsert_requests_total.reject_verify_autherr(action)
			mo.server_upsert_requests_total.reject_verify_udptimeout(action)
			mo.server_upsert_requests_total.reject_verify_udperr(action)
			mo.server_upsert_requests_total.fail_other_error(action)
			mo.server_upsert_requests_total.fail_serverlist_error(action)
			mo.server_upsert_requests_total.http_method_not_allowed(action)
			mo.server_upsert_modinfo_parse_errors_total(action)
		}
		mo.server_upsert_verify_time_seconds.success = mo.set.NewHistogram(`atlas_api0_server_upsert_verify_time_seconds{success="true"}`)
		mo.server_upsert_verify_time_seconds.failure = mo.set.NewHistogram(`atlas_api0_server_upsert_verify_time_seconds{success="false"}`)
		mo.server_remove_requests_total.success = mo.set.NewCounter(`atlas_api0_server_remove_requests_total{result="success"}`)
		mo.server_remove_requests_total.reject_unauthorized_ip = mo.set.NewCounter(`atlas_api0_server_remove_requests_total{result="reject_unauthorized_ip"}`)
		mo.server_remove_requests_total.reject_bad_request = mo.set.NewCounter(`atlas_api0_server_remove_requests_total{result="reject_bad_request"}`)
		mo.server_remove_requests_total.reject_server_not_found = mo.set.NewCounter(`atlas_api0_server_remove_requests_total{result="reject_server_not_found"}`)
		mo.server_remove_requests_total.fail_other_error = mo.set.NewCounter(`atlas_api0_server_remove_requests_total{result="fail_other_error"}`)
		mo.server_remove_requests_total.http_method_not_allowed = mo.set.NewCounter(`atlas_api0_server_remove_requests_total{result="http_method_not_allowed"}`)
		mo.player_pdata_requests_total.success = func(filter string) *metrics.Counter {
			if filter == "" {
				panic("invalid filter")
			}
			return mo.set.GetOrCreateCounter(`atlas_api0_player_pdata_requests_total{result="success",filter="` + filter + `"}`)
		}
		mo.player_pdata_requests_total.reject_bad_request = mo.set.NewCounter(`atlas_api0_player_pdata_requests_total{result="reject_bad_request"}`)
		mo.player_pdata_requests_total.reject_player_not_found = mo.set.NewCounter(`atlas_api0_player_pdata_requests_total{result="reject_player_not_found"}`)
		mo.player_pdata_requests_total.fail_storage_error_pdata = mo.set.NewCounter(`atlas_api0_player_pdata_requests_total{result="fail_storage_error_pdata"}`)
		mo.player_pdata_requests_total.fail_pdata_invalid = mo.set.NewCounter(`atlas_api0_player_pdata_requests_total{result="fail_pdata_invalid"}`)
		mo.player_pdata_requests_total.fail_other_error = mo.set.NewCounter(`atlas_api0_player_pdata_requests_total{result="fail_other_error"}`)
		mo.player_pdata_requests_total.http_method_not_allowed = mo.set.NewCounter(`atlas_api0_player_pdata_requests_total{result="http_method_not_allowed"}`)
	})

	// ensure we initialized everything
	var chk func(v reflect.Value, name string)
	chk = func(v reflect.Value, name string) {
		switch v.Kind() {
		case reflect.Struct:
			for i := 0; i < v.NumField(); i++ {
				chk(v.Field(i), name+"."+v.Type().Field(i).Name)
			}
		case reflect.Pointer, reflect.Func:
			if v.IsNil() {
				panic(fmt.Errorf("check metrics: unexpected nil %q", name))
			}
		default:
			panic(fmt.Errorf("check metrics: unexpected kind %s", v.Kind()))
		}
	}
	chk(reflect.ValueOf(h.metricsObj), "metricsObj")

	return &h.metricsObj
}