diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml index 73af07380b94..800f1afcb4ed 100644 --- a/spring-boot-actuator/pom.xml +++ b/spring-boot-actuator/pom.xml @@ -46,6 +46,11 @@ jackson-dataformat-xml true + + org.influxdb + influxdb-java + true + io.searchbox jest diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/InfluxDBMetricWriter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/InfluxDBMetricWriter.java new file mode 100644 index 000000000000..6f3f95312b8c --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/InfluxDBMetricWriter.java @@ -0,0 +1,100 @@ +/* + * Copyright 2012-2013 the original author or 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 + * + * http://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 org.springframework.boot.actuate.metrics.writer; + +import java.util.concurrent.TimeUnit; + +import org.influxdb.InfluxDB; +import org.influxdb.dto.Point; + +import org.springframework.boot.actuate.metrics.Metric; +import org.springframework.util.Assert; + +/** + * A {@link GaugeWriter} that writes the metric updates to InfluxDB. + * + * @author Mateusz Klimaszewski + */ +public class InfluxDBMetricWriter implements GaugeWriter { + + private static final String DEFAULT_DATABASE_NAME = "metrics"; + private static final int DEFAULT_BATCH_ACTIONS = 500; + private static final int DEFAULT_FLUSH_DURATION = 30; + + private final InfluxDB influxDB; + private final String databaseName; + + private InfluxDBMetricWriter(Builder builder) { + this.influxDB = builder.influxDB; + this.databaseName = builder.databaseName; + this.influxDB.createDatabase(this.databaseName); + this.influxDB.enableBatch(builder.batchActions, builder.flushDuration, + builder.flushDurationTimeUnit); + this.influxDB.setLogLevel(builder.logLevel); + } + + @Override + public void set(Metric value) { + Point point = Point.measurement(value.getName()) + .time(value.getTimestamp().getTime(), TimeUnit.MILLISECONDS) + .addField("value", value.getValue()) + .build(); + this.influxDB.write(this.databaseName, value.getName(), point); + } + + /** + * {@link InfluxDBMetricWriter} builder with possibility to change default arguments + */ + public static class Builder { + private final InfluxDB influxDB; + private String databaseName = DEFAULT_DATABASE_NAME; + private int batchActions = DEFAULT_BATCH_ACTIONS; + private int flushDuration = DEFAULT_FLUSH_DURATION; + private TimeUnit flushDurationTimeUnit = TimeUnit.SECONDS; + private InfluxDB.LogLevel logLevel = InfluxDB.LogLevel.BASIC; + + public Builder(InfluxDB influxDB) { + Assert.notNull(influxDB, "InfluxDB must not be null"); + this.influxDB = influxDB; + } + + public Builder databaseName(String databaseName) { + this.databaseName = databaseName; + return this; + } + + public Builder batchActions(int batchActions) { + this.batchActions = batchActions; + return this; + } + + public Builder flushDuration(int flushDuration, TimeUnit flushDurationTimeUnit) { + this.flushDuration = flushDuration; + this.flushDurationTimeUnit = flushDurationTimeUnit; + return this; + } + + public Builder logLevel(InfluxDB.LogLevel logLevel) { + this.logLevel = logLevel; + return this; + } + + public InfluxDBMetricWriter build() { + return new InfluxDBMetricWriter(this); + } + } +} diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/writer/InfluxDBMetricWriterTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/writer/InfluxDBMetricWriterTests.java new file mode 100644 index 000000000000..400d6a3fa3e7 --- /dev/null +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/writer/InfluxDBMetricWriterTests.java @@ -0,0 +1,85 @@ +/* + * Copyright 2012-2013 the original author or 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 + * + * http://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 org.springframework.boot.actuate.metrics.writer; + +import java.util.concurrent.TimeUnit; + +import org.influxdb.InfluxDB; +import org.influxdb.dto.Point; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import org.springframework.boot.actuate.metrics.Metric; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * Tests for {@link InfluxDBMetricWriter}. + * + * @author Mateusz Klimaszewski + */ +public class InfluxDBMetricWriterTests { + + private InfluxDB influxDB = mock(InfluxDB.class); + private InfluxDBMetricWriter influxDBMetricWriter; + + @Test + public void builderNonDefaultOptions() { + this.influxDBMetricWriter = new InfluxDBMetricWriter.Builder(this.influxDB) + .databaseName("testDatabaseName") + .batchActions(2000) + .flushDuration(10, TimeUnit.MILLISECONDS) + .logLevel(InfluxDB.LogLevel.FULL) + .build(); + ArgumentCaptor databaseNameCaptor = ArgumentCaptor.forClass( + String.class); + ArgumentCaptor bashActionsCaptor = ArgumentCaptor.forClass( + Integer.class); + ArgumentCaptor flushDurationCaptor = ArgumentCaptor.forClass( + Integer.class); + ArgumentCaptor flushDurationTimeUnitCaptor = ArgumentCaptor.forClass( + TimeUnit.class); + ArgumentCaptor logLevelCaptor = ArgumentCaptor.forClass( + InfluxDB.LogLevel.class); + verify(this.influxDB).createDatabase(databaseNameCaptor.capture()); + verify(this.influxDB).enableBatch(bashActionsCaptor.capture(), + flushDurationCaptor.capture(), flushDurationTimeUnitCaptor.capture()); + verify(this.influxDB).setLogLevel(logLevelCaptor.capture()); + assertThat("testDatabaseName").isEqualTo(databaseNameCaptor.getValue()); + assertThat(2000).isEqualTo(bashActionsCaptor.getValue().intValue()); + assertThat(10).isEqualTo(flushDurationCaptor.getValue().intValue()); + assertThat(TimeUnit.MILLISECONDS).isEqualTo(flushDurationTimeUnitCaptor + .getValue()); + assertThat(InfluxDB.LogLevel.FULL).isEqualTo(logLevelCaptor.getValue()); + } + + @Test + public void setMetric() { + this.influxDBMetricWriter = new InfluxDBMetricWriter.Builder(this.influxDB) + .build(); + Metric metric = new Metric("testName", 1); + this.influxDBMetricWriter.set(metric); + verify(this.influxDB, times(1)).write(anyString(), eq(metric.getName()), + any(Point.class)); + } +} diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index a1582787b101..87246c8a5f2d 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -92,6 +92,7 @@ 4.5.2 4.4.5 8.2.4.Final + 2.4 2.8.4 2.7.8 3.20.0-GA @@ -865,6 +866,11 @@ reactor-core ${reactor.version} + + org.influxdb + influxdb-java + ${influx.version} + io.searchbox jest