opentelemetry-solon-cloud-plugin [预览]
<dependency>
<groupId>org.noear</groupId>
<artifactId>opentelemetry-solon-cloud-plugin</artifactId>
</dependency>
1、描述
(3.7.3-SNAPSHOT 后支持)分布式扩展插件。基于 opentelemetry 适配的 solon cloud 插件。可与支持 opentelemetry 规范的服务,一同提供链路跟踪支持。
2、配置示例
solon.app:
name: "demoapp"
group: "demo"
solon.cloud.opentelemetry:
server: "http://localhost:4317"
trace:
enable: true #是否启用(默认:true)
exclude: "/healthz,/_run/check/" #排除路径,多个以,号隔开
3、附带技能
支持 slf4j 日志框架的 MDC 变量(可以通过格式符获取,例:"%X{X-TraceId}"):
- X-TraceId
- X-SpanId
4、代码应用
- 添加示例需要的依赖
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
<version>${opentelemetry.version}</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
<version>${opentelemetry.version}</version>
</dependency>
<dependency>
<groupId>io.opentelemetry.semconv</groupId>
<artifactId>opentelemetry-semconv</artifactId>
<version>${opentelemetry-semconv.version}</version>
</dependency>
</dependencies>
- 启用和配置跟踪器实现(仅供参考)
public class App {
public static void main(String[] args) {
Solon.start(App.class, args);
}
}
@Configuration
public class DemoConfig {
@Bean
public Tracer tracer(OpenTelemetry openTelemetry) {
return openTelemetry.getTracer(Solon.cfg().appName(), "1.0.0");
}
@Bean
public OpenTelemetry openTelemetry(AppContext context) {
CloudProps cloudProps = new CloudProps(context, "opentelemetry");
// 1. 定义资源 (Resource),包含服务名称
Resource serviceResource = Resource.getDefault()
.toBuilder()
.put(ServiceAttributes.SERVICE_NAME, Solon.cfg().appName())
.put(ServiceAttributes.SERVICE_VERSION,"1.0.0")
.build();
// 2. 配置 Span Exporter (例如 OTLP/gRPC) //
OtlpGrpcSpanExporter otlpExporter = OtlpGrpcSpanExporter.builder()
// 默认连接到 http://localhost:4317 (OTLP Collector)
.setEndpoint(cloudProps.getServer())
.setTimeout(30, TimeUnit.SECONDS)
.build();
// 3. 配置 Span Processor (例如 BatchSpanProcessor)
BatchSpanProcessor spanProcessor = BatchSpanProcessor.builder(otlpExporter)
.setScheduleDelay(100, TimeUnit.MILLISECONDS)
.build();
// 4. 配置 Tracer Provider
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
.setResource(serviceResource)
.addSpanProcessor(spanProcessor)
// 设置采样器 (Sampler.alwaysOn() 表示 100% 采样)
.setSampler(Sampler.alwaysOn())
.build();
// 5. 构建 OpenTelemetry SDK 并注册为全局单例
OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder()
.setTracerProvider(tracerProvider)
.buildAndRegisterGlobal();
System.out.println("OpenTelemetry SDK initialized and set as global.");
return openTelemetrySdk;
}
}
- 应用代码
// -- 可以当它不存在得用
@Controller
public class TestController {
@NamiClient
UserService userService;
@Inject
OrderService orderService;
@Mapping("/")
public String hello(String name) {
name = userService.getUser(name);
return orderService.orderCreate(name, "1");
}
}
import org.noear.solon.annotation.Component;
import org.noear.solon.cloud.telemetry.Spans;
import org.noear.solon.cloud.telemetry.annotation.Tracing;
//-- 通过注解增加业务链节点 ( @Tracing )
@Component
public class OrderService {
@Tracing(name = "创建订单", tags = "订单=#{orderId}")
public String orderCreate(String userName, String orderId) {
//手动添加 tag
Spans.active().setAttribute("用户", userName);
return orderId;
}
}
5、@Tracing 注意事项
-
控制器或最终转为 Handler 的类可以不加(已由 Filter 全局处理了),加了会产生新的 Span
-
修改当前 Span 的操作名
@Controller
public class TestController {
@Mapping("/")
public String hello(String name) {
Spans.active().setOperationName("Hello"); //修改当前操作名
return "Hello " + name;
}
}
- 添加在空接口上,一般会无效(比如:Mapper)。除非其底层有适配
- 需加在代理的类上,不然拦截器不会生效。如:@Component 注解的类