-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds new module for Prometheus PushGateway (#848)
PR adds support for Prometheus PushGateway. Once module is included in classpath, it will be enabled by default. Added: - new module - docs for new module - tests for new module
- Loading branch information
Showing
14 changed files
with
479 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
plugins { | ||
id 'io.micronaut.build.internal.micrometer-registry' | ||
} | ||
|
||
dependencies { | ||
api libs.micrometer.registry.prometheus | ||
api projects.micronautMicrometerRegistryPrometheus | ||
api libs.managed.prometheus.metrics.exporter.pushgateway | ||
testImplementation(mnSerde.micronaut.serde.jackson) | ||
} | ||
|
||
micronautBuild { | ||
binaryCompatibility { | ||
enabledAfter '5.9.0' // adjust as needed | ||
} | ||
} |
140 changes: 140 additions & 0 deletions
140
.../configuration/metrics/micrometer/prometheus/pushgateway/PrometheusPushGatewayConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
/* | ||
* Copyright 2017-2024 original authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.configuration.metrics.micrometer.prometheus.pushgateway; | ||
|
||
import io.micronaut.configuration.metrics.micrometer.prometheus.PrometheusMeterRegistryFactory; | ||
import io.micronaut.context.annotation.BootstrapContextCompatible; | ||
import io.micronaut.context.annotation.ConfigurationBuilder; | ||
import io.micronaut.context.annotation.ConfigurationProperties; | ||
import io.micronaut.context.annotation.Requires; | ||
import io.micronaut.core.annotation.Internal; | ||
import io.micronaut.core.annotation.Nullable; | ||
import io.micronaut.core.util.StringUtils; | ||
import io.prometheus.metrics.exporter.pushgateway.PushGateway; | ||
|
||
import java.time.Duration; | ||
import java.util.Map; | ||
|
||
/** | ||
* Configuration for the {@link PushGateway}. | ||
*/ | ||
@ConfigurationProperties(PrometheusPushGatewayFactory.PROMETHEUS_PUSHGATEWAY_CONFIG) | ||
@BootstrapContextCompatible | ||
@Requires(property = PrometheusPushGatewayFactory.PROMETHEUS_PUSHGATEWAY_ENABLED, value = StringUtils.TRUE, defaultValue = StringUtils.TRUE) | ||
@Requires(property = PrometheusMeterRegistryFactory.PROMETHEUS_ENABLED, value = StringUtils.TRUE, defaultValue = StringUtils.TRUE) | ||
@Internal | ||
final class PrometheusPushGatewayConfig { | ||
|
||
@ConfigurationBuilder(prefixes = "", excludes = {"basicAuth", "groupingKey"}) | ||
final PushGateway.Builder builder = PushGateway.builder(); | ||
|
||
private String basicAuthUsername; | ||
private String basicAuthPassword; | ||
private boolean enabled; | ||
private Duration interval; | ||
private Duration initialDelay; | ||
private Map<String, String> groupingKeys; | ||
|
||
/** | ||
* @return Map of the grouping keys. | ||
*/ | ||
@Nullable | ||
public Map<String, String> getGroupingKeys() { | ||
return groupingKeys; | ||
} | ||
|
||
/** | ||
* @param groupingKeys Map of the grouping keys. | ||
*/ | ||
public void setGroupingKeys(@Nullable Map<String, String> groupingKeys) { | ||
this.groupingKeys = groupingKeys; | ||
} | ||
|
||
/** | ||
* @return username for basic auth. | ||
*/ | ||
@Nullable | ||
public String getBasicAuthUsername() { | ||
return basicAuthUsername; | ||
} | ||
|
||
/** | ||
* @param basicAuthUsername the username for basic auth. | ||
*/ | ||
public void setBasicAuthUsername(@Nullable String basicAuthUsername) { | ||
this.basicAuthUsername = basicAuthUsername; | ||
} | ||
|
||
/** | ||
* @return password for the basic auth. | ||
*/ | ||
@Nullable | ||
public String getBasicAuthPassword() { | ||
return basicAuthPassword; | ||
} | ||
|
||
/** | ||
* @param basicAuthPassword the password for basic auth. | ||
*/ | ||
public void setBasicAuthPassword(@Nullable String basicAuthPassword) { | ||
this.basicAuthPassword = basicAuthPassword; | ||
} | ||
|
||
/** | ||
* @return interval of {@link PrometheusPushGatewayScheduler#pushData()}. | ||
*/ | ||
@Nullable | ||
public Duration getInterval() { | ||
return interval; | ||
} | ||
|
||
/** | ||
* @param interval interval for {@link PrometheusPushGatewayScheduler#pushData()}. | ||
*/ | ||
public void setInterval(@Nullable Duration interval) { | ||
this.interval = interval; | ||
} | ||
|
||
/** | ||
* @return initialDelay of {@link PrometheusPushGatewayScheduler#pushData()}. | ||
*/ | ||
@Nullable | ||
public Duration getInitialDelay() { | ||
return initialDelay; | ||
} | ||
|
||
/** | ||
* @param initialDelay interval for {@link PrometheusPushGatewayScheduler#pushData()}. | ||
*/ | ||
public void setInitialDelay(@Nullable Duration initialDelay) { | ||
this.initialDelay = initialDelay; | ||
} | ||
|
||
/** | ||
* @return is PushGateway feature enabled. | ||
*/ | ||
public boolean isEnabled() { | ||
return enabled; | ||
} | ||
|
||
/** | ||
* @param enabled is PushGateway feature enabled. | ||
*/ | ||
public void setEnabled(boolean enabled) { | ||
this.enabled = enabled; | ||
} | ||
|
||
} |
62 changes: 62 additions & 0 deletions
62
...configuration/metrics/micrometer/prometheus/pushgateway/PrometheusPushGatewayFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Copyright 2017-2019 original authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.configuration.metrics.micrometer.prometheus.pushgateway; | ||
|
||
import io.micrometer.prometheusmetrics.PrometheusMeterRegistry; | ||
import io.micronaut.context.annotation.Factory; | ||
import io.micronaut.context.annotation.Requires; | ||
import io.micronaut.core.annotation.Internal; | ||
import io.micronaut.core.util.StringUtils; | ||
import io.prometheus.metrics.exporter.pushgateway.PushGateway; | ||
import jakarta.inject.Singleton; | ||
|
||
import static io.micronaut.configuration.metrics.micrometer.MeterRegistryFactory.MICRONAUT_METRICS_EXPORT; | ||
|
||
/** | ||
* Creates a Prometheus {@link PushGateway}. | ||
*/ | ||
@Factory | ||
@Internal | ||
class PrometheusPushGatewayFactory { | ||
|
||
public static final String PROMETHEUS_PUSHGATEWAY_CONFIG = MICRONAUT_METRICS_EXPORT + ".prometheus.pushgateway"; | ||
public static final String PROMETHEUS_PUSHGATEWAY_ENABLED = PROMETHEUS_PUSHGATEWAY_CONFIG + ".enabled"; | ||
|
||
/** | ||
* Create a PushGateway bean if global metrics are enabled | ||
* , Prometheus is enabled and PushGateway is enabled. Will be true by default when this | ||
* configuration is included in project. | ||
* | ||
* @return PushGateway | ||
*/ | ||
@Singleton | ||
@Requires(beans = PrometheusPushGatewayConfig.class) | ||
@Requires(beans = PrometheusMeterRegistry.class) | ||
PushGateway pushGateway(PrometheusMeterRegistry prometheusMeterRegistry, PrometheusPushGatewayConfig prometheusRegistryConfig) { | ||
PushGateway.Builder builder = prometheusRegistryConfig.builder.registry(prometheusMeterRegistry.getPrometheusRegistry()); | ||
|
||
if (!StringUtils.isEmpty(prometheusRegistryConfig.getBasicAuthUsername()) && !StringUtils.isEmpty(prometheusRegistryConfig.getBasicAuthPassword())) { | ||
builder.basicAuth(prometheusRegistryConfig.getBasicAuthUsername(), prometheusRegistryConfig.getBasicAuthPassword()); | ||
} | ||
|
||
if (prometheusRegistryConfig.getGroupingKeys() != null && !prometheusRegistryConfig.getGroupingKeys().isEmpty()) { | ||
prometheusRegistryConfig.getGroupingKeys().forEach(builder::groupingKey); | ||
} | ||
|
||
return builder.build(); | ||
} | ||
|
||
} |
47 changes: 47 additions & 0 deletions
47
...nfiguration/metrics/micrometer/prometheus/pushgateway/PrometheusPushGatewayScheduler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* Copyright 2017-2024 original authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.configuration.metrics.micrometer.prometheus.pushgateway; | ||
|
||
import io.micronaut.context.annotation.Requires; | ||
import io.micronaut.core.annotation.Internal; | ||
import io.micronaut.scheduling.annotation.Scheduled; | ||
import io.prometheus.metrics.exporter.pushgateway.PushGateway; | ||
import jakarta.inject.Singleton; | ||
|
||
import java.io.IOException; | ||
|
||
/** | ||
* PrometheusPushGatewayScheduler pushes data to Prometheus pushGateway. | ||
*/ | ||
@Singleton | ||
@Requires(beans = PushGateway.class) | ||
@Internal | ||
final class PrometheusPushGatewayScheduler { | ||
|
||
private final PushGateway pushGateway; | ||
|
||
PrometheusPushGatewayScheduler(PushGateway pushGateway) { | ||
this.pushGateway = pushGateway; | ||
} | ||
|
||
@Scheduled( | ||
fixedDelay = "${micronaut.metrics.export.prometheus.pushgateway.interval:1m}", | ||
initialDelay = "${micronaut.metrics.export.prometheus.pushgateway.initial-delay:1m}") | ||
void pushData() throws IOException { | ||
pushGateway.push(); | ||
} | ||
|
||
} |
27 changes: 27 additions & 0 deletions
27
...va/io/micronaut/configuration/metrics/micrometer/prometheus/pushgateway/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright 2017-2019 original authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
/** | ||
* Micronaut integration with Prometheus PushGateway. | ||
*/ | ||
@Configuration | ||
@Requires(property = PrometheusPushGatewayFactory.PROMETHEUS_PUSHGATEWAY_ENABLED, notEquals = StringUtils.FALSE) | ||
@Requires(property = PrometheusMeterRegistryFactory.PROMETHEUS_ENABLED, notEquals = StringUtils.FALSE) | ||
package io.micronaut.configuration.metrics.micrometer.prometheus.pushgateway; | ||
|
||
import io.micronaut.configuration.metrics.micrometer.prometheus.PrometheusMeterRegistryFactory; | ||
import io.micronaut.context.annotation.Configuration; | ||
import io.micronaut.context.annotation.Requires; | ||
import io.micronaut.core.util.StringUtils; |
27 changes: 27 additions & 0 deletions
27
...naut/configuration/metrics/micrometer/prometheus/controllers/MetricsTestController.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package io.micronaut.configuration.metrics.micrometer.prometheus.controllers | ||
|
||
import io.micronaut.http.MediaType | ||
import io.micronaut.http.annotation.Body | ||
import io.micronaut.http.annotation.Consumes | ||
import io.micronaut.http.annotation.Controller | ||
import io.micronaut.http.annotation.Get | ||
import io.micronaut.http.annotation.Header | ||
import io.micronaut.http.annotation.Put | ||
|
||
@Controller("/metrics/job/test") | ||
class MetricsTestController { | ||
|
||
private static String authHeader = "" | ||
|
||
@Get | ||
String hello() { | ||
return authHeader | ||
} | ||
|
||
@Put | ||
@Consumes(MediaType.TEXT_PLAIN) | ||
String test(@Body String body, @Header("Authorization") auth) { | ||
MetricsTestController.authHeader = auth | ||
return "OK" | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
...uration/metrics/micrometer/prometheus/pushgateway/PrometheusPushGatewayFactorySpec.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package io.micronaut.configuration.metrics.micrometer.prometheus.pushgateway | ||
|
||
import io.micrometer.core.instrument.MeterRegistry | ||
import io.micronaut.context.ApplicationContext | ||
import io.prometheus.metrics.exporter.pushgateway.PushGateway | ||
import spock.lang.Specification | ||
import spock.lang.Unroll | ||
|
||
import static io.micronaut.configuration.metrics.micrometer.MeterRegistryFactory.MICRONAUT_METRICS_ENABLED | ||
import static PrometheusPushGatewayFactory.PROMETHEUS_PUSHGATEWAY_ENABLED | ||
|
||
class PrometheusPushGatewayFactorySpec extends Specification { | ||
|
||
void "verify PushGateway is created by default when this configuration used"() { | ||
when: | ||
ApplicationContext context = ApplicationContext.run() | ||
|
||
then: | ||
context.getBeansOfType(MeterRegistry).size() == 1 | ||
context.getBeansOfType(MeterRegistry)*.class*.simpleName.containsAll(['PrometheusMeterRegistry']) | ||
context.getBeansOfType(PushGateway) | ||
|
||
cleanup: | ||
context.stop() | ||
} | ||
|
||
@Unroll | ||
void "verify PrometheusMeterRegistry bean exists = #result when config #cfg = #setting"() { | ||
when: | ||
ApplicationContext context = ApplicationContext.run([(cfg): setting]) | ||
|
||
then: | ||
context.findBean(PushGateway).isPresent() == result | ||
|
||
cleanup: | ||
context.stop() | ||
|
||
where: | ||
cfg | setting | result | ||
MICRONAUT_METRICS_ENABLED | false | false | ||
MICRONAUT_METRICS_ENABLED | true | true | ||
PROMETHEUS_PUSHGATEWAY_ENABLED | true | true | ||
PROMETHEUS_PUSHGATEWAY_ENABLED | false | false | ||
} | ||
} |
Oops, something went wrong.