chore(api-gateway): merge review docs and update dependencies

This commit is contained in:
SpecialX
2026-07-10 16:50:33 +08:00
parent 8e91039896
commit 9e767b4e95
11 changed files with 1246 additions and 152 deletions

View File

@@ -1,73 +1,35 @@
// Package observability also bootstraps OpenTelemetry tracing. The tracer is
// initialized via shared-go/tracer so push-gateway and api-gateway share the
// same SDK configuration.
package observability
import (
"context"
"log"
"net/url"
"time"
"fmt"
"os"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"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.26.0"
"github.com/edu-cloud/shared-go/tracer"
)
// InitTracer 初始化 OpenTelemetry tracer.
//
// endpoint 为 "http://host:port" 格式(如 "http://localhost:4318"
// 为空时跳过初始化tracing disabled
//
// 返回 shutdown 函数,应在服务退出时调用以 flush 待发送 span.
// InitTracer initializes the OTel tracer using shared-go/tracer. When the
// OTLP endpoint is empty (or "localhost:4318") the exporter still runs but
// emits no spans if no collector is listening. Returns a shutdown function
// that must be called on process exit.
func InitTracer(serviceName, endpoint string) func() {
if endpoint == "" {
log.Println("OTEL endpoint not set, tracing disabled")
// shared-go/tracer reads OTEL_EXPORTER_OTLP_ENDPOINT directly; override it
// explicitly so push-gateway's own config value takes precedence.
if endpoint != "" {
_ = os.Setenv("OTEL_EXPORTER_OTLP_ENDPOINT", endpoint)
}
if err := tracer.Init(serviceName); err != nil {
// Tracing is best-effort: log and continue without a tracer rather than
// failing the whole process.
fmt.Fprintf(os.Stderr, "push-gateway: tracer init failed: %v (tracing disabled)\n", err)
return func() {}
}
u, err := url.Parse(endpoint)
if err != nil || u.Host == "" {
log.Printf("invalid OTEL endpoint %q, tracing disabled", endpoint)
return func() {}
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
exporter, err := otlptracehttp.New(ctx,
otlptracehttp.WithEndpoint(u.Host),
otlptracehttp.WithInsecure(),
)
if err != nil {
log.Printf("failed to create OTLP exporter: %v, tracing disabled", err)
return func() {}
}
res, err := resource.New(ctx,
resource.WithAttributes(semconv.ServiceName(serviceName)),
)
if err != nil {
log.Printf("failed to create resource: %v", err)
return func() {}
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(res),
)
otel.SetTracerProvider(tp)
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
propagation.TraceContext{},
propagation.Baggage{},
))
log.Printf("OpenTelemetry tracer initialized for %s (endpoint=%s)", serviceName, u.Host)
return func() {
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := tp.Shutdown(shutdownCtx); err != nil {
log.Printf("failed to shutdown tracer: %v", err)
if err := tracer.Shutdown(context.Background()); err != nil {
fmt.Fprintf(os.Stderr, "push-gateway: tracer shutdown failed: %v\n", err)
}
}
}