Skip to content

Commit 4a5d42e

Browse files
committed
Add 'logging' as new metric export type
Signed-off-by: Vasily Pelikh <[email protected]>
1 parent 33038d3 commit 4a5d42e

File tree

8 files changed

+393
-0
lines changed

8 files changed

+393
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://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,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.micrometer.metrics.autoconfigure.export.logging;
18+
19+
import io.micrometer.core.instrument.Clock;
20+
import io.micrometer.core.instrument.logging.LoggingMeterRegistry;
21+
import io.micrometer.core.instrument.logging.LoggingRegistryConfig;
22+
23+
import org.springframework.boot.autoconfigure.AutoConfiguration;
24+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
25+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
26+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
27+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
28+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
29+
import org.springframework.boot.micrometer.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration;
30+
import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsAutoConfiguration;
31+
import org.springframework.boot.micrometer.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport;
32+
import org.springframework.boot.micrometer.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration;
33+
import org.springframework.context.annotation.Bean;
34+
35+
/**
36+
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to a
37+
* {@link LoggingMeterRegistry}.
38+
*
39+
* @author Vasily Pelikh
40+
* @since 4.0.0
41+
*/
42+
@AutoConfiguration(
43+
before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class },
44+
after = MetricsAutoConfiguration.class)
45+
@ConditionalOnBean(Clock.class)
46+
@ConditionalOnClass(LoggingMeterRegistry.class)
47+
@ConditionalOnEnabledMetricsExport("logging")
48+
@EnableConfigurationProperties(LoggingMetricsExportProperties.class)
49+
public final class LoggingMetricsExportAutoConfiguration {
50+
51+
@Bean
52+
@ConditionalOnMissingBean
53+
LoggingRegistryConfig loggingRegistryConfig(LoggingMetricsExportProperties loggingMetricsExportProperties) {
54+
return new LoggingMetricsExportPropertiesConfigAdapter(loggingMetricsExportProperties);
55+
}
56+
57+
@Bean
58+
@ConditionalOnMissingBean
59+
LoggingMeterRegistry loggingMeterRegistry(LoggingRegistryConfig config, Clock clock) {
60+
return new LoggingMeterRegistry(config, clock);
61+
}
62+
63+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://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,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.micrometer.metrics.autoconfigure.export.logging;
18+
19+
import io.micrometer.core.instrument.logging.LoggingMeterRegistry;
20+
21+
import org.springframework.boot.context.properties.ConfigurationProperties;
22+
import org.springframework.boot.micrometer.metrics.autoconfigure.export.properties.StepRegistryProperties;
23+
24+
/**
25+
* {@link ConfigurationProperties @ConfigurationProperties} for configuring metrics export
26+
* to a {@link LoggingMeterRegistry}.
27+
*
28+
* @author Vasily Pelikh
29+
* @since 4.0.0
30+
*/
31+
@ConfigurationProperties("management.logging.metrics.export")
32+
public class LoggingMetricsExportProperties extends StepRegistryProperties {
33+
34+
/**
35+
* Whether counters and timers that have no activity in an interval are still logged.
36+
*/
37+
private boolean logInactive = false;
38+
39+
public boolean isLogInactive() {
40+
return this.logInactive;
41+
}
42+
43+
public void setLogInactive(boolean logInactive) {
44+
this.logInactive = logInactive;
45+
}
46+
47+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://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,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.micrometer.metrics.autoconfigure.export.logging;
18+
19+
import io.micrometer.core.instrument.logging.LoggingRegistryConfig;
20+
21+
import org.springframework.boot.micrometer.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter;
22+
23+
/**
24+
* Adapter to convert {@link LoggingMetricsExportProperties} to a
25+
* {@link LoggingRegistryConfig}.
26+
*
27+
* @author Vasily Pelikh
28+
* @since 4.0.0
29+
*/
30+
public class LoggingMetricsExportPropertiesConfigAdapter
31+
extends StepRegistryPropertiesConfigAdapter<LoggingMetricsExportProperties> implements LoggingRegistryConfig {
32+
33+
public LoggingMetricsExportPropertiesConfigAdapter(LoggingMetricsExportProperties properties) {
34+
super(properties);
35+
}
36+
37+
@Override
38+
public String prefix() {
39+
return "management.logging.metrics.export";
40+
}
41+
42+
@Override
43+
public boolean logInactive() {
44+
return obtain(LoggingMetricsExportProperties::isLogInactive, LoggingRegistryConfig.super::logInactive);
45+
}
46+
47+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://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,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Support for exporting actuator metrics to a log.
19+
*/
20+
@NullMarked
21+
package org.springframework.boot.micrometer.metrics.autoconfigure.export.logging;
22+
23+
import org.jspecify.annotations.NullMarked;

module/spring-boot-micrometer-metrics/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ org.springframework.boot.micrometer.metrics.autoconfigure.export.humio.HumioMetr
1313
org.springframework.boot.micrometer.metrics.autoconfigure.export.influx.InfluxMetricsExportAutoConfiguration
1414
org.springframework.boot.micrometer.metrics.autoconfigure.export.jmx.JmxMetricsExportAutoConfiguration
1515
org.springframework.boot.micrometer.metrics.autoconfigure.export.kairos.KairosMetricsExportAutoConfiguration
16+
org.springframework.boot.micrometer.metrics.autoconfigure.export.logging.LoggingMetricsExportAutoConfiguration
1617
org.springframework.boot.micrometer.metrics.autoconfigure.export.newrelic.NewRelicMetricsExportAutoConfiguration
1718
org.springframework.boot.micrometer.metrics.autoconfigure.export.otlp.OtlpMetricsExportAutoConfiguration
1819
org.springframework.boot.micrometer.metrics.autoconfigure.export.prometheus.PrometheusMetricsExportAutoConfiguration
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://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,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.micrometer.metrics.autoconfigure.export.logging;
18+
19+
import io.micrometer.core.instrument.Clock;
20+
import io.micrometer.core.instrument.logging.LoggingMeterRegistry;
21+
import io.micrometer.core.instrument.logging.LoggingRegistryConfig;
22+
import org.junit.jupiter.api.Test;
23+
24+
import org.springframework.boot.autoconfigure.AutoConfigurations;
25+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
26+
import org.springframework.context.annotation.Bean;
27+
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.context.annotation.Import;
29+
30+
import static org.assertj.core.api.Assertions.assertThat;
31+
32+
/**
33+
* Tests for {@link LoggingMetricsExportAutoConfiguration}.
34+
*
35+
* @author Vasily Pelikh
36+
*/
37+
class LoggingMetricsExportAutoConfigurationTests {
38+
39+
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
40+
.withConfiguration(AutoConfigurations.of(LoggingMetricsExportAutoConfiguration.class));
41+
42+
@Test
43+
void backsOffWithoutAClock() {
44+
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(LoggingMeterRegistry.class));
45+
}
46+
47+
@Test
48+
void autoConfiguresConfigAndMeterRegistry() {
49+
this.contextRunner.withUserConfiguration(BaseConfiguration.class)
50+
.run((context) -> assertThat(context).hasSingleBean(LoggingMeterRegistry.class)
51+
.hasSingleBean(LoggingRegistryConfig.class));
52+
}
53+
54+
@Test
55+
void autoConfigurationCanBeDisabledWithDefaultsEnabledProperty() {
56+
this.contextRunner.withUserConfiguration(BaseConfiguration.class)
57+
.withPropertyValues("management.defaults.metrics.export.enabled=false")
58+
.run((context) -> assertThat(context).doesNotHaveBean(LoggingMeterRegistry.class)
59+
.doesNotHaveBean(LoggingRegistryConfig.class));
60+
}
61+
62+
@Test
63+
void autoConfigurationCanBeDisabledWithSpecificEnabledProperty() {
64+
this.contextRunner.withUserConfiguration(BaseConfiguration.class)
65+
.withPropertyValues("management.logging.metrics.export.enabled=false")
66+
.run((context) -> assertThat(context).doesNotHaveBean(LoggingMeterRegistry.class)
67+
.doesNotHaveBean(LoggingRegistryConfig.class));
68+
}
69+
70+
@Test
71+
void allowsCustomConfigToBeUsed() {
72+
this.contextRunner.withUserConfiguration(CustomConfigConfiguration.class)
73+
.run((context) -> assertThat(context).hasSingleBean(LoggingMeterRegistry.class)
74+
.hasSingleBean(LoggingRegistryConfig.class)
75+
.hasBean("customConfig"));
76+
}
77+
78+
@Test
79+
void allowsRegistryToBeCustomized() {
80+
this.contextRunner.withUserConfiguration(CustomRegistryConfiguration.class)
81+
.run((context) -> assertThat(context).hasSingleBean(LoggingMeterRegistry.class)
82+
.hasSingleBean(LoggingRegistryConfig.class)
83+
.hasBean("customRegistry"));
84+
}
85+
86+
@Configuration(proxyBeanMethods = false)
87+
static class BaseConfiguration {
88+
89+
@Bean
90+
Clock customClock() {
91+
return Clock.SYSTEM;
92+
}
93+
94+
}
95+
96+
@Configuration(proxyBeanMethods = false)
97+
@Import(BaseConfiguration.class)
98+
static class CustomConfigConfiguration {
99+
100+
@Bean
101+
LoggingRegistryConfig customConfig() {
102+
return (key) -> null;
103+
}
104+
105+
}
106+
107+
@Configuration(proxyBeanMethods = false)
108+
@Import(BaseConfiguration.class)
109+
static class CustomRegistryConfiguration {
110+
111+
@Bean
112+
LoggingMeterRegistry customRegistry(LoggingRegistryConfig config, Clock clock) {
113+
return new LoggingMeterRegistry(config, clock);
114+
}
115+
116+
}
117+
118+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://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,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.micrometer.metrics.autoconfigure.export.logging;
18+
19+
import org.junit.jupiter.api.BeforeEach;
20+
import org.junit.jupiter.api.Test;
21+
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
24+
/**
25+
* Tests for {@link LoggingMetricsExportPropertiesConfigAdapter}.
26+
*
27+
* @author Vasily Pelikh
28+
*/
29+
class LoggingMetricsExportPropertiesConfigAdapterTests {
30+
31+
private LoggingMetricsExportProperties properties;
32+
33+
@BeforeEach
34+
void setUp() {
35+
this.properties = new LoggingMetricsExportProperties();
36+
}
37+
38+
@Test
39+
void whenPropertiesAggregationTemporalityIsNotSetAdapterAggregationTemporalityReturnsCumulative() {
40+
assertThat(createAdapter().logInactive()).isFalse();
41+
}
42+
43+
@Test
44+
void whenPropertiesAggregationTemporalityIsSetAdapterAggregationTemporalityReturnsIt() {
45+
this.properties.setLogInactive(true);
46+
assertThat(createAdapter().logInactive()).isTrue();
47+
}
48+
49+
private LoggingMetricsExportPropertiesConfigAdapter createAdapter() {
50+
return new LoggingMetricsExportPropertiesConfigAdapter(this.properties);
51+
}
52+
53+
}

0 commit comments

Comments
 (0)