Skip to content

Commit fabbc5d

Browse files
Merge pull request #37 from DeyanZhelyazkov/master
Add dropwizard based java client for custom metrics. Excluding jackson dependency.
2 parents 1ecc179 + f81216b commit fabbc5d

File tree

40 files changed

+1525
-92
lines changed

40 files changed

+1525
-92
lines changed

README.md

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ All in all, you should do the following:
2929
And
3030
4. Adjust your logging configuration accordingly.
3131

32-
Let's say you want to make use of the *servlet filter* feature, then you need to add the following dependency to your POM with property `cf-logging-version` referring to the latest nexus version (currently `3.0.1`):
32+
Let's say you want to make use of the *servlet filter* feature, then you need to add the following dependency to your POM with property `cf-logging-version` referring to the latest nexus version (currently `3.0.2`):
3333

3434
```xml
3535
<properties>
36-
<cf-logging-version>3.0.1</cf-logging-version>
36+
<cf-logging-version>3.0.2</cf-logging-version>
3737
</properties>
3838
```
3939

@@ -48,7 +48,9 @@ Let's say you want to make use of the *servlet filter* feature, then you need to
4848

4949
This feature only depends on the servlet API which you have included in your POM anyhow. You can find more information about the *servlet filter* feature (like e.g. how to adjust the web.xml) in the [Wiki](https://github.com/SAP/cf-java-logging-support/wiki/Instrumenting-Servlets).
5050

51-
If you want to use the `custom metrics` `spring-boot client`, just define the following dependency:
51+
If you want to use the `custom metrics`, just define the following dependency:
52+
53+
* `spring-boot client`:
5254

5355
``` xml
5456

@@ -59,6 +61,18 @@ If you want to use the `custom metrics` `spring-boot client`, just define the fo
5961
</dependency>
6062
```
6163

64+
* `java client`:
65+
66+
``` xml
67+
68+
<dependency>
69+
<groupId>com.sap.hcp.cf.logging</groupId>
70+
<artifactId>cf-custom-metrics-clients-java</artifactId>
71+
<version>${cf-logging-version}</version>
72+
</dependency>
73+
```
74+
75+
6276
## Implementation variants and logging configurations
6377

6478
The *core* feature (on which all other features rely) is just using the `org.slf4j` API, but to actually get logs written, you need to pick an implementation feature. As stated above, we have two implementations:
@@ -160,7 +174,7 @@ Here are the minimal configurations you'd need:
160174
With the custom metrics clients you can send metrics defined inside your code. If you choose not to use one of these clients, you can still directly push the metrics using the REST API. Once send the metrics can be consumed in Kibana.
161175
To use the clients you'd need:
162176

163-
*Using spring-boot client in Spring Boot 2 application:*
177+
1. *Using spring-boot client in Spring Boot 2 application:*
164178

165179
``` xml
166180
<dependency>
@@ -221,12 +235,50 @@ public class DemoController {
221235
```
222236
In the example above, three custom metrics are defined and used. The metrics are `Counter`, `LongTaskTimer` and `Gauge`.
223237

238+
2. *Using java client in Java application:*
239+
240+
``` xml
241+
<dependency>
242+
<groupId>com.sap.hcp.cf.logging</groupId>
243+
<artifactId>cf-custom-metrics-clients-java</artifactId>
244+
<version>${cf-logging-version}</version>
245+
</dependency>
246+
```
247+
248+
The java client uses [Dropwizard](https://metrics.dropwizard.io) which allows to define all kind of metrics supports by Dropwizard. The following metrics are available: com.codahale.metrics.Gauge, com.codahale.metrics.Counter, com.codahale.metrics.Histogram, com.codahale.metrics.Meter and com.codahale.metrics.Timer. More information about the [metric types and their usage](https://metrics.dropwizard.io/4.0.0/getting-started.html). Define your custom metrics and iterate with them:
249+
250+
``` java
251+
import java.io.IOException;
252+
253+
import javax.servlet.ServletException;
254+
import javax.servlet.http.HttpServlet;
255+
import javax.servlet.http.HttpServletRequest;
256+
import javax.servlet.http.HttpServletResponse;
257+
258+
import com.codahale.metrics.Counter;
259+
import com.codahale.metrics.Meter;
260+
import com.sap.cloud.cf.monitoring.java.CustomMetricRegistry;
261+
262+
public class CustomMetricsServlet extends HttpServlet {
263+
private static Counter counter = CustomMetricRegistry.get().counter("custom.metric.request.count");
264+
private static Meter meter = CustomMetricRegistry.get().meter("custom.metric.request.meter");
265+
266+
@Override
267+
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
268+
counter.inc(3);
269+
meter.mark();
270+
response.getWriter().println("<p>Greetings from Custom Metrics</p>");
271+
}
272+
}
273+
```
274+
224275
## Custom metrics client configurations
225276

226277
This client library supports the following configurations regarding sending custom metrics:
227278
* `interval`: the interval for sending metrics, in millis. **Default value: `60000`**
228279
* `enabled`: enables or disables the sending of metrics. **Default value: `true`**
229280
* `metrics`: array of whitelisted metric names. Only mentioned metrics would be processed and sent. If it is an empty array all metrics are being sent. **Default value: `[]`**
281+
* `metricQuantiles`: enables or disables the sending of metric's [quantiles](https://en.wikipedia.org/wiki/Quantile) like median, 95th percentile, 99th percentile. Spring-boot client does not support this configuration. **Default value: `false`**
230282

231283
Configurations are read from environment variable named `CUSTOM_METRICS`. To change the default values, you should override the environment variable with your custom values. Example:
232284

@@ -237,7 +289,8 @@ This client library supports the following configurations regarding sending cust
237289
"metrics": [
238290
"my.whitelist.metric.1",
239291
"my.whitelist.metric.2"
240-
]
292+
],
293+
"metricQuantiles":true
241294
}
242295
```
243296

cf-java-logging-support-core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<parent>
3333
<groupId>com.sap.hcp.cf.logging</groupId>
3434
<artifactId>cf-java-logging-support-parent</artifactId>
35-
<version>3.0.1</version>
35+
<version>3.0.2</version>
3636
<relativePath>../pom.xml</relativePath>
3737
</parent>
3838
<build>

cf-java-logging-support-jersey/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<relativePath>../pom.xml</relativePath>
1010
<groupId>com.sap.hcp.cf.logging</groupId>
1111
<artifactId>cf-java-logging-support-parent</artifactId>
12-
<version>3.0.1</version>
12+
<version>3.0.2</version>
1313
</parent>
1414

1515
<name>cf-java-logging-support-jersey</name>

cf-java-logging-support-log4j2/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<relativePath>../pom.xml</relativePath>
1212
<groupId>com.sap.hcp.cf.logging</groupId>
1313
<artifactId>cf-java-logging-support-parent</artifactId>
14-
<version>3.0.1</version>
14+
<version>3.0.2</version>
1515
</parent>
1616

1717
<dependencies>

cf-java-logging-support-logback/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<relativePath>../pom.xml</relativePath>
1111
<groupId>com.sap.hcp.cf.logging</groupId>
1212
<artifactId>cf-java-logging-support-parent</artifactId>
13-
<version>3.0.1</version>
13+
<version>3.0.2</version>
1414
</parent>
1515

1616
<dependencies>

cf-java-logging-support-servlet/pom.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
<artifactId>cf-java-logging-support-servlet</artifactId>
66
<packaging>jar</packaging>
77

8-
<name>cf-java-logging-support-servlet</name>
9-
<parent>
10-
<groupId>com.sap.hcp.cf.logging</groupId>
11-
<artifactId>cf-java-logging-support-parent</artifactId>
12-
<version>3.0.1</version>
13-
<relativePath>../pom.xml</relativePath>
14-
</parent>
8+
<name>cf-java-logging-support-servlet</name>
9+
<parent>
10+
<groupId>com.sap.hcp.cf.logging</groupId>
11+
<artifactId>cf-java-logging-support-parent</artifactId>
12+
<version>3.0.2</version>
13+
<relativePath>../pom.xml</relativePath>
14+
</parent>
1515

1616
<properties>
1717
<servlet.api.version>3.0.1</servlet.api.version>
Lines changed: 53 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,56 @@
1-
<project xmlns="http://maven.apache.org/POM/4.0.0"
2-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4-
<modelVersion>4.0.0</modelVersion>
5-
<parent>
6-
<groupId>com.sap.hcp.cf.logging</groupId>
7-
<artifactId>cf-java-monitoring-custom-metrics-clients</artifactId>
8-
<version>3.0.1</version>
9-
</parent>
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<parent>
5+
<groupId>com.sap.hcp.cf.logging</groupId>
6+
<artifactId>cf-java-monitoring-custom-metrics-clients</artifactId>
7+
<version>3.0.2</version>
8+
</parent>
109

11-
<artifactId>cf-custom-metrics-clients-core</artifactId>
12-
<packaging>jar</packaging>
13-
<name>cf-java-monitoring-custom-metrics-clients-core</name>
10+
<artifactId>cf-custom-metrics-clients-core</artifactId>
11+
<packaging>jar</packaging>
12+
<name>cf-java-monitoring-custom-metrics-clients-core</name>
1413

15-
<build>
16-
<plugins>
17-
<plugin>
18-
<groupId>org.apache.maven.plugins</groupId>
19-
<artifactId>maven-compiler-plugin</artifactId>
20-
<configuration>
21-
<source>1.7</source>
22-
<target>1.7</target>
23-
</configuration>
24-
</plugin>
25-
</plugins>
26-
</build>
27-
28-
<dependencies>
29-
<dependency>
30-
<groupId>org.apache.httpcomponents</groupId>
31-
<artifactId>httpclient</artifactId>
32-
</dependency>
33-
<dependency>
34-
<groupId>com.google.code.gson</groupId>
35-
<artifactId>gson</artifactId>
36-
</dependency>
37-
<dependency>
38-
<groupId>org.slf4j</groupId>
39-
<artifactId>slf4j-api</artifactId>
40-
<scope>provided</scope>
41-
</dependency>
42-
<!-- Test dependencies-->
43-
<dependency>
44-
<groupId>junit</groupId>
45-
<artifactId>junit</artifactId>
46-
<scope>test</scope>
47-
</dependency>
48-
<dependency>
49-
<groupId>org.mockito</groupId>
50-
<artifactId>mockito-all</artifactId>
51-
<scope>test</scope>
52-
</dependency>
53-
</dependencies>
14+
<dependencies>
15+
<dependency>
16+
<groupId>org.apache.httpcomponents</groupId>
17+
<artifactId>httpclient</artifactId>
18+
</dependency>
19+
<dependency>
20+
<groupId>com.google.code.gson</groupId>
21+
<artifactId>gson</artifactId>
22+
</dependency>
23+
<dependency>
24+
<groupId>org.slf4j</groupId>
25+
<artifactId>slf4j-api</artifactId>
26+
<scope>provided</scope>
27+
</dependency>
28+
<!-- Test dependencies -->
29+
<dependency>
30+
<groupId>junit</groupId>
31+
<artifactId>junit</artifactId>
32+
<scope>test</scope>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.mockito</groupId>
36+
<artifactId>mockito-all</artifactId>
37+
<scope>test</scope>
38+
</dependency>
39+
</dependencies>
40+
<build>
41+
<plugins>
42+
<plugin>
43+
<groupId>org.apache.maven.plugins</groupId>
44+
<artifactId>maven-jar-plugin</artifactId>
45+
<version>3.0.2</version>
46+
<executions>
47+
<execution>
48+
<goals>
49+
<goal>test-jar</goal>
50+
</goals>
51+
</execution>
52+
</executions>
53+
</plugin>
54+
</plugins>
55+
</build>
5456
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.sap.cloud.cf.monitoring.client.configuration;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.List;
6+
import java.util.concurrent.TimeUnit;
7+
8+
public class CustomMetricsConfiguration {
9+
10+
static final long DEFAULT_INTERVAL = TimeUnit.MINUTES.toMillis(1);
11+
private long interval = DEFAULT_INTERVAL;
12+
private boolean enabled = true;
13+
private List<String> metrics;
14+
private boolean metricQuantiles = false;
15+
16+
public long getInterval() {
17+
return interval;
18+
}
19+
20+
public boolean isEnabled() {
21+
return enabled;
22+
}
23+
24+
public List<String> getMetrics() {
25+
if (this.metrics == null) {
26+
return Collections.emptyList();
27+
}
28+
return new ArrayList<>(metrics);
29+
}
30+
31+
public boolean metricQuantiles() {
32+
return metricQuantiles;
33+
}
34+
35+
@Override
36+
public String toString() {
37+
return new StringBuilder("CustomMetricsConfiguration[").append("interval=")
38+
.append(interval)
39+
.append(", enabled=")
40+
.append(enabled)
41+
.append(", metrics=")
42+
.append(metrics)
43+
.append("]")
44+
.append(", metricQuantiles=")
45+
.append(metricQuantiles)
46+
.toString();
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.sap.cloud.cf.monitoring.client.configuration;
2+
3+
import java.util.Map;
4+
5+
import com.google.gson.Gson;
6+
import com.google.gson.GsonBuilder;
7+
8+
public class CustomMetricsConfigurationFactory {
9+
10+
private static final String CUSTOM_METRICS_KEY = "CUSTOM_METRICS";
11+
private static final Gson gson =
12+
new GsonBuilder().registerTypeAdapter(long.class, new LongIntervalGsonTypeAdapter()).create();
13+
14+
public static CustomMetricsConfiguration create() {
15+
return create(System.getenv());
16+
}
17+
18+
public static CustomMetricsConfiguration create(Map<String, String> env) {
19+
String customMetricsString = env.get(CUSTOM_METRICS_KEY);
20+
if (customMetricsString == null || customMetricsString.isEmpty()) {
21+
return new CustomMetricsConfiguration();
22+
}
23+
return gson.fromJson(customMetricsString, CustomMetricsConfiguration.class);
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.sap.cloud.cf.monitoring.client.configuration;
2+
3+
import static com.sap.cloud.cf.monitoring.client.configuration.CustomMetricsConfiguration.DEFAULT_INTERVAL;
4+
5+
import java.lang.reflect.Type;
6+
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
10+
import com.google.gson.JsonDeserializationContext;
11+
import com.google.gson.JsonDeserializer;
12+
import com.google.gson.JsonElement;
13+
import com.google.gson.JsonParseException;
14+
15+
final class LongIntervalGsonTypeAdapter implements JsonDeserializer<Long> {
16+
private static final Logger LOGGER = LoggerFactory.getLogger(LongIntervalGsonTypeAdapter.class);
17+
private static final long MINIMAL_INTERVAL = 20000L;
18+
19+
@Override
20+
public Long deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
21+
long value = Long.parseLong(json.getAsString());
22+
if (value < MINIMAL_INTERVAL) {
23+
LOGGER.warn(String.format(
24+
"The value of 'interval' property could not be less than %s. The default value %s will be used.",
25+
MINIMAL_INTERVAL, DEFAULT_INTERVAL));
26+
return DEFAULT_INTERVAL;
27+
}
28+
return value;
29+
}
30+
}

0 commit comments

Comments
 (0)