Skip to content

Commit 84da3c4

Browse files
committed
Add InfluxDB exporter to Actuator.
Configurable implementation of gauge writer to export metrics into InfluxDB. Fixes gh-5688
1 parent ed9f111 commit 84da3c4

File tree

4 files changed

+195
-0
lines changed

4 files changed

+195
-0
lines changed

spring-boot-actuator/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@
4646
<artifactId>jackson-dataformat-xml</artifactId>
4747
<optional>true</optional>
4848
</dependency>
49+
<dependency>
50+
<groupId>org.influxdb</groupId>
51+
<artifactId>influxdb-java</artifactId>
52+
<optional>true</optional>
53+
</dependency>
4954
<dependency>
5055
<groupId>io.searchbox</groupId>
5156
<artifactId>jest</artifactId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright 2012-2013 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+
* 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,
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.actuate.metrics.writer;
18+
19+
import java.util.concurrent.TimeUnit;
20+
21+
import org.influxdb.InfluxDB;
22+
import org.influxdb.dto.Point;
23+
24+
import org.springframework.boot.actuate.metrics.Metric;
25+
import org.springframework.util.Assert;
26+
27+
/**
28+
* A {@link GaugeWriter} that writes the metric updates to InfluxDB.
29+
*
30+
* @author Mateusz Klimaszewski
31+
*/
32+
public class InfluxDBMetricWriter implements GaugeWriter {
33+
34+
private static final String DEFAULT_DATABASE_NAME = "metrics";
35+
private static final int DEFAULT_BATCH_ACTIONS = 500;
36+
private static final int DEFAULT_FLUSH_DURATION = 30;
37+
38+
private final InfluxDB influxDB;
39+
private final String databaseName;
40+
41+
private InfluxDBMetricWriter(Builder builder) {
42+
this.influxDB = builder.influxDB;
43+
this.databaseName = builder.databaseName;
44+
this.influxDB.createDatabase(this.databaseName);
45+
this.influxDB.enableBatch(builder.batchActions, builder.flushDuration,
46+
builder.flushDurationTimeUnit);
47+
this.influxDB.setLogLevel(builder.logLevel);
48+
}
49+
50+
@Override
51+
public void set(Metric<?> value) {
52+
Point point = Point.measurement(value.getName())
53+
.time(value.getTimestamp().getTime(), TimeUnit.MILLISECONDS)
54+
.addField("value", value.getValue())
55+
.build();
56+
this.influxDB.write(this.databaseName, value.getName(), point);
57+
}
58+
59+
/**
60+
* {@link InfluxDBMetricWriter} builder with possibility to change default arguments
61+
*/
62+
public static class Builder {
63+
private final InfluxDB influxDB;
64+
private String databaseName = DEFAULT_DATABASE_NAME;
65+
private int batchActions = DEFAULT_BATCH_ACTIONS;
66+
private int flushDuration = DEFAULT_FLUSH_DURATION;
67+
private TimeUnit flushDurationTimeUnit = TimeUnit.SECONDS;
68+
private InfluxDB.LogLevel logLevel = InfluxDB.LogLevel.BASIC;
69+
70+
public Builder(InfluxDB influxDB) {
71+
Assert.notNull(influxDB, "InfluxDB must not be null");
72+
this.influxDB = influxDB;
73+
}
74+
75+
public Builder databaseName(String databaseName) {
76+
this.databaseName = databaseName;
77+
return this;
78+
}
79+
80+
public Builder batchActions(int batchActions) {
81+
this.batchActions = batchActions;
82+
return this;
83+
}
84+
85+
public Builder flushDuration(int flushDuration, TimeUnit flushDurationTimeUnit) {
86+
this.flushDuration = flushDuration;
87+
this.flushDurationTimeUnit = flushDurationTimeUnit;
88+
return this;
89+
}
90+
91+
public Builder logLevel(InfluxDB.LogLevel logLevel) {
92+
this.logLevel = logLevel;
93+
return this;
94+
}
95+
96+
public InfluxDBMetricWriter build() {
97+
return new InfluxDBMetricWriter(this);
98+
}
99+
}
100+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright 2012-2013 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+
* 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,
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.actuate.metrics.writer;
18+
19+
import java.util.concurrent.TimeUnit;
20+
21+
import org.influxdb.InfluxDB;
22+
import org.influxdb.dto.Point;
23+
import org.junit.Test;
24+
import org.mockito.ArgumentCaptor;
25+
26+
import org.springframework.boot.actuate.metrics.Metric;
27+
28+
import static org.assertj.core.api.Assertions.assertThat;
29+
import static org.mockito.Matchers.any;
30+
import static org.mockito.Matchers.anyString;
31+
import static org.mockito.Matchers.eq;
32+
import static org.mockito.Mockito.mock;
33+
import static org.mockito.Mockito.times;
34+
import static org.mockito.Mockito.verify;
35+
36+
/**
37+
* Tests for {@link InfluxDBMetricWriter}.
38+
*
39+
* @author Mateusz Klimaszewski
40+
*/
41+
public class InfluxDBMetricWriterTests {
42+
43+
private InfluxDB influxDB = mock(InfluxDB.class);
44+
private InfluxDBMetricWriter influxDBMetricWriter;
45+
46+
@Test
47+
public void builderNonDefaultOptions() {
48+
this.influxDBMetricWriter = new InfluxDBMetricWriter.Builder(this.influxDB)
49+
.databaseName("testDatabaseName")
50+
.batchActions(1000)
51+
.flushDuration(10, TimeUnit.MILLISECONDS)
52+
.logLevel(InfluxDB.LogLevel.FULL)
53+
.build();
54+
ArgumentCaptor<String> databaseNameCaptor = ArgumentCaptor.forClass(
55+
String.class);
56+
ArgumentCaptor<Integer> bashActionsCaptor = ArgumentCaptor.forClass(
57+
Integer.class);
58+
ArgumentCaptor<Integer> flushDurationCaptor = ArgumentCaptor.forClass(
59+
Integer.class);
60+
ArgumentCaptor<TimeUnit> flushDurationTimeUnitCaptor = ArgumentCaptor.forClass(
61+
TimeUnit.class);
62+
ArgumentCaptor<InfluxDB.LogLevel> logLevelCaptor = ArgumentCaptor.forClass(
63+
InfluxDB.LogLevel.class);
64+
verify(this.influxDB).createDatabase(databaseNameCaptor.capture());
65+
verify(this.influxDB).enableBatch(bashActionsCaptor.capture(),
66+
flushDurationCaptor.capture(), flushDurationTimeUnitCaptor.capture());
67+
verify(this.influxDB).setLogLevel(logLevelCaptor.capture());
68+
assertThat("testDatabaseName").isEqualTo(databaseNameCaptor.getValue());
69+
assertThat(1000).isEqualTo(bashActionsCaptor.getValue().intValue());
70+
assertThat(10).isEqualTo(flushDurationCaptor.getValue().intValue());
71+
assertThat(TimeUnit.MILLISECONDS).isEqualTo(flushDurationTimeUnitCaptor.getValue());
72+
assertThat(InfluxDB.LogLevel.FULL).isEqualTo(logLevelCaptor.getValue());
73+
}
74+
75+
@Test
76+
public void setMetric() {
77+
this.influxDBMetricWriter = new InfluxDBMetricWriter.Builder(this.influxDB)
78+
.build();
79+
Metric<Number> metric = new Metric<Number>("testName", 1);
80+
this.influxDBMetricWriter.set(metric);
81+
verify(this.influxDB, times(1)).write(anyString(), eq(metric.getName()),
82+
any(Point.class));
83+
}
84+
}

spring-boot-dependencies/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
<httpclient.version>4.5.2</httpclient.version>
9393
<httpcore.version>4.4.5</httpcore.version>
9494
<infinispan.version>8.2.4.Final</infinispan.version>
95+
<influx.version>2.4</influx.version>
9596
<jackson.version>2.8.4</jackson.version>
9697
<janino.version>2.7.8</janino.version>
9798
<javassist.version>3.20.0-GA</javassist.version> <!-- Same as Hibernate -->
@@ -865,6 +866,11 @@
865866
<artifactId>reactor-core</artifactId>
866867
<version>${reactor.version}</version>
867868
</dependency>
869+
<dependency>
870+
<groupId>org.influxdb</groupId>
871+
<artifactId>influxdb-java</artifactId>
872+
<version>${influx.version}</version>
873+
</dependency>
868874
<dependency>
869875
<groupId>io.searchbox</groupId>
870876
<artifactId>jest</artifactId>

0 commit comments

Comments
 (0)