使用OpenTelemetry来监控GoLang应用

1. 前言

我曾经写过一篇关于OpenTelemetry的文章,介绍如何使用基于eBPF的绝对无侵入方式来监控各种语言的应用。这种方式仍然是OpenTelemetry非侵入式监控GoLang应用的主要方式之一,但还有一种不修改应用代码来监控GoLang应用的方法,也比较成熟并被广泛使用,这里一并介绍一下。

2. 使用基于eBPF的绝对无侵入方式(OBI)

这是对我原来的文章《OpenTelemetry OBI - 非侵入式监控各种语言应用的神器的简单回顾,详细信息请参照原文。

首先要下载OBI工具,到 OBI 的发行网页(Releases · open-telemetry/opentelemetry-ebpf-instrumentation · GitHub),根据您的平台选择最新的发行版来下载。比如对于最常见的平台(amd64) 和当前最新的版本好v0.10.0, 下载:obi-v0.10.0-linux-amd64.tar.gz

配饰OBI的方式非常多。可以采用环境变量,也可以用配置文件。对于这个简单的测试,我使用了以下的配置文件:obi.yaml

XML 复制代码
discovery:
  instrument:
    - open_ports: 8080,9090,28080
log_level: DEBUG

ebpf:
  context_propagation: all

otel_traces_export:
  endpoint: http://localhost:4318

otel_metrics_export:
  endpoint: http://loalhost:4318

注意:

  • 这个配置文件说明我要监控8080、9090和28080三个端口的应用。
  • 通过OTLP协议发送信息到OpenTelemetry Collector或者OpenTelemetry后端,这个例子里是http://localhost:4318

以下是运行OBI的命令(在应用所在的Linux主机上运行,注意应用的端口必须在 obi.yaml 设置的范围之内):

bash 复制代码
sudo ./obi --config=./obi.yaml

至于配置OBI的详细说明,请参照官方文档:Configure OBI | OpenTelemetry

为了让OpenTelemetry很好的区分不同的应用,请在启动应用之前,设置OTEL_SERVICE_NAME环境变量。例如:

复制代码
export OTEL_SERVICE_NAME=my-godemo
./app

这样,如果访问您的程序,在OpenTelemetry Collector或者OpenTelemetry后端,就可以发现大量的metrics和traces。

3. 使用编译时无侵入插桩(Compile-Time Instrumentation)

3.1 概述

这种方式也不需要修改应用代码,只是需要稍微调整一下编译的命令。

没有额外配置的情况下,编译时无侵入插桩 otelc 会自动扫描并识别项目中引入的以下依赖,并自动为你应用内置的 Hook 规则:

  1. HTTP 框架
  • net/http(标准库)、github.com/gin-gonic/gin

  • 自动拦截 HTTP Request/Response,自动从 Header 提取/注入 TraceContext

  1. RPC 框架
  1. 数据库/SQL
  1. 缓存/MQ
  1. 日志与指标

3.2 下载 otelc 工具

到"Releases · open-telemetry/opentelemetry-go-compile-instrumentation · GitHub"选择和您的平台匹配的otelc的最高版本下载即可。对于我使用的Linux平台,大致的命令如下:

复制代码
wget https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation/releases/download/v1.0.1/otelc-linux-amd64
mv otelc-linux-amd64 otelc
chmod +x otelc

如果为了方便调用,可以把 otelc 放到 /usr/bin 下。

3.3 使用 otelc 编译GoLang代码

如果您原来的编译命令是:

复制代码
go build -o httpsvr 

那就改成:

复制代码
otelc go build -o httpsvr 

自动插桩在编译时完成!

3.4 运行被编译时插桩的程序

如果您原来只是简单地执行:

复制代码
./httpsvr

现在还需要指定您的应用的OpenTelemetry服务名(这里假设是my-service),还有如何发送数据到OpenTelemetry Collector或者OpenTelemetry后端(这里假设是http://localhost:4318)。那么需要的命令是:

复制代码
export OTEL_SERVICE_NAME=my-service
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf

./httpsvr

好了,这时候如果访问您的程序,您就可以在OpenTelemetry Collector或者OpenTelemetry后端看到大量metrics和traces了。

3.5 编译时插装还可以使用配置文件进行增强

通过使用编译时插装的配置文件,可以给指定的任意函数加trace。但是目前没有官方提供的通用包,不但要有配置, 还需要自己编写一些代码。 虽然加trace不难, 但是拼接trace和span有难度。我这里就先不写了,详情请参考:Go compile-time instrumentation | OpenTelemetry

4. 比较"编译时无侵入插桩 (otelc)"和"基于 eBPF 的无侵入插桩 (OBI)"

  1. "编译时无侵入插桩 (otelc)"的强项
  • Go 框架的理解
  • 自定义函数插桩(目前还没有通用的代码)
  1. "基于 eBPF 的无侵入插桩 (OBI)"的强项
  • 真正零侵入,简单易行
  • 跨语言
  • 操作系统底层网络连接的感知能力

您可以配合两种插桩方式,为了避免一个调用多个trace,可以禁止一部分"编译时无侵入插桩 (otelc)",在启动引用前可以增加如下的环境变量:

复制代码
export OTEL_GO_DISABLED_INSTRUMENTATIONS=nethttp,grpc

5. 总结

本文介绍了两种非侵入式监控GoLang应用的方法:基于eBPF的绝对无侵入方式(OBI)和编译时无侵入插桩(otelc)。OBI通过下载工具并配置监控端口,无需修改代码即可收集应用指标和追踪数据。编译时插桩则需在构建阶段使用otelc工具,自动为常见框架添加监控功能,运行时通过环境变量配置数据导出。两种方式各有优势:OBI简单跨语言,otelc对Go框架支持更深入且支持自定义函数插桩。文章详细说明了两种方法的配置步骤,并建议可根据需求配合使用,同时提供了相关官方文档链接供进一步参考。

相关推荐
Elastic 中国社区官方博客4 小时前
Elasticsearch:使用 AI Agent 来创建 workflow
大数据·运维·人工智能·elasticsearch·搜索引擎·自动化·全文检索
测试运维日常笔记4 小时前
Linux系统安装配置TigerVNC服务器完整指南
linux·运维·服务器
喜欢的名字被抢了5 小时前
程序出问题怎么查,以及如何让它不掉线
java·运维·数据库
雾时之林5 小时前
Linux----cron定时服务
linux·运维·服务器
壹玖玖肆5 小时前
医院后勤智能运维系统实用性评测
运维
wengqidaifeng6 小时前
1.从“会敲命令”到理解 Linux:15 个基础指令、文件树与命令执行的本质
linux·运维·服务器·ubuntu
xzlAwin6 小时前
Win10安装Go语言多版本管理器g工具
开发语言·golang
tedcloud1236 小时前
book-to-skill 怎么部署?把技术书和文档转换成可复用的 AI Skill
运维·服务器·人工智能·开源·ai编程
xiaoxiangsiyan7 小时前
企业日常运维高频应用服务全解
运维·网络·云原生·容器·dns
AR_xsy7 小时前
docker--资源配额 配置
运维·docker·容器