赞
踩
Ubuntu 20.04 LTS内核版本不满足要求,Beyla要求至少5.8以上
Static hostname: test
Icon name: computer-vm
Chassis: vm
Machine ID: 22349ac6f9ba406293d0541bcba7c05d
Boot ID: 83bb7e5dbf27453c94ff9f1fe88d5f02
Virtualization: vmware
Operating System: Ubuntu 22.04.4 LTS
Kernel: Linux 5.15.0-105-generic
Architecture: x86-64
Hardware Vendor: VMware, Inc.
Hardware Model: VMware Virtual Platform
Grafana Beyla 是一个基于 eBPF(Extended Berkeley Packet Filter)的应用程序自动仪表化工具,旨在轻松实现应用程序的可观测性。它使用 eBPF 自动检查应用程序可执行文件和操作系统网络层,并捕获与 Web 事务相关的跟踪跨度和 Linux HTTP/S 和 gRPC 服务的 Rate Errors Duration (RED) 指标,而无需对应用程序代码或配置进行任何修改.
以下是 Grafana Beyla 的一些特点:
Grafana Beyla 的开发目前处于早期阶段。它是一个基于 eBPF 的应用程序自动仪表化工具,旨在轻松实现应用程序的可观测性。Beyla 使用 eBPF 自动检查应用程序可执行文件和操作系统网络层,并捕获与 Web 事务相关的跟踪跨度和 Linux HTTP/S 和 gRPC 服务的 Rate Errors Duration (RED) 指标,而无需对应用程序代码或配置进行任何修改。
beyla支持通过eBPF,无侵入地自动采集应用程序的trace信息。以下是Beyla对trace的采集实现原理,以golang的net/http为例:
整体原理:
net/http
中的函数:
net/http.serverHandler.ServeHTTP
net/http.(*Transport).roundTrip
ServeHTTP
时:
traceparent
,存入go_trace_map
结构(key=goroutine地址,value=trace信息)。go_trace_map
结构。roundTrip
的调用:
go_trace_map
结构,得到trace信息。ongoing_http_client_requests
结构(key=goroutine地址,value=trace信息)。roundTrip
的调用返回:
ongoing_http_client_requests
结构,得到trace信息。http_request_trace
结构,保存到ringbuf中。监听uprobe/ServeHTTP处理流程:
server_trace_parent()
函数,处理trace信息,存入go_trace_map
结构。ongoing_http_server_requests
结构。监听uprobe/roundTrip处理流程:
traceparent格式:
00-traceId-parentId-type
。9201c25ae90fee19c5bb224e5b1d4941
。0000000000000000
,是用户发起的http调用的span。4228643b4d469989
,即发起www.baidu.com
调用的span。Beyla不仅采集了trace信息,还实现了trace context propagation,使得外部服务可以根据header中的traceparent字段了解trace上下文信息。
检查eBPF支持
如果输出包含CONFIG_BPF=y,则表示eBPF已经启用。
# grep CONFIG_BPF /boot/config-$(uname -r)
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
CONFIG_BPFILTER=y
CONFIG_BPFILTER_UMH=m
CONFIG_BPF_JIT=y
CONFIG_BPF_STREAM_PARSER=y
CONFIG_BPF_EVENTS=y
CONFIG_BPF_KPROBE_OVERRIDE=y
启用未授权的eBPF
允许非特权用户使用eBPF功能
# sysctl kernel.unprivileged_bpf_disabled
kernel.unprivileged_bpf_disabled = 2
# sysctl -w kernel.unprivileged_bpf_disabled=0
安装必要工具
apt install -y bpfcc-tools linux-headers-$(uname -r)
设置go
# 下载go1.22.2.linux-amd64.tar.gz
wget https://go.dev/dl/go1.22.2.linux-amd64.tar.gz
# 设置代理
/root/go/bin/go env -w GO111MODULE=on
/root/go/bin/go env -w GOPROXY=https://goproxy.cn
安装beyla
/root/go/bin/go install github.com/grafana/beyla/cmd/beyla@latest
运行beyla
配置文件方式
cat > config.yml <<EOF
open_port: 443
prometheus_export:
port: 8999
EOF
/root/go/bin/beyla -config config.yml
命令行方式
BEYLA_PROMETHEUS_PORT=8999 BEYLA_OPEN_PORT=443 BEYLA_PRINT_TRACES=true /root/go/bin/beyla
apt-get install -y adduser libfontconfig1 musl
wget https://dl.grafana.com/oss/release/grafana_10.4.2_amd64.deb
dpkg -i grafana_10.4.2_amd64.deb
systemctl start grafana-server
systemctl enable grafana-server
server1
package main import ( "io/ioutil" "log" "net/http" "time" ) func main() { // Define HTTP handler for service1 http.HandleFunc("/service1", func(w http.ResponseWriter, r *http.Request) { // 发送HTTP请求到服务2 req, _ := http.NewRequest("GET", "http://localhost:8082/service2", nil) resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() // Simulate some processing time.Sleep(45 * time.Millisecond) // 读取服务3的响应 body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } // 将服务3的响应写入服务2的响应体 w.Write(body) }) log.Fatal(http.ListenAndServe(":8081", nil)) }
server2
package main import ( "io/ioutil" "log" "net/http" "time" ) func main() { // Define HTTP handler for service2 http.HandleFunc("/service2", func(w http.ResponseWriter, r *http.Request) { // 发送HTTP请求到服务2 req, _ := http.NewRequest("GET", "http://localhost:8083/service3", nil) resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() // Simulate some processing time.Sleep(45 * time.Millisecond) // 读取服务3的响应 body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } // 将服务3的响应写入服务2的响应体 w.Write(body) }) log.Fatal(http.ListenAndServe(":8082", nil)) }
server3
package main import ( "log" "net/http" "time" ) func main() { // Define HTTP handler for service3 http.HandleFunc("/service3", func(w http.ResponseWriter, r *http.Request) { // Simulate some processing time.Sleep(45 * time.Millisecond) // Respond to the request w.Write([]byte("Service 3 response")) }) // Start service log.Fatal(http.ListenAndServe(":8083", nil)) }
启动测试程序
screen -dmS srv1 /root/test/srv1 &
screen -dmS srv2 /root/test/srv2 &
screen -dmS srv3 /root/test/srv3 &
# 监控的应用端口号
export BEYLA_OPEN_PORT=8081
# 控制台输出trace
export BEYLA_PRINT_TRACES=true
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
# export OTEL_EXPORTER_OTLP_ENDPOINT="https://otlp-gateway-prod-eu-west-0.grafana.net/otlp"
# export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic ...your-encoded-credentials..."
/root/go/bin/beyla
从10.1.1.1访问 http://10.1.1.70:8081/service1 查看控制台trace消息
2024-04-29 16:46:38.42944638 (94.102539ms[94.102539ms]) CLNT 200 GET /service2 [127.0.0.1 as srv1]->[127.0.0.1 as localhost:8082] size:0B svc=[srv1 go] traceparent=[00-8e4ad16d45da000a9d7137eeb6f5e937-14c8373e769fb56e-01]
2024-04-29 16:46:38.42944638 (141.977651ms[141.90828ms]) SRV 200 GET /service1 [10.1.1.1 as 10.1.1.1]->[10.1.1.70 as srv1:8081] size:0B svc=[srv1 go] traceparent=[00-8e4ad16d45da000a9d7137eeb6f5e937-0000000000000000-01]
安装
curl -Lo tempo_2.4.1_linux_amd64.deb https://github.com/grafana/tempo/releases/download/v2.4.1/tempo_2.4.1_linux_amd64.deb
echo 2fdd167cbb00d732435123a254469ec4cfde3c525a4ec89d235423a5e9abc4b3 \
tempo_2.4.1_linux_amd64.deb | sha256sum -c
dpkg -i tempo_2.4.1_linux_amd64.deb
配置
cat > /etc/tempo/config.yml <<EOF server: http_listen_port: 3200 distributor: receivers: otlp: protocols: http: grpc: compactor: compaction: block_retention: 48h metrics_generator: registry: external_labels: source: tempo cluster: linux-microservices storage: path: /tmp/tempo/generator/wal remote_write: - url: http://localhost:9090/api/v1/write send_exemplars: true storage: # trace: # backend: s3 # s3: # endpoint: s3.us-east-1.amazonaws.com # bucket: grafana-traces-data # forcepathstyle: true # # set to false if endpoint is https # insecure: true # access_key: # TODO - Add S3 access key # secret_key: # TODO - Add S3 secret key trace: backend: local wal: path: /tmp/tempo/wal local: path: /tmp/tempo/blocks overrides: defaults: metrics_generator: processors: [service-graphs, span-metrics] EOF
在 Grafana Tempo 的数据流程中,数据首先写入 Write-Ahead Log (WAL),然后是 block,最后才是配置的 backend 云存储。这个过程确保了数据的持久性和完整性。下面是这个过程的简要说明:
WAL (Write-Ahead Log):
Block:
Backend 云存储:
这个流程提供了一个高效且可靠的方式来存储和管理大量的跟踪数据。
启动
systemctl start tempo.service
systemctl enable tempo.service
systemctl is-active tempo
wget --no-check-certificate https://github.com/prometheus/prometheus/releases/download/v2.45.4/prometheus-2.45.4.linux-amd64.tar.gz tar -zxf prometheus-2.45.4.linux-amd64.tar.gz mkdir -p /etc/prometheus mkdir -p /export/prometheus/data cp -r prometheus-2.45.4.linux-amd64/* /etc/prometheus/ mv /etc/prometheus/prometheus /usr/local/bin/ mv /etc/prometheus/promtool /usr/local/bin/ # 配置抓取promttheus cat <<EOF >/etc/prometheus/prometheus.yml global: alerting: alertmanagers: - static_configs: - targets: # - alertmanager:9093 rule_files: # - "first_rules.yml" # - "second_rules.yml" scrape_configs: - job_name: "prometheus" static_configs: - targets: ["localhost:9090"] - job_name: "beyla" static_configs: - targets: ["localhost:9101", "localhost:9102", "localhost:9103"] EOF # 启动 # 使用--web.enable-remote-write-receiver启用远程写入接口来接收tempo的service graph数据,地址为/api/v1/write screen -dmS prom prometheus --config.file=/etc/prometheus/prometheus.yml --web.enable-remote-write-receiver --storage.tsdb.path=/export/prometheus/data --web.console.libraries=/etc/prometheus/console_libraries --web.console.templates=/etc/prometheus/consoles --storage.tsdb.retention=7d &
注意OTEL_EXPORTER_OTLP_PROTOCOL值对应的tempo接收端口
beyla环境变量参数配置
以下配置允许beyla主动只发送metrics信息(不配置OTEL_EXPORTER_OTLP_TRACES_ENDPOINT默认不处理trace)到endpoint,例如prometheus pushgateway或者opentelemetry collector,注意地址要完整
export OTEL_EXPORTER_OTLP_METRICS_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT="http://localhost:9099"
另外beyla还可以主动监听来允许任何客户端获取prometheus metrics数据
export BEYLA_PROMETHEUS_PORT="9100"
export BEYLA_PROMETHEUS_PATH="/metrics" # 默认是/metrics,所以此值可不设置,默认即可
beyla的内部metrics reporter
export BEYLA_INTERNAL_METRICS_PROMETHEUS_PORT="9100"
export BEYLA_INTERNAL_METRICS_PROMETHEUS_PATH="/internal/metrics" #默认为/internal/metrics
beyla使用如下配置会默认给发送trace的地址添加/v1/traces,但是会向endpoint发送trace和metrics数据
如果只有tempo的endpoint设置,则会导致beyla报metrics发送错误的消息,因为tempo只接收trace数据
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
指定完整的endpoint,如果只指定这个endpoint则只发送trace数据
export OTEL_EXPORTER_OTLP_TRACES_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://localhost:4318/v1/traces"
启动beyla trace任务,这里使用监听端口等待prometheus抓取metrcis数据,指定只推送trace数据
# trace server1 export BEYLA_OPEN_PORT=8081 export BEYLA_PRINT_TRACES=true export BEYLA_PROMETHEUS_PORT="9101" export OTEL_EXPORTER_OTLP_TRACES_PROTOCOL="http/protobuf" export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://localhost:4318/v1/traces" /root/go/bin/beyla # trace server2 export BEYLA_OPEN_PORT=8082 export BEYLA_PRINT_TRACES=true export BEYLA_PROMETHEUS_PORT="9102" export OTEL_EXPORTER_OTLP_TRACES_PROTOCOL="http/protobuf" export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://localhost:4318/v1/traces" /root/go/bin/beyla # trace server3 export BEYLA_OPEN_PORT=8083 export BEYLA_PRINT_TRACES=true export BEYLA_PROMETHEUS_PORT="9103" export OTEL_EXPORTER_OTLP_TRACES_PROTOCOL="http/protobuf" export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://localhost:4318/v1/traces" /root/go/bin/beyla
curl http://localhost:8081/service1
添加tempo源并启用node graph
prometheus需要使用–web.enable-remote-write-receiver启用远程写入接口来接收tempo的service graph数据,地址为/api/v1/write
prometheus http API
在explorer中搜索service graph
设置hosts
# vim /etc/hosts
127.0.0.1 prometheus
beyla OTEL_EXPORTER_OTLP_PROTOCOL变量有哪些值可选
OTEL_EXPORTER_OTLP_PROTOCOL
是用于配置 OpenTelemetry Protocol (OTLP) Exporter 的环境变量之一,用于指定 OTLP 传输协议,以便发送遥测数据(跟踪、指标或日志)。以下是可选的值:
您可以根据您的需求选择其中一个值,并将其设置为环境变量 OTEL_EXPORTER_OTLP_PROTOCOL
。例如,如果您希望使用 OTLP/gRPC,可以执行以下操作:
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
如果您需要使用 OTLP/HTTP + Protobuf,可以设置如下:
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
请注意,这些值取决于您的 SDK 和实际需求,因此您可以根据您的环境和用例选择适当的协议。
beyla向tempo发送数据显示failed to upload metrics: Post “http://localhost:4317/v1/metrics”: net/http: HTTP/1.x transport connection broken: malformed HTTP response “\x00\x00\x06\x04\x00\x00\x00\x00\x00\x00\x05\x00\x00@\x00”
您遇到的问题看起来是由于 Beyla 在尝试向 Tempo 发送指标数据时,HTTP 连接中断导致的。这个错误信息表明 HTTP 响应格式不正确,这可能是由于多种原因造成的,包括网络问题、配置错误或服务端的问题。
根据我找到的信息,有一个类似的问题被报告在 Beyla 的 GitHub 问题跟踪中。在某些情况下,OpenTelemetry Go 库不接受用于指标的 OTEL_EXPORTER_OTLP_HEADERS
环境变量值(尽管它对追踪数据有效)。作为解决方法,您可以显式设置 OTEL_EXPORTER_OTLP_METRICS_HEADERS
环境变量,使用与 OTEL_EXPORTER_OTLP_HEADERS
相同的值,这样 Beyla 就会向指标端点发送正确的头部信息。
如果您已经确认网络和服务都正常运行,并且问题仍然存在,那么您可能需要检查以下几点:
4317
端口。如何显式设置beyla OTEL_EXPORTER_OTLP_METRICS_HEADERS 环境变量,使用与 OTEL_EXPORTER_OTLP_HEADERS 相同的值
要显式设置 Beyla 的 OTEL_EXPORTER_OTLP_METRICS_HEADERS
环境变量,并使用与 OTEL_EXPORTER_OTLP_HEADERS
相同的值,您可以按照以下步骤操作:
export
命令来设置环境变量。如果您已经有了 OTEL_EXPORTER_OTLP_HEADERS
的值,您可以直接将其赋值给 OTEL_EXPORTER_OTLP_METRICS_HEADERS
。例如:export OTEL_EXPORTER_OTLP_METRICS_HEADERS=$OTEL_EXPORTER_OTLP_HEADERS
这条命令会将 OTEL_EXPORTER_OTLP_HEADERS
环境变量的当前值赋给 OTEL_EXPORTER_OTLP_METRICS_HEADERS
。
echo
命令来检查它们的值:echo $OTEL_EXPORTER_OTLP_METRICS_HEADERS
echo $OTEL_EXPORTER_OTLP_HEADERS
两个命令应该输出相同的值。
请注意,设置环境变量的方法可能会根据您使用的操作系统和 shell 类型略有不同。上述命令适用于大多数 Unix-like 系统,包括 Linux 和 macOS。如果您使用的是 Windows,您可能需要使用 set
命令而不是 export
。
tempo有/v1/metrics路径吗?能接收metric数据吗?
根据 Grafana Tempo 的官方文档,Tempo 服务确实提供了一个 /metrics
端点。这个端点是用于返回运行中的 Tempo 服务的指标数据,格式是 Prometheus 的展示格式。然而,这个 /metrics
端点是为了监控 Tempo 自身的性能指标,而不是用来接收外部的 metrics 数据。
如果你想要将 metrics 数据发送到 Prometheus,你通常需要使用 OpenTelemetry Collector 或者 Grafana Agent,并配置它们的 prometheusremotewrite
导出器来将 metrics 数据发送到 Prometheus 的 remote_write
端点。
例如,以下是一个 OpenTelemetry Collector 配置的示例,展示了如何将 metrics 数据通过 prometheusremotewrite
导出器发送到 Prometheus:
exporters:
prometheusremotewrite:
endpoint: "http://your-prometheus-server/api/v1/push"
在这个配置中,endpoint
就是你的 Prometheus 服务器的 remote_write
端点。你需要将 "http://your-prometheus-server/api/v1/push"
替换为你的 Prometheus 服务器的实际地址。
总结来说,Tempo 的 /v1/metrics
端点不是用来接收 metrics 数据的。如果你需要将 metrics 数据发送到 Prometheus,你应该使用 OpenTelemetry Collector 或 Grafana Agent,并配置相应的 prometheusremotewrite
导出器。
node graph和service graph有什么区别
Node Graph 和 Service Graph 是两种不同的图形表示方法,它们在可视化服务和网络结构时有各自的特点和用途。
总的来说,Node Graph 更多地用于展示网络层面的结构,而 Service Graph 则用于展示服务层面的交互和依赖关系。在实际应用中,这两种图形可以帮助运维人员和开发人员从不同角度理解和监控系统的状态和性能。
详细解释下tempo的metrics_generator:配置
metrics_generator
是 Tempo 中的一个可选组件,它能够从接收到的追踪数据中生成指标。如果启用,metrics_generator
将处理跨度(spans)并使用 Prometheus 的远程写入协议将指标写入到 Prometheus 数据源。以下是 metrics_generator
配置的详细解释:
registry
部分用于配置指标的注册表,包括收集间隔和外部标签。external_labels
用于添加额外的标签到所有由 metrics_generator
生成的指标,这有助于在 Prometheus 中区分不同来源的指标。storage
部分定义了指标数据的存储位置和方式。path
指定了本地存储指标数据的路径。remote_write
配置了一个或多个远程写入端点,metrics_generator
将定期将指标数据发送到这些端点。url
指定了远程写入的目标地址,这应该是一个兼容 Prometheus 的端点。send_exemplars
设置为 true
时,将允许发送 exemplars 数据,这是一种附加在时间序列指标上的追踪数据,有助于更精细地理解指标背后的追踪信息。metrics_generator
可以生成服务图(Service Graphs),这是分布式系统中服务之间关系的表示。metrics_generator
的配置使得 Tempo 能够提供额外的价值,通过从追踪中生成指标来增强可观测性。这些指标随后可以在 Grafana 中进行查询和可视化。
grafana agent和beyla有什么相同点和不同点
Grafana Agent 和 Beyla 都是与监控和可观测性相关的工具,但它们之间有一些区别。让我们来看看它们的相同点和不同点:
相同点:
监控和指标收集:Grafana Agent 和 Beyla 都专注于收集指标和监控数据,以便进行性能分析、故障排除和优化。
eBPF 基础:两者都使用了 eBPF(Extended Berkeley Packet Filter)技术。eBPF 是一种强大的内核扩展,允许在运行时动态注入代码来分析和操作内核和用户空间的数据。
自动仪表化:Beyla 和 Grafana Agent 都支持自动仪表化,无需手动更改应用程序代码或配置。
不同点:
总之,Grafana Agent 和 Beyla 都是有助于实现可观测性的工具,但它们的重点和用途略有不同。选择哪个工具取决于您的具体需求和环境。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。