如何用OpenTelemetry从零开始编写一个Instrumentation?

2026-05-21 15:235阅读0评论运维
  • 内容介绍
  • 文章标签
  • 相关推荐

从零开始编写一个 OpenTelemetry Instrumentation

前段时间我们从 SkyWalking 切换到了 OpenTelemetry ,这时候之前使用 SkyWalking 编写的插件也得转移到 OpenTelemetry 体系下。 我也写了相关介绍文章: 实战:如何优雅的从 SkyWalking 切换到 OpenTelemetry 好在 OpenTelemetry 提供了丰富的 Instrumentation 库, 我算是看透了。 但仍然有一些库或框架未被支持。

恰好公司内部也有一些开发同学有类似的需求:,正宗。

OpenTelemetry 实战:从 0 到 1 编写一个 Instrumentation

比如它会拉取目前最新的依赖进行测试:

@AutoService public class PowerJobInstrumentationModule extends InstrumentationModule { public PowerJobInstrumentationModule { super; }

@Override  
public List typeInstrumentations {  
  return asList);  
}

}

这样就可以把整个链路串起来 一边还能查看 PowerJob 调度的 JobId、以及调用参数等数据,这样排查问题时也更加直观,这是可以说的吗?。

前置知识点

在正式开发 Instrumentation 之前还需要了解一些前置知识点,我跪了。。

主要原因是公司内部在使用 PowerJob 作为我们的分布式调度系统, 一边又是使用 OpenTelemetry 作为可观测的底座,但目前 OpenTelemetry 还没有对 PowerJob 提供支持,目前社区只对同类型的 XXL-JOB 有支持。

创建 InstrumentationModule

先说说第一步需要创建一个 InstrumentationModule:

摆烂。 public PowerJobInstrumentationModule { super; }

我们需要遵守 v4_0_0 的规则,一边还得与 PowerJo 白嫖。 bInstrumentationModule 中定义的名称相同:

实现 TypeInstrumentation

我们都曾是... 之后便是实现这里最核心的 BasicProcessorInstrumentation。

public class BasicProcessorInstrumentation implements TypeInstrumentation { @Overr 这家伙... ide public ElementMatcher typeMatcher { return implementsInterface); }

@Override  
public void transform {  
  transformer.applyAdviceToMethod(  
      named.and).and),  
      this.getClass.getName + "$ProcessAdvice");  
}

从它的代码也可以看出, 这里主要是指定我们需要对哪个方法的哪个函数进行埋点,然后埋点之后的处理逻辑是在哪个类中实现的。

Muzzle 校验

第三个是 Muzzle 校验,Muzzle 是为了保证 javaagent 在业务代码中使用时和运行时的依赖不发生冲突而定义的一个校验规则。

啊这... muzzle { pass { assertInverse instrumentationModule versions") minJavaVersionSupported extraDependency } }

extraDependency: 的作用是额外需要依赖的包, 我这里额外使用了这个包里的一些类,如果不加上的话在做 Muzzle 校验时也会失败,翻旧账。。

单元测试

再说说便是单元测试了:

摸鱼。 @Test void testBasicProcessor throws Exception { long jobId = 1; String jobParam = "abc"; TaskContext taskContext = genTaskContext; BasicProcessor testBasicProcessor = new TestBasicProcessor; testBasicProcessor.process;

assertThat.satisfiesExactly;}  

gRPCgRPC 和 PowerJob instrumentation 对比

gRPC特性 gRPC功能描述 PowerJob特性 PowerJob功能描述
客户端拦截器 支持客户端拦截器 ,用于埋点 无特定 点 无特定 点,需要使用 Agent 级别埋点
服务端拦截器 支持服务端拦截器 ,用于埋点 无特定 点 同上,需 Agent 级别埋点
library模块 存在 library 模块,可手动引入实现 trace 埋点 无 library 模块 暂无 library 模块,直接使用 Agent 级别埋点

其实整个埋点过程非常简单,我们可以参考一些现有的 instrumentation 就可以很快实现逻辑; 换个赛道。 真正麻烦的时候在提交 PR 时需要通过 CI 校验。 我这里大概提交了 8次才把 CI 全部跑通过。

从零开始编写一个 OpenTelemetry Instrumentation

前段时间我们从 SkyWalking 切换到了 OpenTelemetry ,这时候之前使用 SkyWalking 编写的插件也得转移到 OpenTelemetry 体系下。 我也写了相关介绍文章: 实战:如何优雅的从 SkyWalking 切换到 OpenTelemetry 好在 OpenTelemetry 提供了丰富的 Instrumentation 库, 我算是看透了。 但仍然有一些库或框架未被支持。

恰好公司内部也有一些开发同学有类似的需求:,正宗。

OpenTelemetry 实战:从 0 到 1 编写一个 Instrumentation

比如它会拉取目前最新的依赖进行测试:

@AutoService public class PowerJobInstrumentationModule extends InstrumentationModule { public PowerJobInstrumentationModule { super; }

@Override  
public List typeInstrumentations {  
  return asList);  
}

}

这样就可以把整个链路串起来 一边还能查看 PowerJob 调度的 JobId、以及调用参数等数据,这样排查问题时也更加直观,这是可以说的吗?。

前置知识点

在正式开发 Instrumentation 之前还需要了解一些前置知识点,我跪了。。

主要原因是公司内部在使用 PowerJob 作为我们的分布式调度系统, 一边又是使用 OpenTelemetry 作为可观测的底座,但目前 OpenTelemetry 还没有对 PowerJob 提供支持,目前社区只对同类型的 XXL-JOB 有支持。

创建 InstrumentationModule

先说说第一步需要创建一个 InstrumentationModule:

摆烂。 public PowerJobInstrumentationModule { super; }

我们需要遵守 v4_0_0 的规则,一边还得与 PowerJo 白嫖。 bInstrumentationModule 中定义的名称相同:

实现 TypeInstrumentation

我们都曾是... 之后便是实现这里最核心的 BasicProcessorInstrumentation。

public class BasicProcessorInstrumentation implements TypeInstrumentation { @Overr 这家伙... ide public ElementMatcher typeMatcher { return implementsInterface); }

@Override  
public void transform {  
  transformer.applyAdviceToMethod(  
      named.and).and),  
      this.getClass.getName + "$ProcessAdvice");  
}

从它的代码也可以看出, 这里主要是指定我们需要对哪个方法的哪个函数进行埋点,然后埋点之后的处理逻辑是在哪个类中实现的。

Muzzle 校验

第三个是 Muzzle 校验,Muzzle 是为了保证 javaagent 在业务代码中使用时和运行时的依赖不发生冲突而定义的一个校验规则。

啊这... muzzle { pass { assertInverse instrumentationModule versions") minJavaVersionSupported extraDependency } }

extraDependency: 的作用是额外需要依赖的包, 我这里额外使用了这个包里的一些类,如果不加上的话在做 Muzzle 校验时也会失败,翻旧账。。

单元测试

再说说便是单元测试了:

摸鱼。 @Test void testBasicProcessor throws Exception { long jobId = 1; String jobParam = "abc"; TaskContext taskContext = genTaskContext; BasicProcessor testBasicProcessor = new TestBasicProcessor; testBasicProcessor.process;

assertThat.satisfiesExactly;}  

gRPCgRPC 和 PowerJob instrumentation 对比

gRPC特性 gRPC功能描述 PowerJob特性 PowerJob功能描述
客户端拦截器 支持客户端拦截器 ,用于埋点 无特定 点 无特定 点,需要使用 Agent 级别埋点
服务端拦截器 支持服务端拦截器 ,用于埋点 无特定 点 同上,需 Agent 级别埋点
library模块 存在 library 模块,可手动引入实现 trace 埋点 无 library 模块 暂无 library 模块,直接使用 Agent 级别埋点

其实整个埋点过程非常简单,我们可以参考一些现有的 instrumentation 就可以很快实现逻辑; 换个赛道。 真正麻烦的时候在提交 PR 时需要通过 CI 校验。 我这里大概提交了 8次才把 CI 全部跑通过。