longGauges;
83 | synchronized (longGaugesByRegistry) {
84 | longGauges = longGaugesByRegistry.computeIfAbsent(backendRegistry.getMeterRegistry(), meterRegistry -> new ConcurrentHashMap<>());
85 | }
86 | VertxMetricsImpl metrics = new VertxMetricsImpl(options, backendRegistry, new LongGauges(longGauges));
87 | metrics.init();
88 |
89 | return metrics;
90 | }
91 |
92 | @Override
93 | public MetricsOptions newOptions(MetricsOptions options) {
94 | if (options instanceof MicrometerMetricsOptions) {
95 | return new MicrometerMetricsOptions((MicrometerMetricsOptions) options);
96 | } else {
97 | return VertxMetricsFactory.super.newOptions(options);
98 | }
99 | }
100 |
101 | @Override
102 | public MetricsOptions newOptions() {
103 | return newOptions((JsonObject) null);
104 | }
105 |
106 | @Override
107 | public MetricsOptions newOptions(JsonObject jsonObject) {
108 | return jsonObject == null ? new MicrometerMetricsOptions() : new MicrometerMetricsOptions(jsonObject);
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/micrometer/PrometheusRequestHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Red Hat licenses this file to you under the Apache License, version 2.0
5 | * (the "License"); you may not use this file except in compliance with the
6 | * License. You may obtain a copy of the License at:
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | package io.vertx.micrometer;
18 | import io.micrometer.prometheusmetrics.PrometheusMeterRegistry;
19 | import io.vertx.codegen.annotations.GenIgnore;
20 | import io.vertx.codegen.annotations.VertxGen;
21 | import io.vertx.core.Handler;
22 | import io.vertx.core.http.HttpServerRequest;
23 | import io.vertx.micrometer.impl.PrometheusRequestHandlerImpl;
24 |
25 | /**
26 | * An interface for creating handlers to expose Prometheus metrics via an HTTP endpoint.
27 | *
28 | * This interface provides factory methods to create handlers that can scrape metrics from a
29 | * PrometheusMeterRegistry and serve them over HTTP. It allows for various configurations of
30 | * the metrics endpoint and the Prometheus registry.
31 | *
32 | *
33 | * @see PrometheusMeterRegistry
34 | * @see Handler
35 | * @see HttpServerRequest
36 | *
37 | * @author Swamy Mavuri
38 | */
39 | @VertxGen
40 | public interface PrometheusRequestHandler {
41 |
42 | /**
43 | * Creates a handler with the specified PrometheusMeterRegistry and metrics endpoint.
44 | *
45 | * This handler scrapes metrics from the given PrometheusMeterRegistry and serves them
46 | * at the specified endpoint.
47 | *
48 | *
49 | * @param registry the PrometheusMeterRegistry to use for scraping metrics
50 | * @param metricsEndpoint the endpoint to expose metrics
51 | * @return a handler for scraping Prometheus metrics
52 | */
53 | @GenIgnore(GenIgnore.PERMITTED_TYPE)
54 | static Handler create(PrometheusMeterRegistry registry, String metricsEndpoint) {
55 | return new PrometheusRequestHandlerImpl(registry, metricsEndpoint);
56 | }
57 |
58 | /**
59 | * Creates a handler with the specified PrometheusMeterRegistry and the default metrics endpoint ("/metrics").
60 | *
61 | * This handler scrapes metrics from the given PrometheusMeterRegistry and serves them
62 | * at the default endpoint "/metrics".
63 | *
64 | *
65 | * @param registry the PrometheusMeterRegistry to use for scraping metrics
66 | * @return a handler for scraping Prometheus metrics
67 | */
68 | @GenIgnore(GenIgnore.PERMITTED_TYPE)
69 | static Handler create(PrometheusMeterRegistry registry) {
70 | return new PrometheusRequestHandlerImpl(registry);
71 | }
72 |
73 | /**
74 | * Creates a handler with a new PrometheusMeterRegistry and the default metrics endpoint ("/metrics").
75 | *
76 | * This handler scrapes metrics from a newly created PrometheusMeterRegistry and serves them
77 | * at the default endpoint "/metrics".
78 | *
79 | *
80 | * @return a handler for scraping Prometheus metrics
81 | */
82 | static Handler create() {
83 | return new PrometheusRequestHandlerImpl();
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/micrometer/PrometheusScrapingHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Red Hat licenses this file to you under the Apache License, version 2.0
5 | * (the "License"); you may not use this file except in compliance with the
6 | * License. You may obtain a copy of the License at:
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | package io.vertx.micrometer;
18 |
19 | import io.micrometer.prometheusmetrics.PrometheusMeterRegistry;
20 | import io.vertx.codegen.annotations.GenIgnore;
21 | import io.vertx.codegen.annotations.VertxGen;
22 | import io.vertx.core.Handler;
23 | import io.vertx.ext.web.RoutingContext;
24 | import io.vertx.micrometer.backends.BackendRegistries;
25 | import io.vertx.micrometer.impl.PrometheusScrapingHandlerImpl;
26 |
27 | import static io.vertx.codegen.annotations.GenIgnore.*;
28 |
29 | /**
30 | * A Vert.x Web {@link io.vertx.ext.web.Route} handler for Prometheus metrics scraping.
31 | *
32 | * @author Thomas Segismont
33 | */
34 | @VertxGen
35 | public interface PrometheusScrapingHandler {
36 |
37 | /**
38 | * Creates a Vert.x Web {@link io.vertx.ext.web.Route} handler for Prometheus metrics scraping.
39 | * The default backend registry is used.
40 | *
41 | * @return a {@link io.vertx.ext.web.Route} handler for the default backend registry
42 | * @see BackendRegistries#getDefaultNow()
43 | */
44 | static Handler create() {
45 | return new PrometheusScrapingHandlerImpl();
46 | }
47 |
48 | /**
49 | * Creates a Vert.x Web {@link io.vertx.ext.web.Route} handler for Prometheus metrics scraping.
50 | * The registry specified by {@code registryName} is used.
51 | *
52 | * @param registryName the backend metrics registry
53 | * @return a {@link io.vertx.ext.web.Route} handler for a specific metrics registry
54 | * @see BackendRegistries#getNow(String)
55 | */
56 | static Handler create(String registryName) {
57 | return new PrometheusScrapingHandlerImpl(registryName);
58 | }
59 |
60 | /**
61 | * Creates a Vert.x Web {@link io.vertx.ext.web.Route} handler for Prometheus metrics scraping.
62 | * The registry specified by {@code registry} is used.
63 | *
64 | * @param registry the backend metrics registry
65 | * @return a {@link io.vertx.ext.web.Route} handler for a specific metrics registry
66 | */
67 | @GenIgnore(PERMITTED_TYPE)
68 | static Handler create(PrometheusMeterRegistry registry) {
69 | return new PrometheusScrapingHandlerImpl(registry);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/micrometer/VertxJmxMetricsOptions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc. and/or its affiliates
3 | * and other contributors as indicated by the @author tags.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.vertx.micrometer;
18 |
19 | import io.micrometer.jmx.JmxConfig;
20 | import io.vertx.codegen.annotations.DataObject;
21 | import io.vertx.codegen.json.annotations.JsonGen;
22 | import io.vertx.core.json.JsonObject;
23 |
24 | import java.time.Duration;
25 |
26 | /**
27 | * Options for Prometheus metrics backend.
28 | *
29 | * @author Joel Takvorian
30 | */
31 | @DataObject
32 | @JsonGen(publicConverter = false, inheritConverter = true)
33 | public class VertxJmxMetricsOptions {
34 |
35 | /**
36 | * Default value for enabled = false.
37 | */
38 | public static final boolean DEFAULT_ENABLED = false;
39 |
40 | /**
41 | * Default value for the domain = metrics.
42 | */
43 | public static final String DEFAULT_DOMAIN = "metrics";
44 |
45 | /**
46 | * Default value for metric collection interval (in seconds) = 10.
47 | */
48 | public static final int DEFAULT_STEP = 10;
49 |
50 | private boolean enabled;
51 | private String domain;
52 | private int step;
53 |
54 | /**
55 | * Default constructor
56 | */
57 | public VertxJmxMetricsOptions() {
58 | enabled = DEFAULT_ENABLED;
59 | domain = DEFAULT_DOMAIN;
60 | step = DEFAULT_STEP;
61 | }
62 |
63 | /**
64 | * Copy constructor
65 | *
66 | * @param other The other {@link VertxJmxMetricsOptions} to copy when creating this
67 | */
68 | public VertxJmxMetricsOptions(VertxJmxMetricsOptions other) {
69 | enabled = other.enabled;
70 | domain = other.domain;
71 | step = other.step;
72 | }
73 |
74 | /**
75 | * Create an instance from a {@link JsonObject}
76 | *
77 | * @param json the JsonObject to create it from
78 | */
79 | public VertxJmxMetricsOptions(JsonObject json) {
80 | this();
81 | VertxJmxMetricsOptionsConverter.fromJson(json, this);
82 | }
83 |
84 | /**
85 | * @return a JSON representation of these options
86 | */
87 | public JsonObject toJson() {
88 | JsonObject json = new JsonObject();
89 | VertxJmxMetricsOptionsConverter.toJson(this, json);
90 | return json;
91 | }
92 |
93 | /**
94 | * Will JMX reporting be enabled?
95 | *
96 | * @return true if enabled, false if not.
97 | */
98 | public boolean isEnabled() {
99 | return enabled;
100 | }
101 |
102 | /**
103 | * Set true to enable Prometheus reporting
104 | */
105 | public VertxJmxMetricsOptions setEnabled(boolean enabled) {
106 | this.enabled = enabled;
107 | return this;
108 | }
109 |
110 | /**
111 | * Get the JMX domain under which metrics are published
112 | */
113 | public String getDomain() {
114 | return domain;
115 | }
116 |
117 | /**
118 | * Set the JMX domain under which to publish metrics
119 | */
120 | public VertxJmxMetricsOptions setDomain(String domain) {
121 | this.domain = domain;
122 | return this;
123 | }
124 |
125 | /**
126 | * Get the step of push intervals, in seconds
127 | */
128 | public int getStep() {
129 | return step;
130 | }
131 |
132 | /**
133 | * Push interval steps, in seconds. Default is 10 seconds.
134 | */
135 | public VertxJmxMetricsOptions setStep(int step) {
136 | this.step = step;
137 | return this;
138 | }
139 |
140 | /**
141 | * Convert these options to a Micrometer's {@code JmxConfig} object
142 | */
143 | public JmxConfig toMicrometerConfig() {
144 | return new JmxConfig() {
145 | @Override
146 | public String get(String s) {
147 | return null;
148 | }
149 |
150 | @Override
151 | public String domain() {
152 | return domain;
153 | }
154 |
155 | @Override
156 | public Duration step() {
157 | return Duration.ofSeconds(step);
158 | }
159 | };
160 |
161 | }
162 |
163 | }
164 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/micrometer/VertxPrometheusOptions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc. and/or its affiliates
3 | * and other contributors as indicated by the @author tags.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.vertx.micrometer;
18 |
19 | import io.vertx.codegen.annotations.DataObject;
20 | import io.vertx.codegen.json.annotations.JsonGen;
21 | import io.vertx.core.http.HttpServerOptions;
22 | import io.vertx.core.json.JsonObject;
23 |
24 | /**
25 | * Options for Prometheus metrics backend.
26 | *
27 | * @author Joel Takvorian
28 | */
29 | @DataObject
30 | @JsonGen(publicConverter = false, inheritConverter = true)
31 | public class VertxPrometheusOptions {
32 |
33 | /**
34 | * Default value for enabled = false.
35 | */
36 | public static final boolean DEFAULT_ENABLED = false;
37 |
38 | /**
39 | * Default value for starting an embedded server = false.
40 | */
41 | public static final boolean DEFAULT_START_EMBEDDED_SERVER = false;
42 |
43 | /**
44 | * The default metrics endpoint = /metrics when using an embedded server.
45 | */
46 | public static final String DEFAULT_EMBEDDED_SERVER_ENDPOINT = "/metrics";
47 |
48 | /**
49 | * Default value for publishing histogram quantiles = false.
50 | */
51 | public static final boolean DEFAULT_PUBLISH_QUANTILES = false;
52 |
53 | private boolean enabled;
54 | private boolean startEmbeddedServer;
55 | private HttpServerOptions embeddedServerOptions;
56 | private String embeddedServerEndpoint;
57 | private boolean publishQuantiles;
58 |
59 | /**
60 | * Default constructor
61 | */
62 | public VertxPrometheusOptions() {
63 | enabled = DEFAULT_ENABLED;
64 | startEmbeddedServer = DEFAULT_START_EMBEDDED_SERVER;
65 | embeddedServerEndpoint = DEFAULT_EMBEDDED_SERVER_ENDPOINT;
66 | publishQuantiles = DEFAULT_PUBLISH_QUANTILES;
67 | }
68 |
69 | /**
70 | * Copy constructor
71 | *
72 | * @param other The other {@link VertxPrometheusOptions} to copy when creating this
73 | */
74 | public VertxPrometheusOptions(VertxPrometheusOptions other) {
75 | enabled = other.enabled;
76 | startEmbeddedServer = other.startEmbeddedServer;
77 | embeddedServerEndpoint = other.embeddedServerEndpoint != null ? other.embeddedServerEndpoint : DEFAULT_EMBEDDED_SERVER_ENDPOINT;
78 | if (other.embeddedServerOptions != null) {
79 | embeddedServerOptions = new HttpServerOptions(other.embeddedServerOptions);
80 | }
81 | publishQuantiles = other.publishQuantiles;
82 | }
83 |
84 | /**
85 | * Create an instance from a {@link io.vertx.core.json.JsonObject}
86 | *
87 | * @param json the JsonObject to create it from
88 | */
89 | public VertxPrometheusOptions(JsonObject json) {
90 | this();
91 | VertxPrometheusOptionsConverter.fromJson(json, this);
92 | }
93 |
94 |
95 | /**
96 | * @return a JSON representation of these options
97 | */
98 | public JsonObject toJson() {
99 | JsonObject json = new JsonObject();
100 | VertxPrometheusOptionsConverter.toJson(this, json);
101 | return json;
102 | }
103 |
104 | /**
105 | * Will Prometheus reporting be enabled?
106 | *
107 | * @return true if enabled, false if not.
108 | */
109 | public boolean isEnabled() {
110 | return enabled;
111 | }
112 |
113 | /**
114 | * Set true to enable Prometheus reporting
115 | */
116 | public VertxPrometheusOptions setEnabled(boolean enabled) {
117 | this.enabled = enabled;
118 | return this;
119 | }
120 |
121 | /**
122 | * Returns true if it is configured to init an embedded web server to expose Prometheus metrics
123 | */
124 | public boolean isStartEmbeddedServer() {
125 | return startEmbeddedServer;
126 | }
127 |
128 | /**
129 | * When true, an embedded server will init to expose metrics with Prometheus format.
130 | */
131 | public VertxPrometheusOptions setStartEmbeddedServer(boolean startEmbeddedServer) {
132 | this.startEmbeddedServer = startEmbeddedServer;
133 | return this;
134 | }
135 |
136 | /**
137 | * Get the HTTP server options of the embedded server, if any
138 | */
139 | public HttpServerOptions getEmbeddedServerOptions() {
140 | return embeddedServerOptions;
141 | }
142 |
143 | /**
144 | * HTTP server options for the embedded server
145 | * @param embeddedServerOptions the server options
146 | */
147 | public VertxPrometheusOptions setEmbeddedServerOptions(HttpServerOptions embeddedServerOptions) {
148 | this.embeddedServerOptions = embeddedServerOptions;
149 | return this;
150 | }
151 |
152 | /**
153 | * Set metrics endpoint. Use conjointly with the embedded server options. Defaults to /metrics.
154 | * @param embeddedServerEndpoint metrics endpoint
155 | */
156 | public VertxPrometheusOptions setEmbeddedServerEndpoint(String embeddedServerEndpoint) {
157 | this.embeddedServerEndpoint = embeddedServerEndpoint;
158 | return this;
159 | }
160 |
161 | /**
162 | * Get the HTTP endpoint used if an embedded server is configured
163 | */
164 | public String getEmbeddedServerEndpoint() {
165 | return embeddedServerEndpoint;
166 | }
167 |
168 | /**
169 | * @return true if quantile stats are published
170 | */
171 | public boolean isPublishQuantiles() {
172 | return publishQuantiles;
173 | }
174 |
175 | /**
176 | * Set true to publish histogram stats, necessary to compute quantiles.
177 | * Note that it generates many new timeseries for stats, which is why it is deactivated by default.
178 | *
179 | * @param publishQuantiles the publishing quantiles flag
180 | * @return a reference to this, so the API can be used fluently
181 | */
182 | public VertxPrometheusOptions setPublishQuantiles(boolean publishQuantiles) {
183 | this.publishQuantiles = publishQuantiles;
184 | return this;
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/micrometer/backends/BackendRegistries.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Red Hat, Inc. and/or its affiliates
3 | * and other contributors as indicated by the @author tags.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.vertx.micrometer.backends;
18 |
19 | import io.micrometer.core.instrument.Meter;
20 | import io.micrometer.core.instrument.MeterRegistry;
21 | import io.micrometer.core.instrument.config.MeterFilter;
22 | import io.micrometer.prometheusmetrics.PrometheusMeterRegistry;
23 | import io.vertx.micrometer.*;
24 |
25 | import java.util.List;
26 | import java.util.Map;
27 | import java.util.concurrent.ConcurrentHashMap;
28 | import java.util.function.Function;
29 | import java.util.regex.Pattern;
30 |
31 | /**
32 | * {@link BackendRegistries} is responsible for managing registries related to particular micrometer backends (influxdb, prometheus...)
33 | * It contains a store of {@link BackendRegistry} objects, each of whose encapsulating a micrometer's {@link MeterRegistry}
34 | * @author Joel Takvorian
35 | */
36 | public final class BackendRegistries {
37 | private static final Map REGISTRIES = new ConcurrentHashMap<>();
38 |
39 | private BackendRegistries() {
40 | }
41 |
42 | /**
43 | * Create a new backend registry, containing a micrometer registry, initialized with the provided options.
44 | * If a registry already exists with the associated name, it is just returned without any effect.
45 | * @param options micrometer options, including configuration related to the backend.
46 | * Should be a subclass of {@link MicrometerMetricsOptions} (ex: {@link VertxInfluxDbOptions}, {@link VertxPrometheusOptions}).
47 | * If the class is not recognized, a {@link NoopBackendRegistry} will be returned.
48 | * @return the created (or existing) {@link BackendRegistry}
49 | */
50 | public static BackendRegistry setupBackend(MicrometerMetricsOptions options, MeterRegistry meterRegistry) {
51 | return REGISTRIES.computeIfAbsent(options.getRegistryName(), k -> {
52 | final BackendRegistry reg;
53 | if (meterRegistry != null) {
54 | if (options.getPrometheusOptions() != null && meterRegistry instanceof PrometheusMeterRegistry) {
55 | // If a Prometheus registry is provided, extra initialization steps may have to be performed
56 | reg = new PrometheusBackendRegistry(options.getPrometheusOptions(), (PrometheusMeterRegistry) meterRegistry);
57 | } else {
58 | // Other backend registries have no special extra steps
59 | reg = () -> meterRegistry;
60 | }
61 | } else if (options.getInfluxDbOptions() != null && options.getInfluxDbOptions().isEnabled()) {
62 | reg = new InfluxDbBackendRegistry(options.getInfluxDbOptions());
63 | } else if (options.getPrometheusOptions() != null && options.getPrometheusOptions().isEnabled()) {
64 | reg = new PrometheusBackendRegistry(options.getPrometheusOptions());
65 | } else if (options.getJmxMetricsOptions() != null && options.getJmxMetricsOptions().isEnabled()) {
66 | reg = new JmxBackendRegistry(options.getJmxMetricsOptions());
67 | } else {
68 | // No backend setup, use global registry
69 | reg = NoopBackendRegistry.INSTANCE;
70 | }
71 | registerMatchers(reg.getMeterRegistry(), options.getLabelMatches());
72 | return reg;
73 | });
74 | }
75 |
76 | /**
77 | * Get the default micrometer registry.
78 | * May return {@code null} if it hasn't been registered yet or if it has been stopped.
79 | * @return the micrometer registry or {@code null}
80 | */
81 | public static MeterRegistry getDefaultNow() {
82 | return getNow(MicrometerMetricsOptions.DEFAULT_REGISTRY_NAME);
83 | }
84 |
85 | /**
86 | * Get the micrometer registry of the given name.
87 | * May return {@code null} if it hasn't been registered yet or if it has been stopped.
88 | * @param registryName the name associated with this registry in Micrometer options
89 | * @return the micrometer registry or {@code null}
90 | */
91 | public static MeterRegistry getNow(String registryName) {
92 | BackendRegistry backendRegistry = REGISTRIES.get(registryName);
93 | if (backendRegistry != null) {
94 | return backendRegistry.getMeterRegistry();
95 | }
96 | return null;
97 | }
98 |
99 | /**
100 | * Stop (unregister) the backend registry of the given name.
101 | * Any resource started by this backend registry will be released (like running HTTP server)
102 | * @param registryName the name associated with this registry in Micrometer options
103 | */
104 | public static void stop(String registryName) {
105 | BackendRegistry reg = REGISTRIES.remove(registryName);
106 | if (reg != null) {
107 | reg.close();
108 | }
109 | }
110 |
111 | public static void registerMatchers(MeterRegistry registry, List matches) {
112 | matches.forEach(m -> {
113 | switch (m.getType()) {
114 | case EQUALS:
115 | if (m.getAlias() == null) {
116 | // Exact match => accept
117 | registry.config().meterFilter(MeterFilter.deny(id -> {
118 | if (m.getDomain() != null && !id.getName().startsWith(m.getDomain().getPrefix())) {
119 | // If domain has been specified and we're not in that domain, ignore rule
120 | return false;
121 | }
122 | String tagValue = id.getTag(m.getLabel());
123 | return !m.getValue().equals(tagValue);
124 | }));
125 | } else {
126 | // Exact match => alias
127 | registry.config().meterFilter(replaceTagValues(
128 | m.getDomain(),
129 | m.getLabel(),
130 | val -> {
131 | if (m.getValue().equals(val)) {
132 | return m.getAlias();
133 | }
134 | return val;
135 | }
136 | ));
137 | }
138 | break;
139 | case REGEX:
140 | Pattern pattern = Pattern.compile(m.getValue());
141 | if (m.getAlias() == null) {
142 | // Regex match => accept
143 | registry.config().meterFilter(MeterFilter.accept(id -> {
144 | if (m.getDomain() != null && !id.getName().startsWith(m.getDomain().getPrefix())) {
145 | // If domain has been specified and we're not in that domain, ignore rule
146 | return true;
147 | }
148 | String tagValue = id.getTag(m.getLabel());
149 | if (tagValue == null) {
150 | return false;
151 | }
152 | return pattern.matcher(tagValue).matches();
153 | }));
154 | } else {
155 | // Regex match => alias
156 | registry.config().meterFilter(replaceTagValues(
157 | m.getDomain(),
158 | m.getLabel(),
159 | val -> {
160 | if (pattern.matcher(val).matches()) {
161 | return m.getAlias();
162 | }
163 | return val;
164 | }
165 | ));
166 | }
167 | break;
168 | }
169 | });
170 | }
171 |
172 | private static MeterFilter replaceTagValues(MetricsDomain domain, String tagKey, Function replacement) {
173 | return new MeterFilter() {
174 | @Override
175 | public Meter.Id map(Meter.Id id) {
176 | if (domain != null && !id.getName().startsWith(domain.getPrefix())) {
177 | return id;
178 | }
179 | return MeterFilter.replaceTagValues(tagKey, replacement).map(id);
180 | }
181 | };
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/micrometer/backends/BackendRegistry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc. and/or its affiliates
3 | * and other contributors as indicated by the @author tags.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.vertx.micrometer.backends;
18 |
19 | import io.micrometer.core.instrument.MeterRegistry;
20 |
21 | /**
22 | * @author Joel Takvorian
23 | */
24 | public interface BackendRegistry {
25 | MeterRegistry getMeterRegistry();
26 | default void init() {}
27 | default void close() {}
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/micrometer/backends/InfluxDbBackendRegistry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc. and/or its affiliates
3 | * and other contributors as indicated by the @author tags.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.vertx.micrometer.backends;
18 |
19 | import io.micrometer.core.instrument.Clock;
20 | import io.micrometer.core.instrument.MeterRegistry;
21 | import io.micrometer.influx.InfluxMeterRegistry;
22 | import io.vertx.micrometer.VertxInfluxDbOptions;
23 |
24 | /**
25 | * @author Joel Takvorian
26 | */
27 | public final class InfluxDbBackendRegistry implements BackendRegistry {
28 | private final InfluxMeterRegistry registry;
29 |
30 | public InfluxDbBackendRegistry(VertxInfluxDbOptions options) {
31 | registry = new InfluxMeterRegistry(options.toMicrometerConfig(), Clock.SYSTEM);
32 | registry.stop();
33 | }
34 |
35 | @Override
36 | public MeterRegistry getMeterRegistry() {
37 | return registry;
38 | }
39 |
40 | @Override
41 | public void init() {
42 | registry.start();
43 | }
44 |
45 | @Override
46 | public void close() {
47 | registry.close();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/micrometer/backends/JmxBackendRegistry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc. and/or its affiliates
3 | * and other contributors as indicated by the @author tags.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.vertx.micrometer.backends;
18 |
19 | import io.micrometer.core.instrument.Clock;
20 | import io.micrometer.core.instrument.MeterRegistry;
21 | import io.micrometer.jmx.JmxMeterRegistry;
22 | import io.vertx.micrometer.VertxJmxMetricsOptions;
23 |
24 | /**
25 | * @author Joel Takvorian
26 | */
27 | public final class JmxBackendRegistry implements BackendRegistry {
28 | private final JmxMeterRegistry registry;
29 |
30 | public JmxBackendRegistry(VertxJmxMetricsOptions options) {
31 | registry = new JmxMeterRegistry(options.toMicrometerConfig(), Clock.SYSTEM);
32 | }
33 |
34 | @Override
35 | public MeterRegistry getMeterRegistry() {
36 | return registry;
37 | }
38 |
39 | @Override
40 | public void init() {
41 | }
42 |
43 | @Override
44 | public void close() {
45 | registry.stop();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/micrometer/backends/NoopBackendRegistry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc. and/or its affiliates
3 | * and other contributors as indicated by the @author tags.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.vertx.micrometer.backends;
18 |
19 | import io.micrometer.core.instrument.MeterRegistry;
20 | import io.micrometer.core.instrument.Metrics;
21 |
22 | /**
23 | * @author Joel Takvorian
24 | */
25 | public enum NoopBackendRegistry implements BackendRegistry {
26 | INSTANCE;
27 |
28 | @Override
29 | public MeterRegistry getMeterRegistry() {
30 | return Metrics.globalRegistry;
31 | }
32 |
33 | @Override
34 | public void init() {
35 | }
36 |
37 | @Override
38 | public void close() {
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/micrometer/backends/PrometheusBackendRegistry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc. and/or its affiliates
3 | * and other contributors as indicated by the @author tags.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.vertx.micrometer.backends;
18 |
19 | import io.micrometer.core.instrument.Meter;
20 | import io.micrometer.core.instrument.MeterRegistry;
21 | import io.micrometer.core.instrument.config.MeterFilter;
22 | import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
23 | import io.micrometer.prometheusmetrics.PrometheusConfig;
24 | import io.micrometer.prometheusmetrics.PrometheusMeterRegistry;
25 | import io.vertx.core.Vertx;
26 | import io.vertx.core.http.HttpServerOptions;
27 | import io.vertx.core.internal.logging.Logger;
28 | import io.vertx.core.internal.logging.LoggerFactory;
29 | import io.vertx.micrometer.PrometheusRequestHandler;
30 | import io.vertx.micrometer.VertxPrometheusOptions;
31 |
32 | /**
33 | * @author Joel Takvorian
34 | */
35 | public final class PrometheusBackendRegistry implements BackendRegistry {
36 | private static final Logger LOGGER = LoggerFactory.getLogger(PrometheusBackendRegistry.class);
37 |
38 | private final PrometheusMeterRegistry registry;
39 | private final VertxPrometheusOptions options;
40 | private Vertx vertx;
41 |
42 | public PrometheusBackendRegistry(VertxPrometheusOptions options) {
43 | this(options, new PrometheusMeterRegistry(PrometheusConfig.DEFAULT));
44 | }
45 |
46 | public PrometheusBackendRegistry(VertxPrometheusOptions options, PrometheusMeterRegistry registry) {
47 | this.options = options;
48 | this.registry = registry;
49 | if (options.isPublishQuantiles()) {
50 | registry.config().meterFilter(
51 | new MeterFilter() {
52 | @Override
53 | public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticConfig config) {
54 | return DistributionStatisticConfig.builder()
55 | .percentilesHistogram(true)
56 | .build()
57 | .merge(config);
58 | }
59 | });
60 | }
61 | }
62 |
63 | @Override
64 | public MeterRegistry getMeterRegistry() {
65 | return registry;
66 | }
67 |
68 | @Override
69 | public void init() {
70 | if (options.isStartEmbeddedServer()) {
71 | this.vertx = Vertx.vertx();
72 | // Start dedicated server
73 | HttpServerOptions serverOptions = options.getEmbeddedServerOptions();
74 | if (serverOptions == null) {
75 | serverOptions = new HttpServerOptions();
76 | }
77 | vertx.createHttpServer(serverOptions)
78 | .requestHandler(PrometheusRequestHandler.create(registry, options.getEmbeddedServerEndpoint()))
79 | .exceptionHandler(t -> LOGGER.error("Error in Prometheus registry embedded server", t))
80 | .listen(serverOptions.getPort(), serverOptions.getHost());
81 | }
82 | }
83 |
84 | @Override
85 | public void close() {
86 | if (this.vertx != null) {
87 | vertx.close();
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/micrometer/impl/AbstractMetrics.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Red Hat, Inc.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.micrometer.impl;
18 |
19 | import io.micrometer.core.instrument.MeterRegistry;
20 | import io.vertx.micrometer.Label;
21 | import io.vertx.micrometer.MetricsDomain;
22 | import io.vertx.micrometer.MetricsNaming;
23 | import io.vertx.micrometer.impl.meters.LongGaugeBuilder;
24 | import io.vertx.micrometer.impl.meters.LongGauges;
25 |
26 | import java.util.EnumSet;
27 | import java.util.concurrent.atomic.LongAdder;
28 | import java.util.function.ToDoubleFunction;
29 |
30 | /**
31 | * Abstract class for metrics container.
32 | *
33 | * @author Joel Takvorian
34 | */
35 | public abstract class AbstractMetrics implements MicrometerMetrics {
36 |
37 | protected final MeterRegistry registry;
38 | protected final MetricsNaming names;
39 | private final String category;
40 | protected final EnumSet