1 package io.getunleash.metric;
2
3 import io.getunleash.util.Throttler;
4 import io.getunleash.util.UnleashConfig;
5 import io.getunleash.util.UnleashScheduledExecutor;
6 import java.time.LocalDateTime;
7 import java.time.ZoneId;
8 import java.util.Set;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11
12 public class UnleashMetricServiceImpl implements UnleashMetricService {
13 private static final Logger LOGGER = LoggerFactory.getLogger(UnleashMetricServiceImpl.class);
14 private final LocalDateTime started;
15 private final UnleashConfig unleashConfig;
16 private final MetricSender metricSender;
17
18
19 private volatile MetricsBucket currentMetricsBucket;
20
21 private final Throttler throttler;
22
23 public UnleashMetricServiceImpl(
24 UnleashConfig unleashConfig, UnleashScheduledExecutor executor) {
25 this(unleashConfig, unleashConfig.getMetricSenderFactory().apply(unleashConfig), executor);
26 }
27
28 public UnleashMetricServiceImpl(
29 UnleashConfig unleashConfig,
30 MetricSender metricSender,
31 UnleashScheduledExecutor executor) {
32 this.currentMetricsBucket = new MetricsBucket();
33 this.started = LocalDateTime.now(ZoneId.of("UTC"));
34 this.unleashConfig = unleashConfig;
35 this.metricSender = metricSender;
36 this.throttler =
37 new Throttler(
38 (int) unleashConfig.getSendMetricsInterval(),
39 300,
40 unleashConfig.getUnleashURLs().getClientMetricsURL());
41 long metricsInterval = unleashConfig.getSendMetricsInterval();
42
43 executor.setInterval(sendMetrics(), metricsInterval, metricsInterval);
44 }
45
46 @Override
47 public void register(Set<String> strategies) {
48 ClientRegistration registration =
49 new ClientRegistration(unleashConfig, started, strategies);
50 metricSender.registerClient(registration);
51 }
52
53 @Override
54 public void count(String toggleName, boolean active) {
55 currentMetricsBucket.registerCount(toggleName, active);
56 }
57
58 @Override
59 public void countVariant(String toggleName, String variantName) {
60 currentMetricsBucket.registerCount(toggleName, variantName);
61 }
62
63 private Runnable sendMetrics() {
64 return () -> {
65 if (throttler.performAction()) {
66 MetricsBucket metricsBucket = this.currentMetricsBucket;
67 this.currentMetricsBucket = new MetricsBucket();
68 metricsBucket.end();
69 ClientMetrics metrics = new ClientMetrics(unleashConfig, metricsBucket);
70 int statusCode = metricSender.sendMetrics(metrics);
71 if (statusCode >= 200 && statusCode < 400) {
72 throttler.decrementFailureCountAndResetSkips();
73 }
74 if (statusCode >= 400) {
75 throttler.handleHttpErrorCodes(statusCode);
76 }
77 } else {
78 throttler.skipped();
79 }
80 };
81 }
82
83 protected int getSkips() {
84 return this.throttler.getSkips();
85 }
86
87 protected int getFailures() {
88 return this.throttler.getFailures();
89 }
90 }
91