Skip to content

Commit d49bb9d

Browse files
Adrian Coleadriancole
Adrian Cole
authored andcommitted
Switches http request duration to undertow filter
1 parent 65a2db7 commit d49bb9d

File tree

6 files changed

+128
-177
lines changed

6 files changed

+128
-177
lines changed

zipkin-autoconfigure/metrics-prometheus/pom.xml

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,6 @@
3131
</properties>
3232

3333
<dependencies>
34-
<!-- prometheusMetricsFilter is a servlet filter -->
35-
<dependency>
36-
<groupId>javax.servlet</groupId>
37-
<artifactId>javax.servlet-api</artifactId>
38-
<version>3.0.1</version>
39-
<scope>provided</scope>
40-
</dependency>
41-
4234
<!-- Prometheus client -->
4335
<dependency>
4436
<groupId>io.prometheus</groupId>
@@ -51,17 +43,16 @@
5143
<artifactId>simpleclient_hotspot</artifactId>
5244
<version>${prometheus_simpleclient.version}</version>
5345
</dependency>
54-
<!-- Expose request times -->
55-
<dependency>
56-
<groupId>io.prometheus</groupId>
57-
<artifactId>simpleclient_servlet</artifactId>
58-
<version>${prometheus_simpleclient.version}</version>
59-
</dependency>
6046
<!-- Prometheus Spring Boot integration -->
6147
<dependency>
6248
<groupId>io.prometheus</groupId>
6349
<artifactId>simpleclient_spring_boot</artifactId>
6450
<version>${prometheus_simpleclient.version}</version>
6551
</dependency>
52+
<dependency>
53+
<groupId>org.springframework.boot</groupId>
54+
<artifactId>spring-boot-starter-undertow</artifactId>
55+
<version>${spring-boot.version}</version>
56+
</dependency>
6657
</dependencies>
6758
</project>

zipkin-autoconfigure/metrics-prometheus/src/main/java/zipkin/autoconfigure/metrics/PrometheusMetricsAutoConfiguration.java

Lines changed: 0 additions & 149 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* Copyright 2015-2017 The OpenZipkin Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
15+
package zipkin.autoconfigure.prometheus;
16+
17+
import io.prometheus.client.Histogram;
18+
import io.prometheus.client.hotspot.DefaultExports;
19+
import io.prometheus.client.spring.boot.EnablePrometheusEndpoint;
20+
import io.prometheus.client.spring.boot.EnableSpringBootMetricsCollector;
21+
import io.prometheus.client.spring.web.EnablePrometheusTiming;
22+
import io.undertow.server.HandlerWrapper;
23+
import io.undertow.server.HttpHandler;
24+
import io.undertow.server.HttpServerExchange;
25+
import org.springframework.boot.context.embedded.undertow.UndertowDeploymentInfoCustomizer;
26+
import org.springframework.context.annotation.Bean;
27+
import org.springframework.context.annotation.Configuration;
28+
29+
@EnablePrometheusEndpoint
30+
@EnableSpringBootMetricsCollector
31+
@EnablePrometheusTiming
32+
@Configuration
33+
public class ZipkinPrometheusMetricsAutoConfiguration {
34+
// needs to be a JVM singleton
35+
static final Histogram http_request_duration_seconds = Histogram.build()
36+
.labelNames("path", "method")
37+
.help("Response time histogram")
38+
.name("http_request_duration_seconds")
39+
.register();
40+
41+
ZipkinPrometheusMetricsAutoConfiguration() {
42+
DefaultExports.initialize();
43+
}
44+
45+
@Bean Histogram httpRequestDuration() {
46+
return http_request_duration_seconds;
47+
}
48+
49+
@Bean UndertowDeploymentInfoCustomizer httpRequestDurationCustomizer() {
50+
HttpRequestDurationHandler.Wrapper result =
51+
new HttpRequestDurationHandler.Wrapper(http_request_duration_seconds);
52+
return info -> info.addInitialHandlerChainWrapper(result);
53+
}
54+
55+
static final class HttpRequestDurationHandler implements HttpHandler {
56+
static final class Wrapper implements HandlerWrapper {
57+
final Histogram httpRequestDuration;
58+
59+
Wrapper(Histogram httpRequestDuration) {
60+
this.httpRequestDuration = httpRequestDuration;
61+
}
62+
63+
@Override public HttpHandler wrap(HttpHandler next) {
64+
return new HttpRequestDurationHandler(httpRequestDuration, next);
65+
}
66+
}
67+
68+
final Histogram httpRequestDuration;
69+
final HttpHandler next;
70+
71+
HttpRequestDurationHandler(Histogram httpRequestDuration, HttpHandler next) {
72+
this.httpRequestDuration = httpRequestDuration;
73+
this.next = next;
74+
}
75+
76+
@Override public void handleRequest(HttpServerExchange exchange) throws Exception {
77+
if (!exchange.isComplete()) {
78+
Histogram.Timer timer = httpRequestDuration
79+
.labels(exchange.getRelativePath(), exchange.getRequestMethod().toString())
80+
.startTimer();
81+
exchange.addExchangeCompleteListener((exchange1, nextListener) -> {
82+
timer.observeDuration();
83+
nextListener.proceed();
84+
});
85+
}
86+
next.handleRequest(exchange);
87+
}
88+
}
89+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2-
zipkin.autoconfigure.metrics.PrometheusMetricsAutoConfiguration
2+
zipkin.autoconfigure.prometheus.ZipkinPrometheusMetricsAutoConfiguration

zipkin-server/src/main/java/zipkin/server/ZipkinServerConfiguration.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.springframework.boot.actuate.metrics.buffer.CounterBuffers;
2323
import org.springframework.boot.actuate.metrics.buffer.GaugeBuffers;
2424
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
25+
import org.springframework.boot.context.embedded.undertow.UndertowDeploymentInfoCustomizer;
2526
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
2627
import org.springframework.context.annotation.Bean;
2728
import org.springframework.context.annotation.Condition;
@@ -44,6 +45,9 @@ public class ZipkinServerConfiguration {
4445
return new ZipkinHealthIndicator(healthAggregator);
4546
}
4647

48+
@Autowired(required = false)
49+
UndertowDeploymentInfoCustomizer httpRequestDurationCustomizer;
50+
4751
@Bean public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory(
4852
@Value("${zipkin.query.allowed-origins:*}") String allowedOrigins
4953
) {
@@ -52,6 +56,9 @@ public class ZipkinServerConfiguration {
5256
factory.addDeploymentInfoCustomizers(
5357
info -> info.addInitialHandlerChainWrapper(cors)
5458
);
59+
if (httpRequestDurationCustomizer != null) {
60+
factory.addDeploymentInfoCustomizers(httpRequestDurationCustomizer);
61+
}
5562
return factory;
5663
}
5764

zipkin-server/src/test/java/zipkin/server/ZipkinServerConfigurationTest.java

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@
2424
import org.springframework.boot.actuate.metrics.buffer.CounterBuffers;
2525
import org.springframework.boot.actuate.metrics.buffer.GaugeBuffers;
2626
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
27+
import org.springframework.boot.context.embedded.undertow.UndertowDeploymentInfoCustomizer;
2728
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
2829
import org.springframework.context.annotation.Bean;
2930
import org.springframework.context.annotation.Configuration;
3031
import org.springframework.context.annotation.Import;
31-
import zipkin.autoconfigure.metrics.PrometheusMetricsAutoConfiguration;
32+
import zipkin.autoconfigure.prometheus.ZipkinPrometheusMetricsAutoConfiguration;
3233
import zipkin.autoconfigure.ui.ZipkinUiAutoConfiguration;
3334
import zipkin.server.brave.BraveConfiguration;
3435

@@ -69,18 +70,6 @@ public void httpCollector_canDisable() {
6970
context.getBean(ZipkinHttpCollector.class);
7071
}
7172

72-
@Test public void prometheusHistogram() {
73-
context.register(
74-
PropertyPlaceholderAutoConfiguration.class,
75-
ZipkinServerConfigurationTest.Config.class,
76-
ZipkinServerConfiguration.class,
77-
PrometheusMetricsAutoConfiguration.class
78-
);
79-
context.refresh();
80-
81-
assertThat(context.getBean("http_request_duration_seconds", Histogram.class)).isNotNull();
82-
}
83-
8473
@Test public void query_enabledByDefault() {
8574
context.register(
8675
PropertyPlaceholderAutoConfiguration.class,
@@ -119,6 +108,30 @@ public void httpCollector_canDisable() {
119108
}
120109
}
121110

111+
@Test public void providesHttpRequestDurationHistogram() {
112+
context.register(
113+
PropertyPlaceholderAutoConfiguration.class,
114+
ZipkinServerConfigurationTest.Config.class,
115+
ZipkinServerConfiguration.class,
116+
ZipkinPrometheusMetricsAutoConfiguration.class
117+
);
118+
context.refresh();
119+
120+
context.getBean(Histogram.class);
121+
}
122+
123+
@Test public void providesHttpRequestDurationCustomizer() {
124+
context.register(
125+
PropertyPlaceholderAutoConfiguration.class,
126+
ZipkinServerConfigurationTest.Config.class,
127+
ZipkinServerConfiguration.class,
128+
ZipkinPrometheusMetricsAutoConfiguration.class
129+
);
130+
context.refresh();
131+
132+
context.getBean(UndertowDeploymentInfoCustomizer.class);
133+
}
134+
122135
@Test public void ui_enabledByDefault() {
123136
context.register(
124137
PropertyPlaceholderAutoConfiguration.class,

0 commit comments

Comments
 (0)