Skip to content

Commit 5221d0d

Browse files
committed
支持使用OpenTelemetry的SDK上报metrics到VictoriaMetrics
1 parent 673ce2a commit 5221d0d

File tree

8 files changed

+196
-0
lines changed

8 files changed

+196
-0
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ feign服务提供者,包含简单的基于feign实现的服务,使用consul
114114
## springboot-leaf
115115
整合美团开源的分布式ID生成服务leaf,包含记录HTTP接口耗时日志切面,数据库表初始化文件为leaf.sql
116116

117+
## springboot-opentelemetry
118+
集成OpenTelemetry的SDK采集上报可观测相关数据
119+
120+
- 支持Metrics推送至VictoriaMetrics(需在application.yml配置victoriaMetrics.url)
121+
117122
## springboot-netty
118123
包含基于netty+websocket实现的简易聊天室功能,入口页面为chat-netty.html
119124

pom.xml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<module>springboot-feign-consumer</module>
2121
<module>springboot-feign-provider</module>
2222
<module>springboot-leaf</module>
23+
<module>springboot-opentelemetry</module>
2324
<module>springboot-netty</module>
2425
<module>springboot-rocketmq-consumer</module>
2526
<module>springboot-rocketmq-producer</module>
@@ -89,6 +90,8 @@
8990
<alibaba-cloud.version>2023.0.1.2</alibaba-cloud.version>
9091
<xmemcached.version>2.4.7</xmemcached.version>
9192
<zookeeper.version>3.9.2</zookeeper.version>
93+
<opentelemetry.version>1.47.0</opentelemetry.version>
94+
<opentelemetry-semconv.version>1.30.0</opentelemetry-semconv.version>
9295
</properties>
9396

9497
<repositories>
@@ -100,6 +103,15 @@
100103

101104
<dependencyManagement>
102105
<dependencies>
106+
<!-- 要放在spring-boot-dependencies之前覆盖里面的版本 -->
107+
<dependency>
108+
<groupId>io.opentelemetry</groupId>
109+
<artifactId>opentelemetry-bom</artifactId>
110+
<version>${opentelemetry.version}</version>
111+
<type>pom</type>
112+
<scope>import</scope>
113+
</dependency>
114+
103115
<!-- Spring Dependencies -->
104116
<dependency>
105117
<groupId>org.springframework.boot</groupId>
@@ -176,6 +188,11 @@
176188
<artifactId>springboot-leaf</artifactId>
177189
<version>${project.version}</version>
178190
</dependency>
191+
<dependency>
192+
<groupId>com.doodl6</groupId>
193+
<artifactId>springboot-opentelemetry</artifactId>
194+
<version>${project.version}</version>
195+
</dependency>
179196
<dependency>
180197
<groupId>com.doodl6</groupId>
181198
<artifactId>springboot-netty</artifactId>
@@ -348,6 +365,25 @@
348365
<artifactId>rocketmq-client</artifactId>
349366
<version>${rocketmq.version}</version>
350367
</dependency>
368+
<dependency>
369+
<groupId>org.apache.rocketmq</groupId>
370+
<artifactId>rocketmq-common</artifactId>
371+
<version>${rocketmq.version}</version>
372+
<exclusions>
373+
<exclusion>
374+
<groupId>io.opentelemetry</groupId>
375+
<artifactId>opentelemetry-exporter-otlp</artifactId>
376+
</exclusion>
377+
<exclusion>
378+
<groupId>io.opentelemetry</groupId>
379+
<artifactId>opentelemetry-exporter-prometheus</artifactId>
380+
</exclusion>
381+
<exclusion>
382+
<groupId>io.opentelemetry</groupId>
383+
<artifactId>opentelemetry-sdk</artifactId>
384+
</exclusion>
385+
</exclusions>
386+
</dependency>
351387
<dependency>
352388
<groupId>org.apache.rocketmq</groupId>
353389
<artifactId>rocketmq-acl</artifactId>
@@ -628,6 +664,12 @@
628664
<artifactId>rxjava</artifactId>
629665
<version>${rxjava.version}</version>
630666
</dependency>
667+
668+
<dependency>
669+
<groupId>io.opentelemetry.semconv</groupId>
670+
<artifactId>opentelemetry-semconv</artifactId>
671+
<version>${opentelemetry-semconv.version}</version>
672+
</dependency>
631673
</dependencies>
632674
</dependencyManagement>
633675

springboot-opentelemetry/pom.xml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>com.doodl6</groupId>
8+
<artifactId>SpringBoot-Project</artifactId>
9+
<version>${revision}</version>
10+
</parent>
11+
12+
<artifactId>springboot-opentelemetry</artifactId>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>com.doodl6</groupId>
17+
<artifactId>springboot-common-web</artifactId>
18+
</dependency>
19+
20+
<dependency>
21+
<groupId>io.opentelemetry</groupId>
22+
<artifactId>opentelemetry-sdk</artifactId>
23+
</dependency>
24+
25+
<dependency>
26+
<groupId>io.opentelemetry</groupId>
27+
<artifactId>opentelemetry-exporter-otlp</artifactId>
28+
</dependency>
29+
<dependency>
30+
<groupId>io.opentelemetry.semconv</groupId>
31+
<artifactId>opentelemetry-semconv</artifactId>
32+
</dependency>
33+
</dependencies>
34+
35+
</project>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.doodl6.springboot.metrics;
2+
3+
import io.opentelemetry.api.GlobalOpenTelemetry;
4+
import io.opentelemetry.api.metrics.LongCounter;
5+
import io.opentelemetry.api.metrics.Meter;
6+
import lombok.extern.slf4j.Slf4j;
7+
8+
@Slf4j
9+
public class Counter {
10+
11+
private static LongCounter REQUEST_COUNTER;
12+
13+
public static LongCounter getRequestCounter() {
14+
if (REQUEST_COUNTER == null) {
15+
Meter meter = GlobalOpenTelemetry.getMeter("springboot-metrics");
16+
REQUEST_COUNTER = meter.counterBuilder("http_request_count").build();
17+
}
18+
return REQUEST_COUNTER;
19+
}
20+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.doodl6.springboot.metrics;
2+
3+
import cn.idev.excel.util.StringUtils;
4+
import io.opentelemetry.api.GlobalOpenTelemetry;
5+
import io.opentelemetry.api.OpenTelemetry;
6+
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
7+
import io.opentelemetry.sdk.OpenTelemetrySdk;
8+
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
9+
import io.opentelemetry.sdk.metrics.export.MetricExporter;
10+
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
11+
import io.opentelemetry.sdk.resources.Resource;
12+
import io.opentelemetry.semconv.ServiceAttributes;
13+
import jakarta.annotation.PostConstruct;
14+
import lombok.extern.slf4j.Slf4j;
15+
import org.springframework.beans.factory.annotation.Value;
16+
import org.springframework.boot.web.servlet.ServletComponentScan;
17+
import org.springframework.context.annotation.Configuration;
18+
19+
import java.util.concurrent.TimeUnit;
20+
21+
@Slf4j
22+
@Configuration
23+
@ServletComponentScan(basePackages = "com.doodl6.springboot.metrics.filter")
24+
public class MetricsAutoConfig {
25+
26+
private static final String METRICS_PATH = "/opentelemetry/v1/metrics";
27+
28+
@Value("${spring.application.name}")
29+
private String applicationName;
30+
31+
@Value("${victoriaMetrics.url}")
32+
private String victoriaMetricsUrl;
33+
34+
@Value("${victoriaMetrics.interval:10}")
35+
private int interval;
36+
37+
@PostConstruct
38+
public void init() {
39+
if (StringUtils.isBlank(victoriaMetricsUrl)) {
40+
throw new IllegalArgumentException("victoriaMetricsUrl is required");
41+
}
42+
43+
GlobalOpenTelemetry.set(createOpenTelemetry());
44+
}
45+
46+
public OpenTelemetry createOpenTelemetry() {
47+
Resource resource = Resource.builder()
48+
.put(ServiceAttributes.SERVICE_NAME, applicationName)
49+
.build();
50+
MetricExporter metricExporter = OtlpHttpMetricExporter.builder().setEndpoint(victoriaMetricsUrl + METRICS_PATH).build();
51+
PeriodicMetricReader metricReader = PeriodicMetricReader.builder(metricExporter).setInterval(interval, TimeUnit.SECONDS).build();
52+
SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
53+
.addResource(resource)
54+
.registerMetricReader(metricReader)
55+
.build();
56+
return OpenTelemetrySdk.builder()
57+
.setMeterProvider(sdkMeterProvider)
58+
.build();
59+
}
60+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.doodl6.springboot.metrics.filter;
2+
3+
import com.doodl6.springboot.metrics.Counter;
4+
import jakarta.servlet.FilterChain;
5+
import jakarta.servlet.annotation.WebFilter;
6+
import jakarta.servlet.http.HttpServletRequest;
7+
import jakarta.servlet.http.HttpServletResponse;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.core.annotation.Order;
10+
import org.springframework.web.filter.OncePerRequestFilter;
11+
12+
@Slf4j
13+
@Order(10)
14+
@WebFilter(asyncSupported = true)
15+
public class RequestCountFilter extends OncePerRequestFilter {
16+
17+
@Override
18+
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
19+
try {
20+
Counter.getRequestCounter().add(1);
21+
} catch (Exception e) {
22+
log.error("RequestCountFilter exception", e);
23+
}
24+
}
25+
26+
}

springboot-web/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@
4848
<artifactId>springboot-leaf</artifactId>
4949
</dependency>
5050

51+
<dependency>
52+
<groupId>com.doodl6</groupId>
53+
<artifactId>springboot-opentelemetry</artifactId>
54+
</dependency>
55+
5156
<dependency>
5257
<groupId>com.doodl6</groupId>
5358
<artifactId>springboot-netty</artifactId>

springboot-web/src/main/resources/application.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,6 @@ rocketmq:
3939
topic: OrderlyMessage
4040
springdoc:
4141
packagesToScan: com.doodl6
42+
victoriaMetrics:
43+
url: http://localhost:8428
44+
interval: 10

0 commit comments

Comments
 (0)