作为第二大活跃的云原生计算基金会 (CNCF) 项目,OpenTelemetry 正朝着成为无处不在的、统一的观测标准和框架的方向发展。OpenTelemetry 的成功归功于其全面且功能丰富的工具集,它允许用户以较低的努力从其应用程序中检索有价值的可观测性数据。OpenTelemetry Java 代理是 OpenTelemetry 生态系统中*最成熟且功能最丰富的组件之一。它为基于 JVM 的应用程序提供自动插桩,并为流行的 Java 框架和库提供广泛的自动插桩模块。
OpenTelemetry Java 代理中使用的原始插桩方法在自动插桩模块的维护和开发方面存在一些限制。作为我们对 OpenTelemetry 的加强承诺的一部分,Elastic® 帮助发展和改进 OpenTelemetry 项目和组件。Elastic 对 OpenTelemetry 的 Elastic Common Schema 贡献是开源社区的重要一步。作为我们对 OpenTelemetry 承诺的另一步,Elastic 开始为 OpenTelemetry Java 代理做出贡献。
Elastic 基于 invokedynamic 的插桩方法
为了克服在 OpenTelemetry Java 代理中开发和维护自动插桩模块时存在的上述限制,Elastic 于 2023 年 7 月开始贡献其基于 invokedynamic 的插桩方法给 OpenTelemetry Java 代理。
为了解释改进之处,您应该知道,在 Java 中,对应用程序进行自动插桩的常见方法是利用 Java 代理在运行时进行字节码插桩。Byte Buddy 是一种流行的通用工具,可帮助进行字节码插桩,而无需直接处理 Java 的字节码。从目标应用程序代码中收集可观测性数据的插桩逻辑存在于所谓的advice 方法中。Byte Buddy 提供了将这些 advice 方法挂钩到目标应用程序方法的不同方式
- Advice 内联:advice 方法的代码被复制到已插桩的目标方法中。
- 静态 advice 分派:已插桩的目标方法调用需要被已插桩代码可见的静态 advice 方法。
- 使用 invokedynamic 的 advice 分派:已插桩的目标方法使用 JVM 的 invokedynamic 字节码指令来调用与已插桩代码隔离的 advice 方法。
在关于Elastic 的 Java APM 代理使用 invokedynamic 的相关博文中,对这些不同的方法进行了详细描述。简而言之,advice 内联和分派到静态 advice 方法这两种方法在编写和维护 advice 代码方面都存在一些限制。到目前为止,OpenTelemetry Java 代理在其字节码插桩中使用了advice 内联。由此产生的对开发插桩的限制在相应的开发人员指南中有记录。其中,无法调试 advice 代码的限制是开发和维护插桩代码时的一个痛苦的限制。
Elastic 的 APM Java 代理多年来一直使用 invokedynamic 方法及其优势 — 已被成千上万的客户验证。为了帮助改进 OpenTelemetry Java 代理,Elastic 开始贡献 invokedynamic 方法,其目标是简化和改进自动插桩模块的开发和可维护性。贡献提案和实现大纲在此 GitHub 问题中有更详细的记录。
随着新方法的实施,Elastic 将帮助迁移现有的插桩,以便 OTel Java 社区可以从基于 invokedynamic 的插桩方法中受益。
Elastic 原生支持 OTel,并具有许多功能来帮助您使用 OTel 分析您的应用程序。
- Elastic Observability 中对 OpenTelemetry 的原生支持
- 插桩 OpenTelemetry 的最佳实践
- 在 Elastic 上使用 OpenTelemetry 的独立性
使用 OpenTelemetry 进行插桩
本文中描述的任何特性或功能的发布和时间安排仍由 Elastic 自行决定。任何当前不可用的特性或功能可能不会按时交付或根本不交付。