You need to enable JavaScript to run this app.
文档中心
日志服务

日志服务

复制全文
下载 pdf
Trace 存储
通过 OpenTelemetry SDK 写入数据
复制全文
下载 pdf
通过 OpenTelemetry SDK 写入数据
日志服务支持通过 OpenTelemetry SDK 直接写入 Trace 数据到日志服务。本文档以 Go SDK 为例,演示 Golang 应用接入 Trace 存储的操作步骤,适用于业务系统首次使用全链路追踪服务的场景。​
前提条件​
  • 已配置 Golang 开发环境,请参考 Go 官网下载和安装 Go 编译运行环境。​
  • Go 版本为 1.19 及后续版本,您可以执行 go version 检查当前 Go 的版本信息。​
背景信息​
在微服务、分布式等涉及多个服务交互的架构或系统中,可以使用全链路追踪服务进行服务调用链路分析或架构性能监控。日志服务通过 Trace 存储提供基于 OpenTelemetry 标准协议的分布式链路追踪能力,您可以参考本文档,在业务系统中部署 Trace 存储,在数据源上启用 Trace 事件,采集并发送日志数据到火山引擎日志服务中。​
操作步骤​
1 创建 Trace 实例​
在日志服务控制台中创建一个 Trace 实例,用于配合业务系统采集并发送、管理 Trace 数据。日志服务会同步创建一个日志主题用于存储 Trace 数据。详细操作步骤请参考创建 Trace 实例。​
2 添加相关依赖​
在本地 Go 项目中执行以下命令添加对应依赖。​
​
# 添加otel协议依赖​
go get go.opentelemetry.io/otel​
go get go.opentelemetry.io/otel/trace​
go get go.opentelemetry.io/otel/bridge/opentracing​
​
# 添加otel exporter的依赖(用户需要通过exporter向日志服务发送trace数据)​
go get go.opentelemetry.io/otel/exporters/otlp/otlptrace​
​
# 添加http exporter依赖(如果配置的是日志服务的http端口,需要添加这个依赖)​
go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp​
​
# 添加grpc exporter依赖(如果配置的是日志服务的grpc端口,需要添加这个依赖)​
go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc​
​
3 初始化 Provider​
添加依赖后,您需要通过执行代码完成 OpenTelemetry Provider 的初始化。您需要指定要使用的数据传输协议,以便 OpenTelemetry 将数据从您的应用程序传输到 Trace 实例。在 Tracer 类的构造函数中,可以使用协议参数来指定该协议。​
初始化时应配置日志服务接入点和鉴权相关参数,详细信息请参考参数说明。日志服务支持通过以下方式配置鉴权信息:​
  • 在 gRPC协议、HTTPS 协议的请求头(Header)中配置。​
  • 在 OpenTelemetry 协议的 Resource 字段中配置鉴权信息。​
HTTP 协议初始化示例​
通过 HTTP 协议方式接入 Trace 存储时,可参考以下示例代码完成 OpenTelemetry Provider 的初始化。日志服务提供两种鉴权参数的配置方式,您可以按需选择对应的示例代码进行接入。详细参数信息请参考参数说明。​
  • (推荐)在 HTTPS 协议的请求头(Header)中配置鉴权参数:​
  • ​
    import (​
    "context"​
    ​
    "go.opentelemetry.io/otel/attribute"​
    "go.opentelemetry.io/otel/exporters/otlp/otlptrace"​
    "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"​
    "go.opentelemetry.io/otel/sdk/resource"​
    "go.opentelemetry.io/otel/sdk/trace"​
    semconv "go.opentelemetry.io/otel/semconv/v1.10.0"​
    )​
    ​
    // 初始化endpoint为日志服务http open telemetry协议端口并且在http请求的hader中添加鉴权信息的TracerProvider​
    func InitTlsOtelTracerWithHttpHeader(endPoint string, topicId string, ak string, sk string, region string) *trace.TracerProvider {​
    // 在http header中添加TLS需要的鉴权字段​
    opts := []otlptracehttp.Option{otlptracehttp.WithEndpoint(endPoint + ":4318"), // endpoint参考【参数配置】​
    otlptracehttp.WithHeaders(map[string]string{"x-tls-otel-tracetopic": topicId, "x-tls-otel-ak": ak, "x-tls-otel-sk": sk, "x-tls-otel-region": region})}​
    exporter, _ := otlptrace.New(​
    context.Background(),​
    otlptracehttp.NewClient(opts...),​
    )​
    ​
    tp := trace.NewTracerProvider(​
    trace.WithBatcher(exporter),​
    trace.WithResource(resource.NewWithAttributes(​
    semconv.SchemaURL,​
    semconv.ServiceNameKey.String("your_service_name"),​
    )),​
    )​
    return tp​
    }​
    ​
  • 通过 OpenTelemetry 协议的 Resource 参数配置鉴权参数:​
  • ​
    import (​
    "context"​
    ​
    "go.opentelemetry.io/otel/attribute"​
    "go.opentelemetry.io/otel/exporters/otlp/otlptrace"​
    "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"​
    "go.opentelemetry.io/otel/sdk/resource"​
    "go.opentelemetry.io/otel/sdk/trace"​
    semconv "go.opentelemetry.io/otel/semconv/v1.10.0"​
    )​
    ​
    // 初始化endpoint为日志服务http open telemetry协议端口并且在trace数据的body中添加鉴权信息的TracerProvider​
    func InitTlsOtelTracerWithHttpResource(endPoint string, topicId string, ak string, sk string, region string) *trace.TracerProvider {​
    traceTopicKey := attribute.Key("tls.otel.tracetopic")​
    akKey := attribute.Key("tls.otel.ak")​
    skKey := attribute.Key("tls.otel.sk")​
    regionKey := attribute.Key("tls.otel.region")​
    ​
    opts := []otlptracehttp.Option{otlptracehttp.WithEndpoint(endPoint + ":4318")} // endpoint为http 【参数配置】​
    exporter, _ := otlptrace.New(​
    context.Background(),​
    otlptracehttp.NewClient(opts...),​
    )​
    ​
    tp := trace.NewTracerProvider(​
    trace.WithBatcher(exporter),​
    trace.WithResource(resource.NewWithAttributes(​
    semconv.SchemaURL,​
    semconv.ServiceNameKey.String("your_service_name"),​
    // 在otel请求body中添加TLS需要的鉴权字段​
    traceTopicKey.String(topicId),​
    akKey.String(ak),​
    skKey.String(sk),​
    regionKey.String(region),​
    )),​
    )​
    return tp​
    }​
    ​
gRPC 协议初始化示例​
通过 gRPC 协议方式接入 Trace 存储时,可参考以下示例代码完成 OpenTelemetry Provider 的初始化。日志服务提供两种鉴权参数的配置方式,您可以按需选择对应的示例代码进行接入。详细参数信息请参考参数说明。​
  • (推荐)在 gRPC 协议的请求头(Header)中配置鉴权参数:​
  • ​
    import (​
    "context"​
    ​
    "go.opentelemetry.io/otel/attribute"​
    "go.opentelemetry.io/otel/exporters/otlp/otlptrace"​
    "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"​
    "go.opentelemetry.io/otel/sdk/resource"​
    "go.opentelemetry.io/otel/sdk/trace"​
    semconv "go.opentelemetry.io/otel/semconv/v1.10.0"​
    "google.golang.org/grpc/credentials/insecure"​
    )​
    ​
    // 初始化endpoint为日志服务grpc open telemetry协议端口并且在grpc请求的hader中添加鉴权信息的TracerProvider​
    func InitTlsOtelTracerWithGrpcHeader(endPoint string, topicId string, ak string, sk string, region string) *trace.TracerProvider {​
    // 在grpc header中添加TLS需要的鉴权字段​
    exporter, _ := otlptrace.New(​
    context.Background(),​
    // otlptracegrpc.WithTLSCredentials(insecure.NewCredentials()) 配置tls方式访问​
    otlptracegrpc.NewClient(otlptracegrpc.WithTLSCredentials(insecure.NewCredentials()), otlptracegrpc.WithEndpoint(endPoint+":4317"), // endpoint为grpc 【参数配置】​
    otlptracegrpc.WithHeaders(map[string]string{"x-tls-otel-tracetopic": topicId, "x-tls-otel-ak": ak, "x-tls-otel-sk": sk, "x-tls-otel-region": region})),​
    )​
    tp := trace.NewTracerProvider(​
    trace.WithBatcher(exporter),​
    trace.WithResource(resource.NewWithAttributes(​
    semconv.SchemaURL,​
    semconv.ServiceNameKey.String("your_service_name"),​
    )),​
    )​
    return tp​
    }​
    ​
  • 通过 OpenTelemetry 协议的 Resource 参数配置鉴权参数:​
  • ​
    import (​
    "context"​
    ​
    "go.opentelemetry.io/otel/attribute"​
    "go.opentelemetry.io/otel/exporters/otlp/otlptrace"​
    "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"​
    "go.opentelemetry.io/otel/sdk/resource"​
    "go.opentelemetry.io/otel/sdk/trace"​
    semconv "go.opentelemetry.io/otel/semconv/v1.10.0"​
    "google.golang.org/grpc/credentials/insecure"​
    )​
    ​
    // 初始化endpoint为日志服务grpc open telemetry协议端口并且在trace数据的body中添加鉴权信息的TracerProvider​
    func InitTlsOtelTracerWithGrpcResource(endPoint string, topicId string, ak string, sk string, region string) *trace.TracerProvider {​
    exporter, _ := otlptrace.New(​
    context.Background(), otlptracegrpc.NewClient(otlptracegrpc.WithTLSCredentials(insecure.NewCredentials()), otlptracegrpc.WithEndpoint(endPoint+":4317")), // endpoint为grpc 【参数配置】​
    )​
    traceTopicKey := attribute.Key("tls.otel.tracetopic")​
    akKey := attribute.Key("tls.otel.ak")​
    skKey := attribute.Key("tls.otel.sk")​
    regionKey := attribute.Key("tls.otel.region")​
    tp := trace.NewTracerProvider(​
    trace.WithBatcher(exporter),​
    trace.WithResource(resource.NewWithAttributes(​
    semconv.SchemaURL,​
    semconv.ServiceNameKey.String("your_service_name"),​
    // 在otel请求body中添加TLS需要的鉴权字段​
    traceTopicKey.String(topicId),​
    akKey.String(ak),​
    skKey.String(sk),​
    regionKey.String(region),​
    )),​
    )​
    return tp​
    }​
    ​
参数说明​
初始化 Provider 时,需要在初始化代码中配置接入点和鉴权相关的参数,参数说明如下。​
  • 接入点相关参数​
  • endpoint 为日志服务的接入点信息,由服务地址和端口号组成,不同协议类型的端口号不同。接入点格式为 ${tls_endpoint}:端口号,其中 ${tls_endpoint} 为日志服务的服务地址,获取方式请参考服务地址。​
  • HTTPS 协议的接入点为 ${tls_endpoint}:4318。例如 https://tls-cn-beijing.ivolces.com:4318。​
  • gRPC 协议的接入点为 ${tls_endpoint}:4317,例如 https://tls-cn-beijing.ivolces.com:4317。​
  • 为保证信息传输的安全性,使用 gRPC 协议时必须开启 TLS。​
  • 鉴权相关参数: 您可以在初始化时通过两种方式配置鉴权信息,即在 gRPC 协议、HTTPS 协议的 Header 中或 OpenTelemetry 协议的 Resource 字段中配置。不同配置方式的参数说明如下。​
  • ​
    Header key​
    Resource key​
    示例​
    说明​
    x-tls-otel-tracetopic​
    tls.otel.tracetopic​
    39f0bce1-e37e-4dc5-ab06-801d310b****​
    用于存储 Trace 数据的日志主题 ID。​
    创建 Trace 实例后,日志服务会自动创建日志主题,详细说明请参考相关资源。​
    x-tls-otel-ak​
    tls.otel.ak​
    AKKTNTA1OTlmOWQ1NTM5DNk5OI****​
    火山引擎主账号或子账号的 Access Key ID。 在火山引擎控制台密钥列表页面,根据页面提示查看并复制 Access Key ID。​
    x-tls-otel-sk​
    tls.otel.sk​
    T0RPLS5EUTFZV1JrTmpAKE5EaGCVRG****​
    火山引擎主账号或子账号的 Secret Access Key。 在火山引擎控制台密钥列表页面,根据页面提示查看并复制 Secret Access Key。​
    x-tls-otel-region​
    tls.otel.region​
    cn-beijing​
    Trace 实例所在的地域 ID(Region)。您可以在服务地址中查看指定地域的 ID。​
    x-tls-otel-token​
    tls.otel.token​
    STSeyJBY2NvdW50SW******​
    STS 鉴权 Token,用于鉴权。详细说明请参考4 调用 AssumeRole 获取临时安全令牌。​
    ​
4 使用 tlsOtelTracer 发送 Trace 数据​
参考以下示例代码,通过 tlsOtelTracer 发送 Trace 数据到火山引擎日志服务。详细说明请参考 OpenTelemetry 官方文档。​
Tip​
  • 在使用 OpenTelemetry 收集和发送 Trace 数据时,请确保数据的准确性和完整性。为了保证数据的可靠性,建议您在应用程序中对数据进行验证和错误处理。​
  • 您也可以启用 Trace 事件,在数据源上使用 OpenTelemetry 的 Config 类设置相应的事件处理程序,自动发送 Trace 数据到日志服务。详细说明请参考 OpenTelemetry 官方文档。​
​
package main​
​
import (​
"context"​
"fmt"​
"math/rand"​
"strconv"​
"time"​
​
"github.com/google/uuid"​
"github.com/opentracing/opentracing-go"​
"github.com/opentracing/opentracing-go/ext"​
"go.opentelemetry.io/otel/attribute"​
otbridge "go.opentelemetry.io/otel/bridge/opentracing"​
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"​
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"​
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"​
"go.opentelemetry.io/otel/sdk/resource"​
"go.opentelemetry.io/otel/sdk/trace"​
semconv "go.opentelemetry.io/otel/semconv/v1.10.0"​
"google.golang.org/grpc/credentials/insecure"​
)​
​
func main() {​
SendTrace(1000)​
time.Sleep(time.Minute)​
}​
​
func SendTrace(traceCnt int) {​
endPoint := "tls-cn-beijing.volces.com" // 别的region请更换相关域名,私网请使用私网域名​
topicId := "${topicId}"​
ak := "${AK}"​
sk := "${SK}"​
region := "cn-shanghai" // 别的region请更换相关region​
// 选择不同的方式初始化trace provider​
httpHeaderProvider := InitTlsOtelTracerWithHttpHeader(endPoint, topicId, ak, sk, region)​
// httpResourceProvider := InitTlsOtelTracerWithHttpResource(endPoint, topicId, ak, sk, region)​
// grpcHeaderProvider := InitTlsOtelTracerWithGrpcHeader(endPoint, topicId, ak, sk, region)​
// grpcResourceProvider := InitTlsOtelTracerWithGrpcResource(endPoint, topicId, ak, sk, region)​
​
tracer, _ := otbridge.NewTracerPair(httpHeaderProvider.Tracer("my_trace"))​
ctx := context.TODO()​
for i := 0; i < traceCnt; i++ {​
sendTrace(ctx, tracer)​
}​
}​
​
func sendTrace(ctx context.Context, tracer *otbridge.BridgeTracer) {​
var OperationName []string​
OperationName = append(OperationName, "Operation_1", "Operation_2", "Operation_3", "Operation_4", "Operation_5")​
i := 0​
var last_span opentracing.Span​
var span opentracing.Span​
for {​
uid, _ := uuid.NewUUID()​
index := strconv.Itoa(i)​
if i == 0 {​
span = spanInit(true, ctx, "test.span."+index, tracer, nil)​
} else {​
span = spanInit(false, ctx, "test.span"+index, tracer, last_span.Context())​
}​
ext.SpanKindRPCClient.Set(span)​
ext.PeerService.Set(span, "tls-test-service")​
// // // #nosec​
span.LogKV(​
"event", "soft error",​
"type", "cache timeout",​
"waited.millis", 1500)​
span.SetTag("uuid", uid.String())​
span.SetTag("host", "")​
span.SetBaggageItem("BaggageItem", "TLS test")​
span.SetOperationName(OperationName[rand.Intn(4)])​
span.FinishWithOptions(opentracing.FinishOptions{FinishTime: time.Now()})​
last_span = span​
fmt.Println("successful", i)​
i++​
if i > 100 {​
break​
}​
}​
}​
​
func spanInit(isRoot bool, context context.Context, span_name string, otTracer *otbridge.BridgeTracer, childOfSpanContext opentracing.SpanContext) opentracing.Span {​
var span opentracing.Span​
if isRoot {​
span, _ = opentracing.StartSpanFromContext(context, span_name+".root.span")​
} else {​
span = otTracer.StartSpan("TLS test", opentracing.ChildOf(childOfSpanContext))​
}​
return span​
}​
​
// 初始化endpoint为日志服务http open telemetry协议端口并且在http请求的hader中添加鉴权信息的TracerProvider​
func InitTlsOtelTracerWithHttpHeader(endPoint string, topicId string, ak string, sk string, region string) *trace.TracerProvider {​
// 在http header中添加TLS需要的鉴权字段​
opts := []otlptracehttp.Option{otlptracehttp.WithEndpoint(endPoint + ":4318"), // endpoint参考【参数配置】​
otlptracehttp.WithHeaders(map[string]string{"x-tls-otel-tracetopic": topicId, "x-tls-otel-ak": ak, "x-tls-otel-sk": sk, "x-tls-otel-region": region})}​
exporter, _ := otlptrace.New(​
context.Background(),​
otlptracehttp.NewClient(opts...),​
)​
​
tp := trace.NewTracerProvider(​
trace.WithBatcher(exporter),​
trace.WithResource(resource.NewWithAttributes(​
semconv.SchemaURL,​
semconv.ServiceNameKey.String("your_service_name"),​
)),​
)​
return tp​
}​
​
// 初始化endpoint为日志服务http open telemetry协议端口并且在trace数据的body中添加鉴权信息的TracerProvider​
func InitTlsOtelTracerWithHttpResource(endPoint string, topicId string, ak string, sk string, region string) *trace.TracerProvider {​
traceTopicKey := attribute.Key("tls.otel.tracetopic")​
akKey := attribute.Key("tls.otel.ak")​
skKey := attribute.Key("tls.otel.sk")​
regionKey := attribute.Key("tls.otel.region")​
​
opts := []otlptracehttp.Option{otlptracehttp.WithEndpoint(endPoint + ":4318")} // endpoint为http 【参数配置】​
exporter, _ := otlptrace.New(​
context.Background(),​
otlptracehttp.NewClient(opts...),​
)​
​
tp := trace.NewTracerProvider(​
trace.WithBatcher(exporter),​
trace.WithResource(resource.NewWithAttributes(​
semconv.SchemaURL,​
semconv.ServiceNameKey.String("your_service_name"),​
// 在otel请求body中添加TLS需要的鉴权字段​
traceTopicKey.String(topicId),​
akKey.String(ak),​
skKey.String(sk),​
regionKey.String(region),​
)),​
)​
return tp​
}​
​
// 初始化endpoint为日志服务grpc open telemetry协议端口并且在grpc请求的hader中添加鉴权信息的TracerProvider​
func InitTlsOtelTracerWithGrpcHeader(endPoint string, topicId string, ak string, sk string, region string) *trace.TracerProvider {​
// 在grpc header中添加TLS需要的鉴权字段​
exporter, _ := otlptrace.New(​
context.Background(),​
// otlptracegrpc.WithTLSCredentials(insecure.NewCredentials()) 配置tls方式访问​
otlptracegrpc.NewClient(otlptracegrpc.WithTLSCredentials(insecure.NewCredentials()), otlptracegrpc.WithEndpoint(endPoint+":4317"), // endpoint为grpc 【参数配置】​
otlptracegrpc.WithHeaders(map[string]string{"x-tls-otel-tracetopic": topicId, "x-tls-otel-ak": ak, "x-tls-otel-sk": sk, "x-tls-otel-region": region})),​
)​
tp := trace.NewTracerProvider(​
trace.WithBatcher(exporter),​
trace.WithResource(resource.NewWithAttributes(​
semconv.SchemaURL,​
semconv.ServiceNameKey.String("your_service_name"),​
)),​
)​
return tp​
}​
​
// 初始化endpoint为日志服务grpc open telemetry协议端口并且在trace数据的body中添加鉴权信息的TracerProvider​
func InitTlsOtelTracerWithGrpcResource(endPoint string, topicId string, ak string, sk string, region string) *trace.TracerProvider {​
exporter, _ := otlptrace.New(​
context.Background(), otlptracegrpc.NewClient(otlptracegrpc.WithTLSCredentials(insecure.NewCredentials()), otlptracegrpc.WithEndpoint(endPoint+":4317")), // endpoint为grpc 【参数配置】​
)​
traceTopicKey := attribute.Key("tls.otel.tracetopic")​
akKey := attribute.Key("tls.otel.ak")​
skKey := attribute.Key("tls.otel.sk")​
regionKey := attribute.Key("tls.otel.region")​
tp := trace.NewTracerProvider(​
trace.WithBatcher(exporter),​
trace.WithResource(resource.NewWithAttributes(​
semconv.SchemaURL,​
semconv.ServiceNameKey.String("your_service_name"),​
// 在otel请求body中添加TLS需要的鉴权字段​
traceTopicKey.String(topicId),​
akKey.String(ak),​
skKey.String(sk),​
regionKey.String(region),​
)),​
)​
return tp​
}​
​
验证接入结果​
成功接入 Trace 数据后,您可以通过日志服务的检索分析功能,在线查看采集到的 Trace 数据。如果 Trace 实例对应的日志主题中可检索到您上传的 Trace 数据,表示接入成功。检索 Trace 数据的方式,请参考单主题检索日志。​
例如,您可以通过以下 SQL 语法检索指定 TraceID 对应的 Trace 数据详情。​
​
* | select * where TraceID = '877247fa95024d2f3a1234216010****'​
​
​
最近更新时间:2026.08.20 10:34:02
这个页面对您有帮助吗?
有用
有用
无用
无用