Skip to content

Commit

Permalink
Added a MetricsService as a push wrapper around io.micrometer
Browse files Browse the repository at this point in the history
  • Loading branch information
clorenz committed Jul 10, 2018
1 parent 337ff64 commit ae95d7d
Show file tree
Hide file tree
Showing 19 changed files with 324 additions and 26 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ The DigitalCollection Common Java Libraries provide project independent common f

Read module specific documentations:

- [DigitalCollections Commons Server](digitalcollections-commons-server)
- [DigitalCollections Commons Spring AOP](digitalcollections-commons-springaop)
- [DigitalCollections Commons Spring Boot](digitalcollections-commons-springboot)
- [DigitalCollections Commons Spring MVC](digitalcollections-commons-springmvc)
- [DigitalCollections Commons Spring Security](digitalcollections-commons-springsecurity)
- [DigitalCollections Commons Validation](digitalcollections-commons-validation)
- [DigitalCollections Commons YAML](digitalcollections-commons-yaml)
- [DigitalCollections Commons XML](digitalcollections-commons-xml)
- [DigitalCollections Commons Server](dc-commons-server)
- [DigitalCollections Commons Spring AOP](dc-commons-springaop)
- [DigitalCollections Commons Spring Boot](dc-commons-springboot)
- [DigitalCollections Commons Spring MVC](dc-commons-springmvc)
- [DigitalCollections Commons Spring Security](dc-commons-springsecurity)
- [DigitalCollections Commons Validation](dc-commons-validation)
- [DigitalCollections Commons YAML](dc-commons-yaml)
- [DigitalCollections Commons XML](dc-commons-xml)
2 changes: 1 addition & 1 deletion dc-commons-feign/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>de.digitalcollections.commons</groupId>
<artifactId>dc-commons</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
</parent>

<name>DigitalCollections: Commons REST Feign</name>
Expand Down
2 changes: 1 addition & 1 deletion dc-commons-jdbi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>de.digitalcollections.commons</groupId>
<artifactId>dc-commons</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
</parent>

<name>DigitalCollections: Commons JDBI</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>de.digitalcollections.commons</groupId>
<artifactId>dc-commons-prosemirror</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
</parent>

<name>DigitalCollections: Commons ProseMirror Model Jackson</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>de.digitalcollections.commons</groupId>
<artifactId>dc-commons-prosemirror</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
</parent>

<name>DigitalCollections: Commons ProseMirror Model</name>
Expand Down
2 changes: 1 addition & 1 deletion dc-commons-prosemirror/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>de.digitalcollections.commons</groupId>
<artifactId>dc-commons</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
</parent>

<name>DigitalCollections: Commons ProseMirror (Parent)</name>
Expand Down
2 changes: 1 addition & 1 deletion dc-commons-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>de.digitalcollections.commons</groupId>
<artifactId>dc-commons</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
</parent>

<name>DigitalCollections: Commons Server</name>
Expand Down
2 changes: 1 addition & 1 deletion dc-commons-springaop/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>de.digitalcollections.commons</groupId>
<artifactId>dc-commons</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
</parent>

<name>DigitalCollections: Commons Spring AOP</name>
Expand Down
38 changes: 35 additions & 3 deletions dc-commons-springboot/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Digital Collections Commons Spring Boot

Offer common used endpoints and contributors for Spring Boot 2 applications.
Offer common used endpoints and contributors for Spring Boot 2 applications as well as monitoring services.

## Usage

Expand All @@ -10,7 +10,7 @@ Add the following artifact to your maven ```pom.xml```
<dependency>
<groupId>de.digitalcollections.commons</groupId>
<artifactId>dc-commons-springboot</artifactId>
<version>1.3.0-SNAPSHOT</version>
<version>1.4.0</version>
</dependency>
```

Expand Down Expand Up @@ -147,4 +147,36 @@ To enable it, extend your Spring Component scan with the following package:
@ComponentScan(basePackages = {
"de.digitalcollections.commons.springboot.contributor"
})
```
```

## Services

### ```MetricsService```

This service offers a lightweight API to *push* data into the ```io.micrometer``` monitoring, which uses the publish-subscribe pattern.

To use it, extend your Spring Component scan with the following package:

```java
@ComponentScan(basePackages = {
"de.digitalcollections.commons.springboot.metrics"
})
[...]
@Autowired MetricsService metricsService;
```

Its API is pretty straightforward, ranging from a simple

```java
setGauge(String name, long value);
```

method to set the value of a gauge (postfixed with ```.amount``), up to complex methods like

```java
increaseCounterWithDurationAndPercentiles(String name, String tag, Long durationMillis);
```

to simultaneously increase a gauge value with a tag and log the duration, e.g. of a previous function call.
15 changes: 14 additions & 1 deletion dc-commons-springboot/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>de.digitalcollections.commons</groupId>
<artifactId>dc-commons</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
</parent>

<name>DigitalCollections: Commons Spring Boot (Spring Boot 2)</name>
Expand All @@ -28,6 +28,14 @@
<artifactId>jackson-databind</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
Expand Down Expand Up @@ -62,6 +70,11 @@
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package de.digitalcollections.commons.springboot.metrics;

import io.micrometer.core.instrument.ImmutableTag;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Timer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.stereotype.Service;

@Service
public class MetricsService {

protected Map<String, Long> counters = new HashMap<>();
protected Map<String,Set<Tag>> counterTags = new HashMap<>();
protected Map<String, Timer> timers = new HashMap<>();

private final MeterRegistry meterRegistry;

public MetricsService(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}

/**
* Sets the value of a gauge
* @param name Name of the gauge, postfixed with <tt>.amount</tt>
* @param value Value of the gauge
*/
public void setGauge(String name, long value) {
handleCounter(name, null, null, value, null, false);
}

/**
* Sets the value of a gauge
* @param name Name of the gauge, postfixed with <tt>.amount</tt>
* @param tag Name of the tag
* @param value Value of the gauge
*/
public void setGauge(String name, String tag, long value) {
handleCounter(name, tag, null, value, null, false);
}

/**
* Increases the gauge counter by one
* @param name Name of the gauge, postfixed with <tt>.amount</tt>
* @param tag Name of the tag
*/
public void increaseCounter(String name, String tag) {
handleCounter(name, tag, 1L, null, null, false);
}

/**
* Increases the gauge counter with a custom increment
* @param name Name of the gauge, postfixed with <tt>.amount</tt>
* @param tag Name of the tag
* @param increment Increment value
*/
public void increaseCounter(String name, String tag, long increment) {
handleCounter(name, tag, increment, null,null, false);
}

/**
* Increases the gauge counter and logs its accompanied duration
* @param name Name of the gauge, postfixed with <tt>.amount</tt> and name of the timer, postfixed with <tt>.duration</tt>
* @param tag Name of the tag
* @param durationMillis Duration in milliseconds
*/
public void increaseCounterWithDuration(String name, String tag, Long durationMillis) {
handleCounter(name, tag, 1L, null, durationMillis, false);
}

/**
* Increases the gauge counter and logs its accompanied duration including percentiles (0.5 and 0.95) and histogram
* @param name Name of the gauge, postfixed with <tt>.amount</tt> and name of the timer, postfixed with <tt>.duration</tt>
* @param tag Name of the tag (must not be null)
* @param durationMillis Duration in milliseconds
*/
public void increaseCounterWithDurationAndPercentiles(String name, String tag, Long durationMillis) {
handleCounter(name, tag, 1L, null, durationMillis, true);
}

private void handleCounter(String name, String tag, Long increment, Long absoluteValue, Long durationMillis, Boolean publishPercentiles) {
String key = name + ( tag != null ? "." + tag : "");

if ( increment != null ) {
// Increase counter value
counters.put(key, counters.getOrDefault(key, 0L) + increment);
} else {
counters.put(key, absoluteValue);
}

// Register counter, if it doesn't exist yet
if (counterTags.get(key) == null) {
counterTags.put(key, new HashSet<>());
if ( tag != null ) {
counterTags.get(key).add(new ImmutableTag("type", tag));
meterRegistry.gauge(name + ".amount", counterTags.get(key), key, counters::get);
} else {
meterRegistry.gauge(name + ".amount", counters.get(key));
}
}

if (durationMillis != null && tag != null) {
// Register Timer
if (timers.get(key) == null) {
Timer.Builder timerBuilder = Timer.builder(name + ".duration")
.tag("type", tag);

if ( publishPercentiles ) {
timerBuilder = timerBuilder.publishPercentiles(0.5, 0.95)
.publishPercentileHistogram();
}

Timer timer = timerBuilder
.register(meterRegistry);

timers.put(key, timer);
}
// Record time
timers.get(key).record(durationMillis, TimeUnit.MILLISECONDS);
}
}

// ------------------------------- only for tests
protected Map<String, Long> getCounters() {
return counters;
}

protected Map<String, Set<Tag>> getCounterTags() {
return counterTags;
}

protected Map<String, Timer> getTimers() {
return timers;
}
}
Loading

0 comments on commit ae95d7d

Please sign in to comment.