Skip to content
This repository was archived by the owner on Dec 5, 2023. It is now read-only.

Commit ff2cc18

Browse files
author
Phil Winder
authored
Merge pull request #26 from microservices-demo/refactor/prometheus
Rationalise prometheus to produce RED metrics.
2 parents 3e98fc2 + 65d444b commit ff2cc18

File tree

5 files changed

+127
-1
lines changed

5 files changed

+127
-1
lines changed

pom.xml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
<parent>
1515
<groupId>org.springframework.boot</groupId>
1616
<artifactId>spring-boot-starter-parent</artifactId>
17-
<version>1.4.0.RELEASE</version>
17+
<version>1.4.4.RELEASE</version>
1818
</parent>
1919

2020
<properties>
2121
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2222
<java.version>1.8</java.version>
23+
<prometheus.version>0.0.21</prometheus.version>
2324
</properties>
2425

2526
<dependencies>
@@ -36,6 +37,21 @@
3637
<artifactId>spring-cloud-starter-zipkin</artifactId>
3738
<version>1.1.0.RELEASE</version>
3839
</dependency>
40+
<dependency>
41+
<groupId>io.prometheus</groupId>
42+
<artifactId>simpleclient_spring_boot</artifactId>
43+
<version>${prometheus.version}</version>
44+
</dependency>
45+
<dependency>
46+
<groupId>io.prometheus</groupId>
47+
<artifactId>simpleclient_hotspot</artifactId>
48+
<version>${prometheus.version}</version>
49+
</dependency>
50+
<dependency>
51+
<groupId>io.prometheus</groupId>
52+
<artifactId>simpleclient_servlet</artifactId>
53+
<version>${prometheus.version}</version>
54+
</dependency>
3955
<dependency>
4056
<groupId>org.springframework.data</groupId>
4157
<artifactId>spring-data-rest-hal-browser</artifactId>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package works.weave.socks.cart.configuration;
2+
3+
import io.prometheus.client.exporter.MetricsServlet;
4+
import io.prometheus.client.hotspot.DefaultExports;
5+
import io.prometheus.client.spring.boot.SpringBootMetricsCollector;
6+
import org.springframework.beans.factory.annotation.Value;
7+
import org.springframework.boot.actuate.endpoint.PublicMetrics;
8+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
9+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
10+
import org.springframework.boot.web.servlet.ServletRegistrationBean;
11+
import org.springframework.context.annotation.Bean;
12+
import org.springframework.context.annotation.Configuration;
13+
14+
import java.util.Collection;
15+
16+
@Configuration
17+
@ConditionalOnClass(SpringBootMetricsCollector.class)
18+
class PrometheusAutoConfiguration {
19+
@Bean
20+
@ConditionalOnMissingBean(SpringBootMetricsCollector.class)
21+
SpringBootMetricsCollector springBootMetricsCollector(Collection<PublicMetrics> publicMetrics) {
22+
SpringBootMetricsCollector springBootMetricsCollector = new SpringBootMetricsCollector
23+
(publicMetrics);
24+
springBootMetricsCollector.register();
25+
return springBootMetricsCollector;
26+
}
27+
28+
@Bean
29+
@ConditionalOnMissingBean(name = "prometheusMetricsServletRegistrationBean")
30+
ServletRegistrationBean prometheusMetricsServletRegistrationBean(@Value("${prometheus.metrics" +
31+
".path:/metrics}") String metricsPath) {
32+
DefaultExports.initialize();
33+
return new ServletRegistrationBean(new MetricsServlet(), metricsPath);
34+
}
35+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package works.weave.socks.cart.configuration;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.context.annotation.Bean;
5+
import org.springframework.context.annotation.Configuration;
6+
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
7+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
8+
import works.weave.socks.cart.middleware.HTTPMonitoringInterceptor;
9+
10+
@Configuration
11+
public class WebMvcConfig extends WebMvcConfigurerAdapter {
12+
@Autowired
13+
private HTTPMonitoringInterceptor httpMonitoringInterceptor;
14+
15+
@Bean
16+
HTTPMonitoringInterceptor httpMonitoringInterceptor() {
17+
return new HTTPMonitoringInterceptor();
18+
}
19+
20+
@Override
21+
public void addInterceptors(InterceptorRegistry registry) {
22+
registry.addInterceptor(httpMonitoringInterceptor)
23+
.addPathPatterns("/**");
24+
}
25+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package works.weave.socks.cart.middleware;
2+
3+
import io.prometheus.client.Histogram;
4+
import org.springframework.beans.factory.annotation.Value;
5+
import org.springframework.web.servlet.HandlerInterceptor;
6+
import org.springframework.web.servlet.ModelAndView;
7+
8+
import javax.servlet.http.HttpServletRequest;
9+
import javax.servlet.http.HttpServletResponse;
10+
11+
public class HTTPMonitoringInterceptor implements HandlerInterceptor {
12+
static final Histogram requestLatency = Histogram.build()
13+
.name("request_duration_seconds")
14+
.help("Request duration in seconds.")
15+
.labelNames("service", "method", "route", "status_code")
16+
.register();
17+
18+
private static final String startTimeKey = "startTime";
19+
20+
@Value("${spring.application.name:carts}")
21+
private String serviceName;
22+
23+
@Override
24+
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse
25+
httpServletResponse, Object o) throws Exception {
26+
httpServletRequest.setAttribute(startTimeKey, System.nanoTime());
27+
return true;
28+
}
29+
30+
@Override
31+
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse
32+
httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
33+
long start = (long) httpServletRequest.getAttribute(startTimeKey);
34+
long elapsed = System.nanoTime() - start;
35+
double seconds = (double) elapsed / 1000000000.0;
36+
requestLatency.labels(
37+
serviceName,
38+
httpServletRequest.getMethod(),
39+
httpServletRequest.getServletPath(),
40+
Integer.toString(httpServletResponse.getStatus())
41+
).observe(seconds);
42+
}
43+
44+
@Override
45+
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse
46+
httpServletResponse, Object o, Exception e) throws Exception {
47+
}
48+
}

src/main/resources/application.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ endpoints.health.enabled=false
44
spring.zipkin.baseUrl=http://${zipkin:zipkin}:9411/
55
spring.sleuth.sampler.percentage=1.0
66
spring.application.name=carts
7+
# Disable actuator metrics endpoints
8+
endpoints.metrics.enabled=false

0 commit comments

Comments
 (0)