-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMicrometerTurnstileMetrics.java
More file actions
101 lines (93 loc) · 4.78 KB
/
Copy pathMicrometerTurnstileMetrics.java
File metadata and controls
101 lines (93 loc) · 4.78 KB
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
package com.digitalsanctuary.cf.turnstile.metrics;
import com.digitalsanctuary.cf.turnstile.dto.ValidationResult.ValidationResultType;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
/**
* Micrometer-backed implementation of {@link TurnstileMetrics}.
* <p>
* This class is only instantiated when Micrometer is present on the classpath, via
* {@code TurnstileMetricsConfig} which is guarded by {@code @ConditionalOnClass(MeterRegistry.class)}.
* </p>
* <p>
* All eight meters ({@code errorCounter} is the aggregate; the four type-specific counters are
* sub-categories whose sum equals the aggregate) are eagerly registered at construction time so
* they appear in monitoring dashboards before the first validation event occurs. A single instance
* should be registered per application context to avoid duplicate meter registration errors.
* </p>
*
* @see NoOpTurnstileMetrics
*/
@Slf4j
public class MicrometerTurnstileMetrics implements TurnstileMetrics {
private final Counter validationCounter;
private final Counter successCounter;
private final Counter errorCounter;
private final Counter networkErrorCounter;
private final Counter configErrorCounter;
private final Counter validationErrorCounter;
private final Counter inputErrorCounter;
private final Timer responseTimer;
/**
* Creates a {@code MicrometerTurnstileMetrics} instance and eagerly registers all Turnstile
* meters with the provided registry. The registered meters are:
* <ul>
* <li>{@code turnstile.validation.requests} — total attempts</li>
* <li>{@code turnstile.validation.success} — successful validations</li>
* <li>{@code turnstile.validation.errors} — all errors (aggregate)</li>
* <li>{@code turnstile.validation.errors.network} — network errors</li>
* <li>{@code turnstile.validation.errors.config} — configuration errors</li>
* <li>{@code turnstile.validation.errors.token} — invalid token errors</li>
* <li>{@code turnstile.validation.errors.input} — input validation errors</li>
* <li>{@code turnstile.validation.response.time} — response time timer</li>
* </ul>
*
* @param registry the Micrometer {@link MeterRegistry} to register meters with; must not be null
*/
public MicrometerTurnstileMetrics(MeterRegistry registry) {
Objects.requireNonNull(registry, "registry must not be null");
log.info("Initializing Turnstile metrics with MeterRegistry");
validationCounter = Counter.builder("turnstile.validation.requests")
.description("Total number of Turnstile validation requests").register(registry);
successCounter = Counter.builder("turnstile.validation.success")
.description("Number of successful Turnstile validations").register(registry);
errorCounter = Counter.builder("turnstile.validation.errors")
.description("Number of failed Turnstile validations").register(registry);
networkErrorCounter = Counter.builder("turnstile.validation.errors.network")
.description("Number of Turnstile validation network errors").register(registry);
configErrorCounter = Counter.builder("turnstile.validation.errors.config")
.description("Number of Turnstile validation configuration errors").register(registry);
validationErrorCounter = Counter.builder("turnstile.validation.errors.token")
.description("Number of Turnstile validation token errors").register(registry);
inputErrorCounter = Counter.builder("turnstile.validation.errors.input")
.description("Number of Turnstile validation input errors").register(registry);
responseTimer = Timer.builder("turnstile.validation.response.time")
.description("Response time for Turnstile validation requests").register(registry);
}
@Override
public void recordValidation() {
validationCounter.increment();
}
@Override
public void recordSuccess() {
successCounter.increment();
}
@Override
public void recordError(ValidationResultType type) {
errorCounter.increment();
switch (type) {
case NETWORK_ERROR -> networkErrorCounter.increment();
case CONFIGURATION_ERROR -> configErrorCounter.increment();
case INVALID_TOKEN -> validationErrorCounter.increment();
case INPUT_ERROR -> inputErrorCounter.increment();
default -> { }
}
}
@Override
public void recordResponseTime(long milliseconds) {
responseTimer.record(milliseconds, TimeUnit.MILLISECONDS);
}
}