1 package com.zaxxer.hikari.metrics.micrometer;
2
3 import com.zaxxer.hikari.metrics.IMetricsTracker;
4 import com.zaxxer.hikari.metrics.PoolStats;
5 import io.micrometer.core.instrument.Counter;
6 import io.micrometer.core.instrument.Gauge;
7 import io.micrometer.core.instrument.MeterRegistry;
8 import io.micrometer.core.instrument.Timer;
9
10 import java.util.concurrent.TimeUnit;
11
12
33 public class MicrometerMetricsTracker implements IMetricsTracker
34 {
35
36 public static final String HIKARI_METRIC_NAME_PREFIX = "hikaricp";
37
38 private static final String METRIC_CATEGORY = "pool";
39 private static final String METRIC_NAME_WAIT = HIKARI_METRIC_NAME_PREFIX + ".connections.acquire";
40 private static final String METRIC_NAME_USAGE = HIKARI_METRIC_NAME_PREFIX + ".connections.usage";
41 private static final String METRIC_NAME_CONNECT = HIKARI_METRIC_NAME_PREFIX + ".connections.creation";
42
43 private static final String METRIC_NAME_TIMEOUT_RATE = HIKARI_METRIC_NAME_PREFIX + ".connections.timeout";
44 private static final String METRIC_NAME_TOTAL_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections";
45 private static final String METRIC_NAME_IDLE_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections.idle";
46 private static final String METRIC_NAME_ACTIVE_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections.active";
47 private static final String METRIC_NAME_PENDING_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections.pending";
48 private static final String METRIC_NAME_MAX_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections.max";
49 private static final String METRIC_NAME_MIN_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections.min";
50
51
52 private final Timer connectionObtainTimer;
53 private final Counter connectionTimeoutCounter;
54 private final Timer connectionUsage;
55 private final Timer connectionCreation;
56 @SuppressWarnings({"FieldCanBeLocal", "unused"})
57 private final Gauge totalConnectionGauge;
58 @SuppressWarnings({"FieldCanBeLocal", "unused"})
59 private final Gauge idleConnectionGauge;
60 @SuppressWarnings({"FieldCanBeLocal", "unused"})
61 private final Gauge activeConnectionGauge;
62 @SuppressWarnings({"FieldCanBeLocal", "unused"})
63 private final Gauge pendingConnectionGauge;
64 @SuppressWarnings({"FieldCanBeLocal", "unused"})
65 private final Gauge maxConnectionGauge;
66 @SuppressWarnings({"FieldCanBeLocal", "unused"})
67 private final Gauge minConnectionGauge;
68 @SuppressWarnings({"FieldCanBeLocal", "unused"})
69 private final PoolStats poolStats;
70
71 MicrometerMetricsTracker(final String poolName, final PoolStats poolStats, final MeterRegistry meterRegistry)
72 {
73 this.poolStats = poolStats;
74
75 this.connectionObtainTimer = Timer.builder(METRIC_NAME_WAIT)
76 .description("Connection acquire time")
77 .tags(METRIC_CATEGORY, poolName)
78 .register(meterRegistry);
79
80 this.connectionCreation = Timer.builder(METRIC_NAME_CONNECT)
81 .description("Connection creation time")
82 .tags(METRIC_CATEGORY, poolName)
83 .register(meterRegistry);
84
85 this.connectionUsage = Timer.builder(METRIC_NAME_USAGE)
86 .description("Connection usage time")
87 .tags(METRIC_CATEGORY, poolName)
88 .register(meterRegistry);
89
90 this.connectionTimeoutCounter = Counter.builder(METRIC_NAME_TIMEOUT_RATE)
91 .description("Connection timeout total count")
92 .tags(METRIC_CATEGORY, poolName)
93 .register(meterRegistry);
94
95 this.totalConnectionGauge = Gauge.builder(METRIC_NAME_TOTAL_CONNECTIONS, poolStats, PoolStats::getTotalConnections)
96 .description("Total connections")
97 .tags(METRIC_CATEGORY, poolName)
98 .register(meterRegistry);
99
100 this.idleConnectionGauge = Gauge.builder(METRIC_NAME_IDLE_CONNECTIONS, poolStats, PoolStats::getIdleConnections)
101 .description("Idle connections")
102 .tags(METRIC_CATEGORY, poolName)
103 .register(meterRegistry);
104
105 this.activeConnectionGauge = Gauge.builder(METRIC_NAME_ACTIVE_CONNECTIONS, poolStats, PoolStats::getActiveConnections)
106 .description("Active connections")
107 .tags(METRIC_CATEGORY, poolName)
108 .register(meterRegistry);
109
110 this.pendingConnectionGauge = Gauge.builder(METRIC_NAME_PENDING_CONNECTIONS, poolStats, PoolStats::getPendingThreads)
111 .description("Pending threads")
112 .tags(METRIC_CATEGORY, poolName)
113 .register(meterRegistry);
114
115 this.maxConnectionGauge = Gauge.builder(METRIC_NAME_MAX_CONNECTIONS, poolStats, PoolStats::getMaxConnections)
116 .description("Max connections")
117 .tags(METRIC_CATEGORY, poolName)
118 .register(meterRegistry);
119
120 this.minConnectionGauge = Gauge.builder(METRIC_NAME_MIN_CONNECTIONS, poolStats, PoolStats::getMinConnections)
121 .description("Min connections")
122 .tags(METRIC_CATEGORY, poolName)
123 .register(meterRegistry);
124
125 }
126
127
128 @Override
129 public void recordConnectionAcquiredNanos(final long elapsedAcquiredNanos)
130 {
131 connectionObtainTimer.record(elapsedAcquiredNanos, TimeUnit.NANOSECONDS);
132 }
133
134
135 @Override
136 public void recordConnectionUsageMillis(final long elapsedBorrowedMillis)
137 {
138 connectionUsage.record(elapsedBorrowedMillis, TimeUnit.MILLISECONDS);
139 }
140
141 @Override
142 public void recordConnectionTimeout()
143 {
144 connectionTimeoutCounter.increment();
145 }
146
147 @Override
148 public void recordConnectionCreatedMillis(long connectionCreatedMillis)
149 {
150 connectionCreation.record(connectionCreatedMillis, TimeUnit.MILLISECONDS);
151 }
152 }
153