├── .editorconfig ├── .github ├── maven-cd-settings.xml ├── maven-ci-settings.xml └── workflows │ ├── ci-4.x.yml │ ├── ci-5.x-stable.yml │ ├── ci-5.x.yml │ ├── ci-matrix-5.x.yml │ ├── ci.yml │ └── deploy.yml ├── .gitignore ├── LICENSE.txt ├── README.adoc ├── log-test.properties ├── pom.xml └── src ├── main ├── asciidoc │ └── index.adoc ├── generated │ └── io │ │ └── vertx │ │ └── micrometer │ │ ├── MetricsNamingConverter.java │ │ ├── MicrometerMetricsOptionsConverter.java │ │ ├── VertxInfluxDbOptionsConverter.java │ │ ├── VertxJmxMetricsOptionsConverter.java │ │ └── VertxPrometheusOptionsConverter.java ├── java │ ├── examples │ │ └── MicrometerMetricsExamples.java │ ├── io │ │ └── vertx │ │ │ └── micrometer │ │ │ ├── Label.java │ │ │ ├── Match.java │ │ │ ├── MatchType.java │ │ │ ├── MetricsDomain.java │ │ │ ├── MetricsNaming.java │ │ │ ├── MetricsService.java │ │ │ ├── MicrometerMetricsFactory.java │ │ │ ├── MicrometerMetricsOptions.java │ │ │ ├── PrometheusRequestHandler.java │ │ │ ├── PrometheusScrapingHandler.java │ │ │ ├── VertxInfluxDbOptions.java │ │ │ ├── VertxJmxMetricsOptions.java │ │ │ ├── VertxPrometheusOptions.java │ │ │ ├── backends │ │ │ ├── BackendRegistries.java │ │ │ ├── BackendRegistry.java │ │ │ ├── InfluxDbBackendRegistry.java │ │ │ ├── JmxBackendRegistry.java │ │ │ ├── NoopBackendRegistry.java │ │ │ └── PrometheusBackendRegistry.java │ │ │ ├── impl │ │ │ ├── AbstractMetrics.java │ │ │ ├── HttpUtils.java │ │ │ ├── MetricsServiceImpl.java │ │ │ ├── MicrometerMetrics.java │ │ │ ├── PrometheusRequestHandlerImpl.java │ │ │ ├── PrometheusScrapingHandlerImpl.java │ │ │ ├── VertxClientMetrics.java │ │ │ ├── VertxDatagramSocketMetrics.java │ │ │ ├── VertxEventBusMetrics.java │ │ │ ├── VertxHttpClientMetrics.java │ │ │ ├── VertxHttpServerMetrics.java │ │ │ ├── VertxMetricsImpl.java │ │ │ ├── VertxNetClientMetrics.java │ │ │ ├── VertxNetServerMetrics.java │ │ │ ├── VertxPoolMetrics.java │ │ │ ├── meters │ │ │ │ ├── LongAdderSupplier.java │ │ │ │ ├── LongGaugeBuilder.java │ │ │ │ └── LongGauges.java │ │ │ └── tags │ │ │ │ └── Labels.java │ │ │ └── package-info.java │ └── module-info.java └── resources │ └── META-INF │ └── services │ └── io.vertx.core.spi.VertxServiceProvider └── test └── java └── io └── vertx └── micrometer └── tests ├── EmptyCompositeMeterRegistryTest.java ├── ExternalConfigurationTest.java ├── MatchersTest.java ├── MetricsNamingTest.java ├── MicrometerMetricsTestBase.java ├── MyVerticle.java ├── UnixSocketTest.java ├── VertxClientMetricsTest.java ├── VertxDatagramNetClientNetServerSocketMetricsTest.java ├── VertxEventBusMetricsTest.java ├── VertxHttpClientServerMetricsTest.java ├── VertxHttpServerMetricsConfigTest.java ├── VertxHttpServerMetricsTest.java ├── VertxNetClientServerMetricsTest.java ├── VertxPoolMetricsTest.java ├── backend ├── CustomMicrometerMetricsITest.java ├── InfluxDbReporterITest.java ├── InfluxDbTestHelper.java ├── JmxMetricsITest.java ├── PrometheusMetricsITest.java └── PrometheusTestHelper.java ├── impl └── meters │ ├── CountersTest.java │ ├── GaugesTest.java │ ├── SummariesTest.java │ └── TimersTest.java └── service └── MetricsServiceImplTest.java /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | trim_trailing_whitespace = true 8 | end_of_line = lf 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.github/maven-cd-settings.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | false 20 | 21 | 22 | 23 | vertx-snapshots-repository 24 | ${env.VERTX_NEXUS_USERNAME} 25 | ${env.VERTX_NEXUS_PASSWORD} 26 | 27 | 28 | 29 | 30 | 31 | google-mirror 32 | 33 | true 34 | 35 | 36 | 37 | google-maven-central 38 | GCS Maven Central mirror EU 39 | https://maven-central.storage-download.googleapis.com/maven2/ 40 | 41 | true 42 | 43 | 44 | false 45 | 46 | 47 | 48 | 49 | 50 | google-maven-central 51 | GCS Maven Central mirror 52 | https://maven-central.storage-download.googleapis.com/maven2/ 53 | 54 | true 55 | 56 | 57 | false 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /.github/maven-ci-settings.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | false 20 | 21 | 22 | 23 | google-mirror 24 | 25 | true 26 | 27 | 28 | 29 | google-maven-central 30 | GCS Maven Central mirror EU 31 | https://maven-central.storage-download.googleapis.com/maven2/ 32 | 33 | true 34 | 35 | 36 | false 37 | 38 | 39 | 40 | 41 | 42 | google-maven-central 43 | GCS Maven Central mirror 44 | https://maven-central.storage-download.googleapis.com/maven2/ 45 | 46 | true 47 | 48 | 49 | false 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /.github/workflows/ci-4.x.yml: -------------------------------------------------------------------------------- 1 | name: vertx-micrometer-metrics (4.x) 2 | on: 3 | schedule: 4 | - cron: '0 4 * * *' 5 | jobs: 6 | CI: 7 | strategy: 8 | matrix: 9 | include: 10 | - os: ubuntu-latest 11 | jdk: 8 12 | - os: ubuntu-latest 13 | jdk: 17 14 | uses: ./.github/workflows/ci.yml 15 | with: 16 | branch: 4.x 17 | jdk: ${{ matrix.jdk }} 18 | os: ${{ matrix.os }} 19 | secrets: inherit 20 | Deploy: 21 | if: ${{ github.repository_owner == 'vert-x3' && (github.event_name == 'push' || github.event_name == 'schedule') }} 22 | needs: CI 23 | uses: ./.github/workflows/deploy.yml 24 | with: 25 | branch: 4.x 26 | jdk: 8 27 | secrets: inherit 28 | -------------------------------------------------------------------------------- /.github/workflows/ci-5.x-stable.yml: -------------------------------------------------------------------------------- 1 | name: vertx-micrometer-metrics (5.x-stable) 2 | on: 3 | push: 4 | branches: 5 | - '5.[0-9]+' 6 | pull_request: 7 | branches: 8 | - '5.[0-9]+' 9 | schedule: 10 | - cron: '0 6 * * *' 11 | jobs: 12 | CI-CD: 13 | uses: ./.github/workflows/ci-matrix-5.x.yml 14 | secrets: inherit 15 | with: 16 | branch: ${{ github.event_name == 'schedule' && vars.VERTX_5_STABLE_BRANCH || github.event.pull_request.head.sha || github.ref_name }} 17 | -------------------------------------------------------------------------------- /.github/workflows/ci-5.x.yml: -------------------------------------------------------------------------------- 1 | name: vertx-micrometer-metrics (5.x) 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | branches: 8 | - master 9 | schedule: 10 | - cron: '0 5 * * *' 11 | jobs: 12 | CI-CD: 13 | uses: ./.github/workflows/ci-matrix-5.x.yml 14 | secrets: inherit 15 | with: 16 | branch: ${{ github.event.pull_request.head.sha || github.ref_name }} 17 | -------------------------------------------------------------------------------- /.github/workflows/ci-matrix-5.x.yml: -------------------------------------------------------------------------------- 1 | name: CI matrix (5.x) 2 | on: 3 | workflow_call: 4 | inputs: 5 | branch: 6 | required: true 7 | type: string 8 | jobs: 9 | CI: 10 | strategy: 11 | matrix: 12 | include: 13 | - os: ubuntu-latest 14 | jdk: 11 15 | - os: ubuntu-latest 16 | jdk: 21 17 | uses: ./.github/workflows/ci.yml 18 | with: 19 | branch: ${{ inputs.branch }} 20 | jdk: ${{ matrix.jdk }} 21 | os: ${{ matrix.os }} 22 | secrets: inherit 23 | Deploy: 24 | if: ${{ github.repository_owner == 'vert-x3' && (github.event_name == 'push' || github.event_name == 'schedule') }} 25 | needs: CI 26 | uses: ./.github/workflows/deploy.yml 27 | with: 28 | branch: ${{ inputs.branch }} 29 | jdk: 11 30 | secrets: inherit 31 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | workflow_call: 4 | inputs: 5 | branch: 6 | required: true 7 | type: string 8 | jdk: 9 | default: 8 10 | type: string 11 | os: 12 | default: ubuntu-latest 13 | type: string 14 | jobs: 15 | Test: 16 | name: Run tests 17 | runs-on: ${{ inputs.os }} 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v2 21 | with: 22 | ref: ${{ inputs.branch }} 23 | - name: Install JDK 24 | uses: actions/setup-java@v2 25 | with: 26 | java-version: ${{ inputs.jdk }} 27 | distribution: temurin 28 | - name: Run tests 29 | run: mvn -s .github/maven-ci-settings.xml -q clean verify -B 30 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | on: 3 | workflow_call: 4 | inputs: 5 | branch: 6 | required: true 7 | type: string 8 | jdk: 9 | default: 8 10 | type: string 11 | jobs: 12 | Deploy: 13 | name: Deploy to OSSRH 14 | runs-on: ubuntu-latest 15 | env: 16 | VERTX_NEXUS_USERNAME: ${{ secrets.VERTX_NEXUS_USERNAME }} 17 | VERTX_NEXUS_PASSWORD: ${{ secrets.VERTX_NEXUS_PASSWORD }} 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v2 21 | with: 22 | ref: ${{ inputs.branch }} 23 | - name: Install JDK 24 | uses: actions/setup-java@v2 25 | with: 26 | java-version: ${{ inputs.jdk }} 27 | distribution: temurin 28 | - name: Get project version 29 | run: echo "PROJECT_VERSION=$(mvn org.apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.version -q -DforceStdout | grep -v '\[')" >> $GITHUB_ENV 30 | - name: Maven deploy 31 | if: ${{ endsWith(env.PROJECT_VERSION, '-SNAPSHOT') }} 32 | run: mvn deploy -s .github/maven-cd-settings.xml -DskipTests -B 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .gradle 3 | .idea 4 | .classpath 5 | .project 6 | .settings 7 | .yardoc 8 | .yardopts 9 | build 10 | target 11 | out 12 | *.iml 13 | *.ipr 14 | *.iws 15 | .vertx 16 | test-output 17 | src/scratchpad 18 | test-results 19 | test-tmp 20 | *.class 21 | *.swp 22 | .vertx 23 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = vertx-micrometer-metrics 2 | :source-language: java 3 | 4 | image:https://github.com/vert-x3/vertx-micrometer-metrics/actions/workflows/ci-5.x.yml/badge.svg["Build Status (5.x)",link="https://github.com/vert-x3/vertx-micrometer-metrics/actions/workflows/ci-5.x.yml"] 5 | image:https://github.com/vert-x3/vertx-micrometer-metrics/actions/workflows/ci-4.x.yml/badge.svg["Build Status (4.x)",link="https://github.com/vert-x3/vertx-micrometer-metrics/actions/workflows/ci-4.x.yml"] 6 | 7 | Vert.x Micrometer Metrics contains metrics collection and reporting to various target systems through link:http://micrometer.io/[Micrometer]. 8 | 9 | The http://vertx.io/docs/vertx-core/java/index.html#_metrics_spi[Vert.x Metrics SPI] allows implementers to 10 | capture events from Vert.x in order to gather metrics. 11 | 12 | Please see the https://vertx.io/docs/vertx-micrometer-metrics/java/[documentation] 13 | on the web-site for a full description. 14 | -------------------------------------------------------------------------------- /log-test.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015 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 | handlers=java.util.logging.ConsoleHandler 18 | 19 | .level=INFO 20 | 21 | java.util.logging.ConsoleHandler.level=ALL 22 | java.util.logging.ConsoleHandler.formatter=io.vertx.core.logging.VertxLoggerFormatter 23 | 24 | io.vertx.micrometer.level=ALL 25 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/micrometer/MicrometerMetricsOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.micrometer; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.micrometer.MicrometerMetricsOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.micrometer.MicrometerMetricsOptions} original class using Vert.x codegen. 11 | */ 12 | public class MicrometerMetricsOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, MicrometerMetricsOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | case "enabled": 18 | if (member.getValue() instanceof Boolean) { 19 | obj.setEnabled((Boolean)member.getValue()); 20 | } 21 | break; 22 | case "disabledMetricsCategories": 23 | if (member.getValue() instanceof JsonArray) { 24 | java.util.LinkedHashSet list = new java.util.LinkedHashSet<>(); 25 | ((Iterable)member.getValue()).forEach( item -> { 26 | if (item instanceof String) 27 | list.add((String)item); 28 | }); 29 | obj.setDisabledMetricsCategories(list); 30 | } 31 | break; 32 | case "registryName": 33 | if (member.getValue() instanceof String) { 34 | obj.setRegistryName((String)member.getValue()); 35 | } 36 | break; 37 | case "labels": 38 | if (member.getValue() instanceof JsonArray) { 39 | java.util.LinkedHashSet list = new java.util.LinkedHashSet<>(); 40 | ((Iterable)member.getValue()).forEach( item -> { 41 | if (item instanceof String) 42 | list.add(io.vertx.micrometer.Label.valueOf((String)item)); 43 | }); 44 | obj.setLabels(list); 45 | } 46 | break; 47 | case "labelMatches": 48 | if (member.getValue() instanceof JsonArray) { 49 | java.util.ArrayList list = new java.util.ArrayList<>(); 50 | ((Iterable)member.getValue()).forEach( item -> { 51 | if (item instanceof JsonObject) 52 | list.add(new io.vertx.micrometer.Match((io.vertx.core.json.JsonObject)item)); 53 | }); 54 | obj.setLabelMatches(list); 55 | } 56 | break; 57 | case "labelMatchs": 58 | if (member.getValue() instanceof JsonArray) { 59 | ((Iterable)member.getValue()).forEach( item -> { 60 | if (item instanceof JsonObject) 61 | obj.addLabelMatch(new io.vertx.micrometer.Match((io.vertx.core.json.JsonObject)item)); 62 | }); 63 | } 64 | break; 65 | case "influxDbOptions": 66 | if (member.getValue() instanceof JsonObject) { 67 | obj.setInfluxDbOptions(new io.vertx.micrometer.VertxInfluxDbOptions((io.vertx.core.json.JsonObject)member.getValue())); 68 | } 69 | break; 70 | case "prometheusOptions": 71 | if (member.getValue() instanceof JsonObject) { 72 | obj.setPrometheusOptions(new io.vertx.micrometer.VertxPrometheusOptions((io.vertx.core.json.JsonObject)member.getValue())); 73 | } 74 | break; 75 | case "jmxMetricsOptions": 76 | if (member.getValue() instanceof JsonObject) { 77 | obj.setJmxMetricsOptions(new io.vertx.micrometer.VertxJmxMetricsOptions((io.vertx.core.json.JsonObject)member.getValue())); 78 | } 79 | break; 80 | case "jvmMetricsEnabled": 81 | if (member.getValue() instanceof Boolean) { 82 | obj.setJvmMetricsEnabled((Boolean)member.getValue()); 83 | } 84 | break; 85 | case "nettyMetricsEnabled": 86 | if (member.getValue() instanceof Boolean) { 87 | obj.setNettyMetricsEnabled((Boolean)member.getValue()); 88 | } 89 | break; 90 | case "metricsNaming": 91 | if (member.getValue() instanceof JsonObject) { 92 | obj.setMetricsNaming(new io.vertx.micrometer.MetricsNaming((io.vertx.core.json.JsonObject)member.getValue())); 93 | } 94 | break; 95 | case "meterCacheEnabled": 96 | if (member.getValue() instanceof Boolean) { 97 | obj.setMeterCacheEnabled((Boolean)member.getValue()); 98 | } 99 | break; 100 | } 101 | } 102 | } 103 | 104 | static void toJson(MicrometerMetricsOptions obj, JsonObject json) { 105 | toJson(obj, json.getMap()); 106 | } 107 | 108 | static void toJson(MicrometerMetricsOptions obj, java.util.Map json) { 109 | json.put("enabled", obj.isEnabled()); 110 | if (obj.getDisabledMetricsCategories() != null) { 111 | JsonArray array = new JsonArray(); 112 | obj.getDisabledMetricsCategories().forEach(item -> array.add(item)); 113 | json.put("disabledMetricsCategories", array); 114 | } 115 | if (obj.getRegistryName() != null) { 116 | json.put("registryName", obj.getRegistryName()); 117 | } 118 | if (obj.getLabels() != null) { 119 | JsonArray array = new JsonArray(); 120 | obj.getLabels().forEach(item -> array.add(item.name())); 121 | json.put("labels", array); 122 | } 123 | if (obj.getInfluxDbOptions() != null) { 124 | json.put("influxDbOptions", obj.getInfluxDbOptions().toJson()); 125 | } 126 | if (obj.getPrometheusOptions() != null) { 127 | json.put("prometheusOptions", obj.getPrometheusOptions().toJson()); 128 | } 129 | if (obj.getJmxMetricsOptions() != null) { 130 | json.put("jmxMetricsOptions", obj.getJmxMetricsOptions().toJson()); 131 | } 132 | json.put("jvmMetricsEnabled", obj.isJvmMetricsEnabled()); 133 | json.put("nettyMetricsEnabled", obj.isNettyMetricsEnabled()); 134 | if (obj.getMetricsNaming() != null) { 135 | json.put("metricsNaming", obj.getMetricsNaming().toJson()); 136 | } 137 | json.put("meterCacheEnabled", obj.isMeterCacheEnabled()); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/micrometer/VertxInfluxDbOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.micrometer; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.micrometer.VertxInfluxDbOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.micrometer.VertxInfluxDbOptions} original class using Vert.x codegen. 11 | */ 12 | public class VertxInfluxDbOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, VertxInfluxDbOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | case "enabled": 18 | if (member.getValue() instanceof Boolean) { 19 | obj.setEnabled((Boolean)member.getValue()); 20 | } 21 | break; 22 | case "uri": 23 | if (member.getValue() instanceof String) { 24 | obj.setUri((String)member.getValue()); 25 | } 26 | break; 27 | case "db": 28 | if (member.getValue() instanceof String) { 29 | obj.setDb((String)member.getValue()); 30 | } 31 | break; 32 | case "userName": 33 | if (member.getValue() instanceof String) { 34 | obj.setUserName((String)member.getValue()); 35 | } 36 | break; 37 | case "password": 38 | if (member.getValue() instanceof String) { 39 | obj.setPassword((String)member.getValue()); 40 | } 41 | break; 42 | case "retentionPolicy": 43 | if (member.getValue() instanceof String) { 44 | obj.setRetentionPolicy((String)member.getValue()); 45 | } 46 | break; 47 | case "compressed": 48 | if (member.getValue() instanceof Boolean) { 49 | obj.setCompressed((Boolean)member.getValue()); 50 | } 51 | break; 52 | case "step": 53 | if (member.getValue() instanceof Number) { 54 | obj.setStep(((Number)member.getValue()).intValue()); 55 | } 56 | break; 57 | case "connectTimeout": 58 | if (member.getValue() instanceof Number) { 59 | obj.setConnectTimeout(((Number)member.getValue()).intValue()); 60 | } 61 | break; 62 | case "readTimeout": 63 | if (member.getValue() instanceof Number) { 64 | obj.setReadTimeout(((Number)member.getValue()).intValue()); 65 | } 66 | break; 67 | case "batchSize": 68 | if (member.getValue() instanceof Number) { 69 | obj.setBatchSize(((Number)member.getValue()).intValue()); 70 | } 71 | break; 72 | case "org": 73 | if (member.getValue() instanceof String) { 74 | obj.setOrg((String)member.getValue()); 75 | } 76 | break; 77 | case "bucket": 78 | if (member.getValue() instanceof String) { 79 | obj.setBucket((String)member.getValue()); 80 | } 81 | break; 82 | case "token": 83 | if (member.getValue() instanceof String) { 84 | obj.setToken((String)member.getValue()); 85 | } 86 | break; 87 | } 88 | } 89 | } 90 | 91 | static void toJson(VertxInfluxDbOptions obj, JsonObject json) { 92 | toJson(obj, json.getMap()); 93 | } 94 | 95 | static void toJson(VertxInfluxDbOptions obj, java.util.Map json) { 96 | json.put("enabled", obj.isEnabled()); 97 | if (obj.getUri() != null) { 98 | json.put("uri", obj.getUri()); 99 | } 100 | if (obj.getDb() != null) { 101 | json.put("db", obj.getDb()); 102 | } 103 | if (obj.getUserName() != null) { 104 | json.put("userName", obj.getUserName()); 105 | } 106 | if (obj.getPassword() != null) { 107 | json.put("password", obj.getPassword()); 108 | } 109 | if (obj.getRetentionPolicy() != null) { 110 | json.put("retentionPolicy", obj.getRetentionPolicy()); 111 | } 112 | json.put("compressed", obj.isCompressed()); 113 | json.put("step", obj.getStep()); 114 | json.put("connectTimeout", obj.getConnectTimeout()); 115 | json.put("readTimeout", obj.getReadTimeout()); 116 | json.put("batchSize", obj.getBatchSize()); 117 | if (obj.getOrg() != null) { 118 | json.put("org", obj.getOrg()); 119 | } 120 | if (obj.getBucket() != null) { 121 | json.put("bucket", obj.getBucket()); 122 | } 123 | if (obj.getToken() != null) { 124 | json.put("token", obj.getToken()); 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/micrometer/VertxJmxMetricsOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.micrometer; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.micrometer.VertxJmxMetricsOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.micrometer.VertxJmxMetricsOptions} original class using Vert.x codegen. 11 | */ 12 | public class VertxJmxMetricsOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, VertxJmxMetricsOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | case "enabled": 18 | if (member.getValue() instanceof Boolean) { 19 | obj.setEnabled((Boolean)member.getValue()); 20 | } 21 | break; 22 | case "domain": 23 | if (member.getValue() instanceof String) { 24 | obj.setDomain((String)member.getValue()); 25 | } 26 | break; 27 | case "step": 28 | if (member.getValue() instanceof Number) { 29 | obj.setStep(((Number)member.getValue()).intValue()); 30 | } 31 | break; 32 | } 33 | } 34 | } 35 | 36 | static void toJson(VertxJmxMetricsOptions obj, JsonObject json) { 37 | toJson(obj, json.getMap()); 38 | } 39 | 40 | static void toJson(VertxJmxMetricsOptions obj, java.util.Map json) { 41 | json.put("enabled", obj.isEnabled()); 42 | if (obj.getDomain() != null) { 43 | json.put("domain", obj.getDomain()); 44 | } 45 | json.put("step", obj.getStep()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/micrometer/VertxPrometheusOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.micrometer; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.micrometer.VertxPrometheusOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.micrometer.VertxPrometheusOptions} original class using Vert.x codegen. 11 | */ 12 | public class VertxPrometheusOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, VertxPrometheusOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | case "enabled": 18 | if (member.getValue() instanceof Boolean) { 19 | obj.setEnabled((Boolean)member.getValue()); 20 | } 21 | break; 22 | case "startEmbeddedServer": 23 | if (member.getValue() instanceof Boolean) { 24 | obj.setStartEmbeddedServer((Boolean)member.getValue()); 25 | } 26 | break; 27 | case "embeddedServerOptions": 28 | if (member.getValue() instanceof JsonObject) { 29 | obj.setEmbeddedServerOptions(new io.vertx.core.http.HttpServerOptions((io.vertx.core.json.JsonObject)member.getValue())); 30 | } 31 | break; 32 | case "embeddedServerEndpoint": 33 | if (member.getValue() instanceof String) { 34 | obj.setEmbeddedServerEndpoint((String)member.getValue()); 35 | } 36 | break; 37 | case "publishQuantiles": 38 | if (member.getValue() instanceof Boolean) { 39 | obj.setPublishQuantiles((Boolean)member.getValue()); 40 | } 41 | break; 42 | } 43 | } 44 | } 45 | 46 | static void toJson(VertxPrometheusOptions obj, JsonObject json) { 47 | toJson(obj, json.getMap()); 48 | } 49 | 50 | static void toJson(VertxPrometheusOptions obj, java.util.Map json) { 51 | json.put("enabled", obj.isEnabled()); 52 | json.put("startEmbeddedServer", obj.isStartEmbeddedServer()); 53 | if (obj.getEmbeddedServerOptions() != null) { 54 | json.put("embeddedServerOptions", obj.getEmbeddedServerOptions().toJson()); 55 | } 56 | if (obj.getEmbeddedServerEndpoint() != null) { 57 | json.put("embeddedServerEndpoint", obj.getEmbeddedServerEndpoint()); 58 | } 59 | json.put("publishQuantiles", obj.isPublishQuantiles()); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/micrometer/Label.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 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.VertxGen; 20 | 21 | /** 22 | * List of labels used in various Vert.x metrics. Labels that may not have bounded values are disabled by default. 23 | * 24 | * @author Joel Takvorian 25 | */ 26 | @VertxGen 27 | public enum Label { 28 | /** 29 | * Local address in client-host or host-client connections (used in net, http and datagram domains) 30 | */ 31 | LOCAL("local"), 32 | /** 33 | * Remote address in client-host or host-client connections (used in net and http domains) 34 | */ 35 | REMOTE("remote"), 36 | /** 37 | * Path of the URI for client or server requests (used in http domain) 38 | */ 39 | HTTP_PATH("path"), 40 | /** 41 | * Route as provided by routing modules to the http requests 42 | */ 43 | HTTP_ROUTE("route"), 44 | /** 45 | * Method (GET, POST, PUT, etc.) of an HTTP requests (used in http domain) 46 | */ 47 | HTTP_METHOD("method"), 48 | /** 49 | * HTTP response code (used in http domain) 50 | */ 51 | HTTP_CODE("code"), 52 | /** 53 | * Class name. When used in error counters (in net, http, datagram and eventbus domains) it relates to an exception 54 | * that occurred. When used in verticle domain, it relates to the verticle class name. 55 | */ 56 | CLASS_NAME("class"), 57 | /** 58 | * Event bus address 59 | */ 60 | EB_ADDRESS("address"), 61 | /** 62 | * Event bus side of the metric, it can be either "local" or "remote" 63 | */ 64 | EB_SIDE("side"), 65 | /** 66 | * Event bus failure name from a ReplyFailure object 67 | */ 68 | EB_FAILURE("failure"), 69 | /** 70 | * Pool type, such as "worker" or "datasource" (used in pools domain) 71 | */ 72 | POOL_TYPE("pool_type"), 73 | /** 74 | * Pool name (used in pools domain) 75 | */ 76 | POOL_NAME("pool_name"), 77 | /** 78 | * Client namespace 79 | */ 80 | NAMESPACE("client_namespace"); 81 | 82 | private final String labelOutput; 83 | 84 | Label(String labelOutput) { 85 | this.labelOutput = labelOutput; 86 | } 87 | 88 | @Override 89 | public String toString() { 90 | return labelOutput; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/micrometer/Match.java: -------------------------------------------------------------------------------- 1 | package io.vertx.micrometer; 2 | 3 | import io.vertx.codegen.annotations.DataObject; 4 | import io.vertx.core.json.JsonObject; 5 | 6 | /** 7 | * A match for a value. 8 | * 9 | * @author Julien Viet 10 | */ 11 | @DataObject 12 | public class Match { 13 | /** 14 | * The default value : {@link MatchType#EQUALS} 15 | */ 16 | public static final MatchType DEFAULT_TYPE = MatchType.EQUALS; 17 | 18 | private MetricsDomain domain; 19 | private String label; 20 | private String value; 21 | private MatchType type; 22 | private String alias; 23 | 24 | /** 25 | * Default constructor 26 | */ 27 | public Match() { 28 | type = DEFAULT_TYPE; 29 | } 30 | 31 | /** 32 | * Copy constructor 33 | * 34 | * @param other The other {@link Match} to copy when creating this 35 | */ 36 | public Match(Match other) { 37 | domain = other.domain; 38 | label = other.label; 39 | value = other.value; 40 | type = other.type; 41 | } 42 | 43 | /** 44 | * Create an instance from a {@link JsonObject} 45 | * 46 | * @param json the JsonObject to create it from 47 | */ 48 | public Match(JsonObject json) { 49 | if (json.containsKey("domain")) { 50 | domain = MetricsDomain.valueOf(json.getString("domain")); 51 | } 52 | label = json.getString("label"); 53 | value = json.getString("value"); 54 | type = MatchType.valueOf(json.getString("type", DEFAULT_TYPE.name())); 55 | alias = json.getString("alias"); 56 | } 57 | 58 | /** 59 | * @return the label domain 60 | */ 61 | public MetricsDomain getDomain() { 62 | return domain; 63 | } 64 | 65 | /** 66 | * Set the label domain, restricting this rule to a single domain. 67 | * 68 | * @param domain the label domain 69 | * @return a reference to this, so the API can be used fluently 70 | */ 71 | public Match setDomain(MetricsDomain domain) { 72 | this.domain = domain; 73 | return this; 74 | } 75 | 76 | /** 77 | * @return the label name 78 | */ 79 | public String getLabel() { 80 | return label; 81 | } 82 | 83 | /** 84 | * Set the label name. The match will apply to the values related to this key. 85 | * 86 | * @param label the label name 87 | * @return a reference to this, so the API can be used fluently 88 | */ 89 | public Match setLabel(String label) { 90 | this.label = label; 91 | return this; 92 | } 93 | 94 | /** 95 | * @return the matched value 96 | */ 97 | public String getValue() { 98 | return value; 99 | } 100 | 101 | /** 102 | * Set the matched value. 103 | * 104 | * @param value the value to match 105 | * @return a reference to this, so the API can be used fluently 106 | */ 107 | public Match setValue(String value) { 108 | this.value = value; 109 | return this; 110 | } 111 | 112 | /** 113 | * @return the matcher type 114 | */ 115 | public MatchType getType() { 116 | return type; 117 | } 118 | 119 | /** 120 | * Set the type of matching to apply. 121 | * 122 | * @param type the matcher type 123 | * @return a reference to this, so the API can be used fluently 124 | */ 125 | public Match setType(MatchType type) { 126 | this.type = type; 127 | return this; 128 | } 129 | 130 | /** 131 | * @return the matcher alias 132 | */ 133 | public String getAlias() { 134 | return alias; 135 | } 136 | 137 | /** 138 | * Set an alias that would replace the label value when it matches. 139 | * 140 | * @param alias the matcher alias 141 | * @return a reference to this, so the API can be used fluently 142 | */ 143 | public Match setAlias(String alias) { 144 | this.alias = alias; 145 | return this; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/micrometer/MatchType.java: -------------------------------------------------------------------------------- 1 | package io.vertx.micrometer; 2 | 3 | import io.vertx.codegen.annotations.VertxGen; 4 | 5 | /** 6 | * The type of match. 7 | * 8 | * @author Julien Viet 9 | */ 10 | @VertxGen 11 | public enum MatchType { 12 | EQUALS, 13 | REGEX 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/micrometer/MetricsDomain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2017 The original author or authors 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 | package io.vertx.micrometer; 17 | 18 | import io.vertx.codegen.annotations.VertxGen; 19 | 20 | 21 | /** 22 | * Metric domains with their associated prefixes. 23 | */ 24 | @VertxGen 25 | public enum MetricsDomain { 26 | 27 | /** 28 | * Net server metrics. 29 | */ 30 | NET_SERVER("vertx.net.server."), 31 | /** 32 | * Net client metrics. 33 | */ 34 | NET_CLIENT("vertx.net.client."), 35 | /** 36 | * Http server metrics. 37 | */ 38 | HTTP_SERVER("vertx.http.server."), 39 | /** 40 | * Http client metrics. 41 | */ 42 | HTTP_CLIENT("vertx.http.client."), 43 | /** 44 | * Datagram socket metrics. 45 | */ 46 | DATAGRAM_SOCKET("vertx.datagram."), 47 | /** 48 | * Event bus metrics. 49 | */ 50 | EVENT_BUS("vertx.eventbus."), 51 | /** 52 | * Named pools metrics. 53 | */ 54 | NAMED_POOLS("vertx.pool."), 55 | /** 56 | * Verticle metrics. 57 | */ 58 | VERTICLES("vertx.verticle."); 59 | 60 | private String prefix; 61 | 62 | MetricsDomain(String prefix) { 63 | this.prefix = prefix; 64 | } 65 | 66 | public String getPrefix() { 67 | return prefix; 68 | } 69 | 70 | public String toCategory() { 71 | // E.g. "vertx.net.server." => "net.server" 72 | return prefix.substring(6, prefix.length() - 1); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/micrometer/MetricsService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2014 The original author or authors 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; 18 | 19 | import io.vertx.codegen.annotations.VertxGen; 20 | import io.vertx.core.json.JsonObject; 21 | import io.vertx.core.metrics.Measured; 22 | import io.vertx.micrometer.impl.MetricsServiceImpl; 23 | 24 | import java.util.Set; 25 | 26 | /** 27 | * The metrics service mainly allows to return a snapshot of measured objects.
28 | * This service is derived and adapted from {@code MetricsService} in the vertx-dropwizard-metrics module. 29 | * 30 | * @author Nick Scavelli 31 | * @author Joel Takvorian 32 | */ 33 | @VertxGen 34 | public interface MetricsService { 35 | 36 | /** 37 | * Creates a metric service for a given {@link Measured} object. 38 | * 39 | * @param measured the measured object 40 | * @return the metrics service 41 | */ 42 | static MetricsService create(Measured measured) { 43 | return new MetricsServiceImpl(measured); 44 | } 45 | 46 | /** 47 | * @return the base name of the measured object 48 | */ 49 | String getBaseName(); 50 | 51 | /** 52 | * @return the known metrics names by this service 53 | */ 54 | Set metricsNames(); 55 | 56 | /** 57 | * Will return the metrics that correspond with the {@code measured} object, null if no metrics is available.

58 | * 59 | * @return the map of metrics where the key is the name of the metric (excluding the base name unless for the Vert.x object) 60 | * and the value is the json data representing that metric 61 | */ 62 | JsonObject getMetricsSnapshot(); 63 | 64 | /** 65 | * Will return the metrics that begins with the {@code baseName}, null if no metrics is available.

66 | * 67 | * @return the map of metrics where the key is the name of the metric and the value is the json data 68 | * representing that metric 69 | */ 70 | JsonObject getMetricsSnapshot(String baseName); 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/micrometer/MicrometerMetricsFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2023 The original author or authors 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 | package io.vertx.micrometer; 17 | 18 | import io.micrometer.core.instrument.Meter; 19 | import io.micrometer.core.instrument.MeterRegistry; 20 | import io.vertx.core.VertxOptions; 21 | import io.vertx.core.json.JsonObject; 22 | import io.vertx.core.metrics.MetricsOptions; 23 | import io.vertx.core.spi.VertxMetricsFactory; 24 | import io.vertx.core.spi.metrics.VertxMetrics; 25 | import io.vertx.micrometer.backends.BackendRegistries; 26 | import io.vertx.micrometer.backends.BackendRegistry; 27 | import io.vertx.micrometer.impl.VertxMetricsImpl; 28 | import io.vertx.micrometer.impl.meters.LongGauges; 29 | 30 | import java.util.Map; 31 | import java.util.WeakHashMap; 32 | import java.util.concurrent.ConcurrentHashMap; 33 | import java.util.concurrent.ConcurrentMap; 34 | import java.util.concurrent.atomic.LongAdder; 35 | 36 | /** 37 | * The micrometer metrics registry. 38 | * 39 | * @author Joel Takvorian 40 | */ 41 | public class MicrometerMetricsFactory implements VertxMetricsFactory { 42 | 43 | private static final Map> longGaugesByRegistry = new WeakHashMap<>(1); 44 | 45 | private final MeterRegistry micrometerRegistry; 46 | 47 | public MicrometerMetricsFactory() { 48 | this(null); 49 | } 50 | 51 | /** 52 | * Build a factory passing the Micrometer MeterRegistry to be used by Vert.x. 53 | * 54 | * This is useful in several scenarios, such as: 55 | *

    56 | *
  • if there is already a MeterRegistry used in the application 57 | * that should be used by Vert.x as well.
  • 58 | *
  • to define some backend configuration that is not covered in this module 59 | * (example: reporting to non-covered backends such as New Relic)
  • 60 | *
  • to use Micrometer's CompositeRegistry
  • 61 | *
62 | * 63 | * This setter is mutually exclusive with setInfluxDbOptions/setPrometheusOptions/setJmxMetricsOptions 64 | * and takes precedence over them. 65 | * 66 | * @param micrometerRegistry the registry to use 67 | */ 68 | public MicrometerMetricsFactory(MeterRegistry micrometerRegistry) { 69 | this.micrometerRegistry = micrometerRegistry; 70 | } 71 | 72 | @Override 73 | public VertxMetrics metrics(VertxOptions vertxOptions) { 74 | MetricsOptions metricsOptions = vertxOptions.getMetricsOptions(); 75 | MicrometerMetricsOptions options; 76 | if (metricsOptions instanceof MicrometerMetricsOptions) { 77 | options = (MicrometerMetricsOptions) metricsOptions; 78 | } else { 79 | options = new MicrometerMetricsOptions(metricsOptions.toJson()); 80 | } 81 | BackendRegistry backendRegistry = BackendRegistries.setupBackend(options, micrometerRegistry); 82 | ConcurrentMap 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