mirror of
https://gitee.com/johng/gf.git
synced 2024-12-12 12:45:08 +08:00
103 lines
3.0 KiB
Go
103 lines
3.0 KiB
Go
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
|
//
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
// If a copy of the MIT was not distributed with this file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
// Package otlpgrpc provides gtrace.Tracer implementation using OpenTelemetry protocol.
|
|
package otlpgrpc
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"go.opentelemetry.io/otel"
|
|
"go.opentelemetry.io/otel/attribute"
|
|
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
|
|
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
|
|
"go.opentelemetry.io/otel/propagation"
|
|
"go.opentelemetry.io/otel/sdk/resource"
|
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
|
semconv "go.opentelemetry.io/otel/semconv/v1.20.0"
|
|
"google.golang.org/grpc"
|
|
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
"github.com/gogf/gf/v2/net/gipv4"
|
|
)
|
|
|
|
const (
|
|
tracerHostnameTagKey = "hostname"
|
|
)
|
|
|
|
// Init initializes and registers `otlpgrpc` to global TracerProvider.
|
|
//
|
|
// The output parameter `Shutdown` is used for waiting exported trace spans to be uploaded,
|
|
// which is useful if your program is ending, and you do not want to lose recent spans.
|
|
func Init(serviceName, endpoint, traceToken string) (func(), error) {
|
|
// Try retrieving host ip for tracing info.
|
|
var (
|
|
intranetIPArray, err = gipv4.GetIntranetIpArray()
|
|
hostIP = "NoHostIpFound"
|
|
)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(intranetIPArray) == 0 {
|
|
if intranetIPArray, err = gipv4.GetIpArray(); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
if len(intranetIPArray) > 0 {
|
|
hostIP = intranetIPArray[0]
|
|
}
|
|
|
|
traceClient := otlptracegrpc.NewClient(
|
|
otlptracegrpc.WithInsecure(),
|
|
otlptracegrpc.WithEndpoint(endpoint), // Replace the otel Agent Addr with the access point obtained in the prerequisite。
|
|
otlptracegrpc.WithHeaders(map[string]string{"Authentication": traceToken}),
|
|
otlptracegrpc.WithDialOption(grpc.WithBlock()))
|
|
ctx := context.Background()
|
|
traceExp, err := otlptrace.New(ctx, traceClient)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res, err := resource.New(ctx,
|
|
resource.WithFromEnv(),
|
|
resource.WithProcess(),
|
|
resource.WithTelemetrySDK(),
|
|
resource.WithHost(),
|
|
resource.WithAttributes(
|
|
// The name of the service displayed on the traceback end。
|
|
semconv.ServiceNameKey.String(serviceName),
|
|
semconv.HostNameKey.String(hostIP),
|
|
attribute.String(tracerHostnameTagKey, hostIP),
|
|
),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
bsp := sdktrace.NewBatchSpanProcessor(traceExp)
|
|
tracerProvider := sdktrace.NewTracerProvider(
|
|
sdktrace.WithSampler(sdktrace.AlwaysSample()),
|
|
sdktrace.WithResource(res),
|
|
sdktrace.WithSpanProcessor(bsp),
|
|
)
|
|
|
|
// Set the global propagator to traceContext (not set by default).
|
|
otel.SetTextMapPropagator(propagation.TraceContext{})
|
|
otel.SetTracerProvider(tracerProvider)
|
|
|
|
return func() {
|
|
ctx, cancel := context.WithTimeout(ctx, time.Second)
|
|
defer cancel()
|
|
if err = traceExp.Shutdown(ctx); err != nil {
|
|
g.Log().Errorf(ctx, "Shutdown traceExp failed err:%+v", err)
|
|
otel.Handle(err)
|
|
}
|
|
g.Log().Debug(ctx, "Shutdown traceExp success")
|
|
}, nil
|
|
}
|