From 9e842aca4e6459e773a22b6cd1880401b2f8a932 Mon Sep 17 00:00:00 2001 From: Joel Takvorian Date: Thu, 3 Jun 2021 16:05:31 +0200 Subject: [PATCH] Implement custom tags provider for HTTP metrics - Allows to implement a custom tags provider (Function: request -> Tags) to provide tags out of HttpRequest objects. - Add tests Fixes https://github.com/vert-x3/vertx-micrometer-metrics/issues/89 Signed-off-by: Joel Takvorian --- .../micrometer/MicrometerMetricsOptions.java | 25 ++++ .../impl/VertxHttpServerMetrics.java | 28 +++-- .../micrometer/impl/VertxMetricsImpl.java | 2 +- .../micrometer/impl/meters/Counters.java | 15 ++- .../vertx/micrometer/impl/meters/Gauges.java | 16 ++- .../micrometer/impl/meters/Summaries.java | 15 ++- .../vertx/micrometer/impl/meters/Timers.java | 20 ++- .../VertxHttpServerMetricsConfigTest.java | 115 ++++++++++++++++++ .../micrometer/impl/meters/CountersTest.java | 14 +++ .../micrometer/impl/meters/GaugesTest.java | 14 +++ .../micrometer/impl/meters/SummariesTest.java | 14 +++ .../micrometer/impl/meters/TimersTest.java | 14 +++ .../service/MetricsServiceImplTest.java | 3 +- 13 files changed, 277 insertions(+), 18 deletions(-) create mode 100644 src/test/java/io/vertx/micrometer/VertxHttpServerMetricsConfigTest.java diff --git a/src/main/java/io/vertx/micrometer/MicrometerMetricsOptions.java b/src/main/java/io/vertx/micrometer/MicrometerMetricsOptions.java index def6a880..8e249644 100644 --- a/src/main/java/io/vertx/micrometer/MicrometerMetricsOptions.java +++ b/src/main/java/io/vertx/micrometer/MicrometerMetricsOptions.java @@ -16,14 +16,17 @@ package io.vertx.micrometer; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; import io.vertx.codegen.annotations.DataObject; import io.vertx.codegen.annotations.GenIgnore; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import io.vertx.core.metrics.MetricsOptions; import io.vertx.core.spi.VertxMetricsFactory; +import io.vertx.core.spi.observability.HttpRequest; import java.util.*; +import java.util.function.Function; /** * Vert.x micrometer configuration. @@ -66,6 +69,8 @@ public class MicrometerMetricsOptions extends MetricsOptions { private VertxJmxMetricsOptions jmxMetricsOptions; private boolean jvmMetricsEnabled; private MetricsNaming metricsNaming; + @GenIgnore + private Function> requestsTagsProvider; /** * Creates default options for Micrometer metrics. @@ -77,6 +82,7 @@ public MicrometerMetricsOptions() { labelMatches = new ArrayList<>(); jvmMetricsEnabled = DEFAULT_JVM_METRICS_ENABLED; metricsNaming = DEFAULT_METRICS_NAMING; + requestsTagsProvider = null; } /** @@ -100,6 +106,7 @@ public MicrometerMetricsOptions(MicrometerMetricsOptions other) { } jvmMetricsEnabled = other.jvmMetricsEnabled; metricsNaming = other.metricsNaming; + requestsTagsProvider = other.requestsTagsProvider; } /** @@ -415,4 +422,22 @@ public MicrometerMetricsOptions setMetricsNaming(MetricsNaming metricsNaming) { this.metricsNaming = metricsNaming; return this; } + + /** + * @return an optional custom tags provider for HTTP requests + */ + public Function> getRequestsTagsProvider() { + return requestsTagsProvider; + } + + /** + * Sets a custom tags provider for HTTP requests. Allows to generate custom tags for every {@code HttpRequest} object processed through the metrics SPI. + * + * @param requestsTagsProvider an object implementing the {@code CustomTagsProvider} interface for {@code HttpRequest}. + * @return a reference to this, so that the API can be used fluently + */ + public MicrometerMetricsOptions setRequestsTagsProvider(Function> requestsTagsProvider) { + this.requestsTagsProvider = requestsTagsProvider; + return this; + } } diff --git a/src/main/java/io/vertx/micrometer/impl/VertxHttpServerMetrics.java b/src/main/java/io/vertx/micrometer/impl/VertxHttpServerMetrics.java index 09f98974..b9a02385 100644 --- a/src/main/java/io/vertx/micrometer/impl/VertxHttpServerMetrics.java +++ b/src/main/java/io/vertx/micrometer/impl/VertxHttpServerMetrics.java @@ -16,6 +16,7 @@ package io.vertx.micrometer.impl; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; import io.vertx.core.http.HttpMethod; import io.vertx.core.http.ServerWebSocket; import io.vertx.core.net.SocketAddress; @@ -34,6 +35,7 @@ import java.util.LinkedList; import java.util.List; import java.util.concurrent.atomic.LongAdder; +import java.util.function.Function; /** * @author Joel Takvorian @@ -46,9 +48,11 @@ class VertxHttpServerMetrics extends VertxNetServerMetrics { private final Timers processingTime; private final Summaries responseBytes; private final Gauges wsConnections; + private final Function> customTagsProvider; - VertxHttpServerMetrics(MeterRegistry registry, MetricsNaming names) { + VertxHttpServerMetrics(MeterRegistry registry, MetricsNaming names, Function> customTagsProvider) { super(registry, MetricsDomain.HTTP_SERVER, names); + this.customTagsProvider = customTagsProvider; requests = longGauges(names.getHttpActiveRequests(), "Number of requests being processed", Label.LOCAL, Label.REMOTE, Label.HTTP_PATH, Label.HTTP_METHOD); requestCount = counters(names.getHttpRequestsCount(), "Number of processed requests", Label.LOCAL, Label.REMOTE, Label.HTTP_ROUTE, Label.HTTP_PATH, Label.HTTP_METHOD, Label.HTTP_CODE); requestResetCount = counters(names.getHttpRequestResetsCount(), "Number of request resets", Label.LOCAL, Label.REMOTE, Label.HTTP_PATH, Label.HTTP_METHOD); @@ -71,26 +75,29 @@ class Instance extends VertxNetServerMetrics.Instance implements HttpServerMetri @Override public Handler requestBegin(String remote, HttpRequest request) { Handler handler = new Handler(remote, request.uri(), request.method().name()); - requests.get(local, remote, handler.path, handler.method).increment(); + if (customTagsProvider != null) { + handler.customTags = customTagsProvider.apply(request); + } + requests.get(handler.customTags, local, remote, handler.path, handler.method).increment(); handler.timer = processingTime.start(); return handler; } @Override public void requestReset(Handler handler) { - requestResetCount.get(local, handler.address, handler.path, handler.method).increment(); - requests.get(local, handler.address, handler.path, handler.method).decrement(); + requestResetCount.get(handler.customTags, local, handler.address, handler.path, handler.method).increment(); + requests.get(handler.customTags, local, handler.address, handler.path, handler.method).decrement(); } @Override public void requestEnd(Handler handler, HttpRequest request, long bytesRead) { - requestBytes.get(local, handler.address, handler.path, handler.method).record(bytesRead); + requestBytes.get(handler.customTags, local, handler.address, handler.path, handler.method).record(bytesRead); } @Override public Handler responsePushed(String remote, HttpMethod method, String uri, HttpResponse response) { Handler handler = new Handler(remote, uri, method.name()); - requests.get(local, remote, handler.path, handler.method).increment(); + requests.get(handler.customTags, local, remote, handler.path, handler.method).increment(); return handler; } @@ -102,10 +109,10 @@ public void responseBegin(Handler handler, HttpResponse response) { public void responseEnd(Handler handler, HttpResponse response, long bytesWritten) { String code = String.valueOf(response.statusCode()); String handlerRoute = handler.getRoute(); - handler.timer.end(local, handler.address, handlerRoute, handler.path, handler.method, code); - requestCount.get(local, handler.address, handlerRoute, handler.path, handler.method, code).increment(); - requests.get(local, handler.address, handler.path, handler.method).decrement(); - responseBytes.get(local, handler.address, handlerRoute, handler.path, handler.method, code).record(bytesWritten); + handler.timer.end(handler.customTags, local, handler.address, handlerRoute, handler.path, handler.method, code); + requestCount.get(handler.customTags, local, handler.address, handlerRoute, handler.path, handler.method, code).increment(); + requests.get(handler.customTags, local, handler.address, handler.path, handler.method).decrement(); + responseBytes.get(handler.customTags, local, handler.address, handlerRoute, handler.path, handler.method, code).record(bytesWritten); } @Override @@ -138,6 +145,7 @@ public static class Handler { // tracks length of resulting routes string private int routesLength; private Timers.EventTiming timer; + private Iterable customTags; Handler(String address, String path, String method) { this.address = address; diff --git a/src/main/java/io/vertx/micrometer/impl/VertxMetricsImpl.java b/src/main/java/io/vertx/micrometer/impl/VertxMetricsImpl.java index 52dd2620..c3c4264b 100644 --- a/src/main/java/io/vertx/micrometer/impl/VertxMetricsImpl.java +++ b/src/main/java/io/vertx/micrometer/impl/VertxMetricsImpl.java @@ -93,7 +93,7 @@ public VertxMetricsImpl(MicrometerMetricsOptions options, BackendRegistry backen httpClientMetrics = options.isMetricsCategoryDisabled(HTTP_CLIENT) ? null : new VertxHttpClientMetrics(registry, names); httpServerMetrics = options.isMetricsCategoryDisabled(HTTP_SERVER) ? null - : new VertxHttpServerMetrics(registry, names); + : new VertxHttpServerMetrics(registry, names, options.getRequestsTagsProvider()); poolMetrics = options.isMetricsCategoryDisabled(NAMED_POOLS) ? null : new VertxPoolMetrics(registry, names); } diff --git a/src/main/java/io/vertx/micrometer/impl/meters/Counters.java b/src/main/java/io/vertx/micrometer/impl/meters/Counters.java index 0f71391f..175314c4 100644 --- a/src/main/java/io/vertx/micrometer/impl/meters/Counters.java +++ b/src/main/java/io/vertx/micrometer/impl/meters/Counters.java @@ -18,9 +18,15 @@ import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; import io.vertx.micrometer.Label; import io.vertx.micrometer.impl.Labels; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + /** * @author Joel Takvorian */ @@ -41,10 +47,17 @@ public Counters(String name, } public Counter get(String... values) { + return get(null, values); + } + + public Counter get(Iterable customTags, String... values) { + List tags = customTags != null + ? Stream.concat(Labels.toTags(keys, values).stream(), StreamSupport.stream(customTags.spliterator(), false)).collect(Collectors.toList()) + : Labels.toTags(keys, values); // Get or create the Counter return Counter.builder(name) .description(description) - .tags(Labels.toTags(keys, values)) + .tags(tags) .register(registry); } } diff --git a/src/main/java/io/vertx/micrometer/impl/meters/Gauges.java b/src/main/java/io/vertx/micrometer/impl/meters/Gauges.java index 3cba0c07..987f8d01 100644 --- a/src/main/java/io/vertx/micrometer/impl/meters/Gauges.java +++ b/src/main/java/io/vertx/micrometer/impl/meters/Gauges.java @@ -19,13 +19,18 @@ import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; import io.vertx.micrometer.Label; import io.vertx.micrometer.impl.Labels; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import java.util.function.ToDoubleFunction; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; /** * @author Joel Takvorian @@ -53,7 +58,14 @@ public Gauges(String name, this.keys = keys; } - public synchronized T get(String... values) { + public T get(String... values) { + return get(null, values); + } + + public synchronized T get(Iterable customTags, String... values) { + List tags = customTags != null + ? Stream.concat(Labels.toTags(keys, values).stream(), StreamSupport.stream(customTags.spliterator(), false)).collect(Collectors.toList()) + : Labels.toTags(keys, values); // This method is synchronized to make sure the "T" built via supplier will match the one passed to Gauge // since it is stored as WeakReference in Micrometer DefaultGauge, it must not be lost. T t = tSupplier.get(); @@ -63,7 +75,7 @@ public synchronized T get(String... values) { // Micrometer will not register the gauge twice if it was already created. Gauge g = Gauge.builder(name, t, dGetter) .description(description) - .tags(Labels.toTags(keys, values)) + .tags(tags) .register(registry); return gauges.computeIfAbsent(g.getId(), v -> t); } diff --git a/src/main/java/io/vertx/micrometer/impl/meters/Summaries.java b/src/main/java/io/vertx/micrometer/impl/meters/Summaries.java index 533cfbf4..a36ee328 100644 --- a/src/main/java/io/vertx/micrometer/impl/meters/Summaries.java +++ b/src/main/java/io/vertx/micrometer/impl/meters/Summaries.java @@ -18,9 +18,15 @@ import io.micrometer.core.instrument.DistributionSummary; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; import io.vertx.micrometer.Label; import io.vertx.micrometer.impl.Labels; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + /** * @author Joel Takvorian */ @@ -41,10 +47,17 @@ public Summaries(String name, } public DistributionSummary get(String... values) { + return get(null, values); + } + + public DistributionSummary get(Iterable customTags, String... values) { + List tags = customTags != null + ? Stream.concat(Labels.toTags(keys, values).stream(), StreamSupport.stream(customTags.spliterator(), false)).collect(Collectors.toList()) + : Labels.toTags(keys, values); // Get or create the Summary return DistributionSummary.builder(name) .description(description) - .tags(Labels.toTags(keys, values)) + .tags(tags) .register(registry); } } diff --git a/src/main/java/io/vertx/micrometer/impl/meters/Timers.java b/src/main/java/io/vertx/micrometer/impl/meters/Timers.java index 6b9ad010..bc83da75 100644 --- a/src/main/java/io/vertx/micrometer/impl/meters/Timers.java +++ b/src/main/java/io/vertx/micrometer/impl/meters/Timers.java @@ -17,11 +17,16 @@ package io.vertx.micrometer.impl.meters; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Timer; import io.vertx.micrometer.Label; import io.vertx.micrometer.impl.Labels; +import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; /** * @author Joel Takvorian @@ -43,10 +48,17 @@ public Timers(String name, } public Timer get(String... values) { + return get(null, values); + } + + public Timer get(Iterable customTags, String... values) { + List tags = customTags != null + ? Stream.concat(Labels.toTags(keys, values).stream(), StreamSupport.stream(customTags.spliterator(), false)).collect(Collectors.toList()) + : Labels.toTags(keys, values); // Get or create the Timer return Timer.builder(name) .description(description) - .tags(Labels.toTags(keys, values)) + .tags(tags) .register(registry); } @@ -64,7 +76,11 @@ private EventTiming(Timers ref) { } public void end(String... values) { - Timer t = ref.get(values); + end(null, values); + } + + public void end(Iterable customTags, String... values) { + Timer t = ref.get(customTags, values); t.record(System.nanoTime() - nanoStart, TimeUnit.NANOSECONDS); } } diff --git a/src/test/java/io/vertx/micrometer/VertxHttpServerMetricsConfigTest.java b/src/test/java/io/vertx/micrometer/VertxHttpServerMetricsConfigTest.java new file mode 100644 index 00000000..18f5b3fd --- /dev/null +++ b/src/test/java/io/vertx/micrometer/VertxHttpServerMetricsConfigTest.java @@ -0,0 +1,115 @@ +package io.vertx.micrometer; + +import io.micrometer.core.instrument.Tag; +import io.vertx.core.AbstractVerticle; +import io.vertx.core.Future; +import io.vertx.core.Promise; +import io.vertx.core.Vertx; +import io.vertx.core.VertxOptions; +import io.vertx.core.http.HttpClient; +import io.vertx.core.http.HttpMethod; +import io.vertx.core.http.HttpServer; +import io.vertx.ext.unit.Async; +import io.vertx.ext.unit.TestContext; +import io.vertx.ext.unit.junit.VertxUnitRunner; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import static io.vertx.micrometer.RegistryInspector.Datapoint; +import static io.vertx.micrometer.RegistryInspector.listDatapoints; +import static io.vertx.micrometer.RegistryInspector.startsWith; +import static io.vertx.micrometer.RegistryInspector.waitForValue; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Joel Takvorian + */ +@RunWith(VertxUnitRunner.class) +public class VertxHttpServerMetricsConfigTest { + private final String registryName = UUID.randomUUID().toString(); + private HttpServer httpServer; + private Vertx vertx; + + @After + public void tearDown(TestContext context) { + vertx.close(context.asyncAssertSuccess()); + } + + @Test + public void shouldReportHttpServerMetricsWithCustomTags(TestContext ctx) { + vertx = Vertx.vertx(new VertxOptions().setMetricsOptions(new MicrometerMetricsOptions() + .setRequestsTagsProvider(req -> { + String user = req.headers().get("user"); + return Collections.singletonList(Tag.of("user", user)); + }) + .setPrometheusOptions(new VertxPrometheusOptions().setEnabled(true)) + .setRegistryName(registryName) + .setEnabled(true))) + .exceptionHandler(ctx.exceptionHandler()); + + prepareServer(ctx); + HttpClient client = vertx.createHttpClient(); + sendRequest(ctx, client, "alice"); + sendRequest(ctx, client, "bob"); + + waitForValue(vertx, ctx, registryName, "vertx.http.client.response.time[code=200,method=POST]$COUNT", + value -> value.intValue() == 2); + waitForValue(vertx, ctx, registryName, "vertx.http.client.active.requests[method=POST]$VALUE", + value -> value.intValue() == 0); + + List datapoints = listDatapoints(registryName, startsWith("vertx.http.server.")); + assertThat(datapoints).extracting(Datapoint::id).contains( + "vertx.http.server.requests[code=200,method=POST,route=,user=alice]$COUNT", + "vertx.http.server.active.requests[method=POST,user=alice]$VALUE", + "vertx.http.server.response.time[code=200,method=POST,route=,user=alice]$COUNT", + "vertx.http.server.requests[code=200,method=POST,route=,user=bob]$COUNT", + "vertx.http.server.active.requests[method=POST,user=bob]$VALUE", + "vertx.http.server.response.time[code=200,method=POST,route=,user=bob]$COUNT"); + } + + private void prepareServer(TestContext ctx) { + // Setup server + Async serverReady = ctx.async(); + vertx.deployVerticle(new AbstractVerticle() { + @Override + public void start(Promise future) throws Exception { + httpServer = vertx.createHttpServer(); + httpServer + .requestHandler(req -> { + vertx.setTimer(30L, handler -> + req.response().setChunked(true).putHeader("Content-Type", "text/plain").end("")); + }) + .listen(9195, "127.0.0.1", r -> { + if (r.failed()) { + ctx.fail(r.cause()); + } else { + serverReady.complete(); + } + }); + } + }); + serverReady.awaitSuccess(); + } + + private void sendRequest(TestContext ctx, HttpClient client, String user) { + Async async = ctx.async(); + client.request(HttpMethod.POST, 9195, "127.0.0.1", "/") + .compose(req -> req + .putHeader("user", user) + .send("") + .compose(response -> { + if (response.statusCode() != 200) { + return Future.failedFuture(response.statusMessage()); + } else { + return response.body(); + } + })) + .onComplete(ctx.asyncAssertSuccess(v -> async.countDown())); + async.await(); + } +} diff --git a/src/test/java/io/vertx/micrometer/impl/meters/CountersTest.java b/src/test/java/io/vertx/micrometer/impl/meters/CountersTest.java index 092d7693..0f06a028 100644 --- a/src/test/java/io/vertx/micrometer/impl/meters/CountersTest.java +++ b/src/test/java/io/vertx/micrometer/impl/meters/CountersTest.java @@ -2,6 +2,7 @@ import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.vertx.micrometer.Label; import io.vertx.micrometer.Match; @@ -9,8 +10,10 @@ import io.vertx.micrometer.backends.BackendRegistries; import org.junit.Test; +import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -62,4 +65,15 @@ public void shouldIgnoreCounterLabel() { c = registry.find("my_counter").tags("address", "addr2").counter(); assertThat(c).isNull(); } + + @Test + public void shouldAddCustomTags() { + List customTags = Arrays.asList(Tag.of("k1", "v1"), Tag.of("k2", "v2")); + MeterRegistry registry = new SimpleMeterRegistry(); + Counters counters = new Counters("my_counter", "", registry, Label.EB_ADDRESS); + counters.get(customTags, "addr1").increment(); + + Counter c = registry.find("my_counter").tags("address", "addr1", "k1", "v1", "k2", "v2").counter(); + assertThat(c.count()).isEqualTo(1d); + } } diff --git a/src/test/java/io/vertx/micrometer/impl/meters/GaugesTest.java b/src/test/java/io/vertx/micrometer/impl/meters/GaugesTest.java index da5ed4ed..1558d160 100644 --- a/src/test/java/io/vertx/micrometer/impl/meters/GaugesTest.java +++ b/src/test/java/io/vertx/micrometer/impl/meters/GaugesTest.java @@ -2,6 +2,7 @@ import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.vertx.micrometer.Label; import io.vertx.micrometer.Match; @@ -9,8 +10,10 @@ import io.vertx.micrometer.backends.BackendRegistries; import org.junit.Test; +import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; +import java.util.List; import java.util.concurrent.atomic.LongAdder; import static org.assertj.core.api.Assertions.assertThat; @@ -63,4 +66,15 @@ public void shouldIgnoreGaugeLabel() { g = registry.find("my_gauge").tags("address", "addr2").gauge(); assertThat(g).isNull(); } + + @Test + public void shouldAddCustomTags() { + List customTags = Arrays.asList(Tag.of("k1", "v1"), Tag.of("k2", "v2")); + MeterRegistry registry = new SimpleMeterRegistry(); + Gauges gauges = new Gauges<>("my_gauge", "", LongAdder::new, LongAdder::doubleValue, registry, Label.EB_ADDRESS); + gauges.get(customTags, "addr1").increment(); + + Gauge g = registry.find("my_gauge").tags("address", "addr1", "k1", "v1", "k2", "v2").gauge(); + assertThat(g.value()).isEqualTo(1d); + } } diff --git a/src/test/java/io/vertx/micrometer/impl/meters/SummariesTest.java b/src/test/java/io/vertx/micrometer/impl/meters/SummariesTest.java index b36428fe..1c59845e 100644 --- a/src/test/java/io/vertx/micrometer/impl/meters/SummariesTest.java +++ b/src/test/java/io/vertx/micrometer/impl/meters/SummariesTest.java @@ -2,6 +2,7 @@ import io.micrometer.core.instrument.DistributionSummary; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.vertx.micrometer.Label; import io.vertx.micrometer.Match; @@ -9,8 +10,10 @@ import io.vertx.micrometer.backends.BackendRegistries; import org.junit.Test; +import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -65,4 +68,15 @@ public void shouldIgnoreSummaryLabel() { s = registry.find("my_summary").tags("address", "addr2").summary(); assertThat(s).isNull(); } + + @Test + public void shouldAddCustomTags() { + List customTags = Arrays.asList(Tag.of("k1", "v1"), Tag.of("k2", "v2")); + MeterRegistry registry = new SimpleMeterRegistry(); + Summaries summaries = new Summaries("my_summary", "", registry, Label.EB_ADDRESS); + summaries.get(customTags, "addr1").record(5); + + DistributionSummary s = registry.find("my_summary").tags("address", "addr1", "k1", "v1", "k2", "v2").summary(); + assertThat(s.count()).isEqualTo(1); + } } diff --git a/src/test/java/io/vertx/micrometer/impl/meters/TimersTest.java b/src/test/java/io/vertx/micrometer/impl/meters/TimersTest.java index 56e68dc7..7ca7947b 100644 --- a/src/test/java/io/vertx/micrometer/impl/meters/TimersTest.java +++ b/src/test/java/io/vertx/micrometer/impl/meters/TimersTest.java @@ -1,6 +1,7 @@ package io.vertx.micrometer.impl.meters; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Timer; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.vertx.micrometer.Label; @@ -9,8 +10,10 @@ import io.vertx.micrometer.backends.BackendRegistries; import org.junit.Test; +import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; +import java.util.List; import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; @@ -66,4 +69,15 @@ public void shouldIgnoreTimerLabel() { t = registry.find("my_timer").tags("address", "addr2").timer(); assertThat(t).isNull(); } + + @Test + public void shouldAddCustomTags() { + List customTags = Arrays.asList(Tag.of("k1", "v1"), Tag.of("k2", "v2")); + MeterRegistry registry = new SimpleMeterRegistry(); + Timers timers = new Timers("my_timer", "", registry, Label.EB_ADDRESS); + timers.get(customTags, "addr1").record(5, TimeUnit.MILLISECONDS); + + Timer t = registry.find("my_timer").tags("address", "addr1", "k1", "v1", "k2", "v2").timer(); + assertThat(t).isNotNull(); + } } diff --git a/src/test/java/io/vertx/micrometer/service/MetricsServiceImplTest.java b/src/test/java/io/vertx/micrometer/service/MetricsServiceImplTest.java index faf2cf74..fce5883c 100644 --- a/src/test/java/io/vertx/micrometer/service/MetricsServiceImplTest.java +++ b/src/test/java/io/vertx/micrometer/service/MetricsServiceImplTest.java @@ -105,7 +105,8 @@ public void shouldGetCompleteSnapshot(TestContext ctx) { "vertx.http.server.request.bytes", "vertx.http.server.requests", "vertx.http.server.response.bytes", - "vertx.http.server.response.time" + "vertx.http.server.response.time", + "vertx.net.client.active.connections" ); assertThat(snapshot).flatExtracting(e -> (List) ((JsonArray) (e.getValue())).getList())