telemetrymgr

package
v0.0.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 26, 2026 License: BSD-2-Clause Imports: 17 Imported by: 0

README

telemetrymgr

可观测性管理模块,提供统一的 Traces、Metrics、Logs 三大信号管理能力。

特性

  • 统一接口 - 提供 ITelemetryManager 接口,统一管理可观测性组件
  • 多驱动支持 - 支持 none(空实现)和 otel(OpenTelemetry)两种驱动
  • 生命周期管理 - 集成 OnStart/OnStop/Shutdown 生命周期钩子,支持优雅关闭
  • 灵活配置 - 支持从配置提供者或直接配置创建管理器实例
  • 完整可观测性 - 支持链路追踪、指标收集和结构化日志
  • OpenTelemetry 集成 - 原生支持 OpenTelemetry 协议,可连接到 OTLP 兼容的收集器

快速开始

使用 none 驱动(空实现)
import (
    "context"
    "github.com/lite-lake/litecore-go/manager/telemetrymgr"
)

func main() {
    mgr, err := telemetrymgr.Build("none", nil)
    if err != nil {
        log.Fatal(err)
    }
    defer mgr.Shutdown(context.Background())

    tracer := mgr.Tracer("my-service")
    ctx, span := tracer.Start(context.Background(), "operation")
    defer span.End()
}
使用 OpenTelemetry 驱动
import (
    "go.opentelemetry.io/otel/attribute"
    "github.com/lite-lake/litecore-go/manager/telemetrymgr"
)

func main() {
    mgr, err := telemetrymgr.Build("otel", map[string]any{
        "endpoint": "localhost:4317",
        "insecure": true,
        "headers": map[string]any{
            "authorization": "Bearer token",
        },
        "traces": map[string]any{
            "enabled": true,
        },
    })
    if err != nil {
        log.Fatal(err)
    }
    defer mgr.Shutdown(context.Background())

    tracer := mgr.Tracer("my-service")
    ctx, span := tracer.Start(context.Background(), "operation")
    defer span.End()
    span.SetAttributes(attribute.String("user.id", "123"))
}
从配置提供者创建
mgr, err := telemetrymgr.BuildWithConfigProvider(configProvider)
if err != nil {
    log.Fatal(err)
}
defer mgr.Shutdown(context.Background())

配置路径:

  • telemetry.driver: 驱动类型("otel" 或 "none")
  • telemetry.otel_config: OTel 配置对象
配置示例

config.yaml 中配置 telemetry:

telemetry:
  driver: "otel"
  otel_config:
    endpoint: "localhost:4317"
    insecure: false
    headers:
      Authorization: "Bearer your-token"
    resource_attributes:
      - key: "service.name"
        value: "my-service"
      - key: "service.version"
        value: "1.0.0"
    traces:
      enabled: true
    metrics:
      enabled: false
    logs:
      enabled: false

支持的遥测驱动

none 驱动

空实现,不产生任何可观测性数据。适用于开发测试环境或不需要遥测的场景。所有方法都返回 no-op 实现,调用开销极小。

特点:

  • 零开销
  • 无网络连接
  • 适用于本地开发或测试环境
otel 驱动

完整的 OpenTelemetry 实现,支持连接到 OTLP 兼容的收集器(如 Jaeger、Tempo、Prometheus 等)。

支持的信号:

  • Traces - 链路追踪(完整支持)
  • Metrics - 指标收集(预留接口,当前使用 noop provider)
  • Logs - 结构化日志(预留接口,当前使用 noop provider)

特点:

  • 连接到 OTLP 收集器(gRPC 协议)
  • 支持资源属性自定义
  • 支持请求头认证
  • 支持 TLS/非 TLS 连接
  • 三大信号独立启用/禁用
  • 批处理导出,减少网络开销

OpenTelemetry 集成

OTLP 端点配置

otel 驱动通过 OTLP(OpenTelemetry Protocol)将数据发送到收集器。默认端点为 localhost:4317(gRPC 协议)。

常用收集器端点:

收集器 端点
Jaeger localhost:4317
Grafana Tempo localhost:4317
Grafana Agent localhost:4317
OpenTelemetry Collector localhost:4317
资源属性

资源属性用于标识产生遥测数据的服务。建议配置以下属性:

config := map[string]any{
    "resource_attributes": []telemetrymgr.ResourceAttribute{
        {Key: "service.name", Value: "my-service"},
        {Key: "service.version", Value: "1.0.0"},
        {Key: "deployment.environment", Value: "production"},
        {Key: "host.name", Value: "server-01"},
    },
}

语义约定(推荐):

  • service.name - 服务名称(必填)
  • service.version - 服务版本
  • deployment.environment - 部署环境(development/staging/production)
  • host.name - 主机名
请求头认证

如果 OTLP 端点需要认证,可以通过 headers 配置:

config := map[string]any{
    "headers": map[string]any{
        "Authorization": "Bearer my-api-key",
        "X-Custom-Header": "custom-value",
    },
}
TLS/非 TLS 连接

默认使用 TLS 安全连接。对于开发环境或内网部署,可以禁用 TLS:

config := map[string]any{
    "endpoint": "localhost:4317",
    "insecure": true,  // 禁用 TLS,使用非安全连接
}

注意: 生产环境建议使用 TLS 加密连接。

独立启用/禁用信号

三大信号可以独立启用或禁用:

config := map[string]any{
    "traces": map[string]any{
        "enabled": true,   // 启用链路追踪
    },
    "metrics": map[string]any{
        "enabled": false,  // 禁用指标收集
    },
    "logs": map[string]any{
        "enabled": false,  // 禁用日志观测
    },
}

配置说明

OTel 驱动配置
字段 类型 默认值 说明
endpoint string localhost:4317 OTLP 端点地址(gRPC 协议)
insecure bool false 是否使用不安全连接(非 TLS)
headers map[string]string nil 请求头(用于认证)
resource_attributes []ResourceAttribute nil 资源属性
traces.enabled bool false 是否启用链路追踪
metrics.enabled bool false 是否启用指标收集
logs.enabled bool false 是否启用结构化日志
资源属性配置
resourceAttributes := []telemetrymgr.ResourceAttribute{
    {Key: "service.name", Value: "my-service"},
    {Key: "service.version", Value: "1.0.0"},
    {Key: "deployment.environment", Value: "production"},
}
配置验证

BuildBuildWithConfigProvider 会自动验证配置。如果配置无效,会返回错误。

验证规则:

  • driver 必须是 "otel" 或 "none"
  • driver 为 "otel" 时,必须提供 otel_config
  • otel_config.endpoint 不能为空

API 说明

创建管理器
Build() - 从直接配置创建
func Build(driverType string, driverConfig map[string]any) (ITelemetryManager, error)

参数:

  • driverType: 驱动类型("otel" 或 "none")
  • driverConfig: 驱动配置(根据驱动类型不同而不同)

返回:

  • ITelemetryManager: 遥测管理器接口实例
  • error: 创建失败的错误
BuildWithConfigProvider() - 从配置提供者创建
func BuildWithConfigProvider(configProvider configmgr.IConfigManager) (ITelemetryManager, error)

参数:

  • configProvider: 配置管理器接口实例

配置路径:

  • telemetry.driver: 驱动类型
  • telemetry.otel_config: OTel 配置(当 driver=otel 时)
Tracer - 链路追踪
tracer := mgr.Tracer("my-service")
ctx, span := tracer.Start(ctx, "operation-name")
defer span.End()

// 设置属性
span.SetAttributes(
    attribute.String("user.id", "123"),
    attribute.Int("retry.count", 3),
)

// 添加事件
span.AddEvent("cache.miss", attribute.String("key", "user:123"))

// 设置状态
span.SetStatus(codes.Error, "operation failed")
Meter - 指标收集
meter := mgr.Meter("my-service")

// Counter 计数器
counter, _ := meter.Float64Counter("requests_total")
counter.Add(ctx, 1, attribute.String("path", "/api/users"))

// Histogram 直方图
histogram, _ := meter.Float64Histogram("request_duration")
histogram.Record(ctx, 123.45, attribute.String("status", "success"))

// UpUpDownCounter 可上下计数
upDownCounter, _ := meter.Int64UpDownCounter("active_connections")
upDownCounter.Add(ctx, 1, attribute.String("type", "websocket"))

注意: 当前 Metrics 使用 noop provider,不会发送数据到 OTLP 端点。此功能为预留接口。

Logger - 结构化日志
logger := mgr.Logger("my-service")
logger.Emit(ctx, log.Record{
    Timestamp:        time.Now(),
    Severity:         log.SeverityInfo,
    Body:             attribute.String("message", "operation completed"),
    Attributes:       []attribute.KeyValue{
        attribute.String("user.id", "123"),
        attribute.String("action", "login"),
    },
})

注意: 当前 Logs 使用 noop provider,不会发送数据到 OTLP 端点。此功能为预留接口。

生命周期管理
// OnStart - 服务器启动时调用
if err := mgr.OnStart(); err != nil {
    log.Fatal(err)
}

// Health - 检查管理器健康状态
if err := mgr.Health(); err != nil {
    log.Printf("manager unhealthy: %v", err)
}

// OnStop - 服务器停止时调用(会自动触发 Shutdown)
if err := mgr.OnStop(); err != nil {
    log.Printf("manager stop failed: %v", err)
}

// Shutdown - 优雅关闭,刷新所有待处理的数据
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := mgr.Shutdown(ctx); err != nil {
    log.Printf("manager shutdown failed: %v", err)
}

与中间件集成

使用 TelemetryMiddleware

litemiddleware 提供了 TelemetryMiddleware,可以自动为 HTTP 请求创建链路追踪 span。

import "github.com/lite-lake/litecore-go/component/litemiddleware"

// 创建中间件
telemetryMiddleware := litemiddleware.NewTelemetryMiddleware(nil)

// 注册到容器
middlewareContainer.RegisterMiddleware(telemetryMiddleware)

TelemetryMiddleware 会:

  • 自动为每个 HTTP 请求创建 span
  • 记录请求方法、路径、状态码等属性
  • 将 span 上下文传播到请求上下文
在 Service 层使用
type MessageService struct {
    TelemetryMgr telemetrymgr.ITelemetryManager `inject:""`
    tracer       trace.Tracer
}

func (s *MessageService) initTracer() {
    if s.TelemetryMgr != nil {
        s.tracer = s.TelemetryMgr.Tracer("message-service")
    }
}

func (s *MessageService) CreateMessage(ctx context.Context, msg *Message) error {
    s.initTracer()
    
    ctx, span := s.tracer.Start(ctx, "CreateMessage")
    defer span.End()
    
    // 业务逻辑
    span.SetAttributes(attribute.String("message.id", msg.ID))
    
    return nil
}

最佳实践

1. 使用 defer 确保资源释放
mgr, err := telemetrymgr.Build("otel", config)
if err != nil {
    return err
}
defer mgr.Shutdown(context.Background())
2. 设置合理的关闭超时
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
mgr.Shutdown(ctx)
3. 为不同服务使用不同的名称
userServiceTracer := mgr.Tracer("user-service")
orderServiceTracer := mgr.Tracer("order-service")
4. 在开发环境使用 none 驱动
driver := "none"
if os.Getenv("ENV") == "production" {
    driver = "otel"
}
mgr, err := telemetrymgr.Build(driver, config)
5. 资源属性包含服务信息
config := map[string]any{
    "resource_attributes": []telemetrymgr.ResourceAttribute{
        {Key: "service.name", Value: "my-service"},
        {Key: "service.version", Value: version},
        {Key: "deployment.environment", Value: environment},
    },
}
6. 传播上下文

在分布式系统中,确保 span 上下文在服务间传播:

// HTTP 请求携带 trace context
req, _ := http.NewRequest("GET", "http://api.example.com/data", nil)
span := trace.SpanFromContext(ctx)
trace.ContextWithSpan(req.Context(), span)
7. 合理设置采样率

在高流量场景下,可以通过采样率减少数据量:

// TODO: 当前版本未暴露采样率配置
// 未来版本将支持采样率配置

性能考虑

  • none 驱动:开销极小,几乎可以忽略
  • otel 驱动未启用特性时:使用 no-op provider,开销很小
  • otel 驱动启用特性后
    • 建立网络连接到 OTLP 端点
    • 使用批处理导出,减少网络开销
    • Traces 使用批量导出,默认批处理大小和超时可优化
  • 并发安全:所有方法都可以安全地并发调用

线程安全

ITelemetryManager 接口的所有实现都是并发安全的,可以在多个 goroutine 中同时使用。

for i := 0; i < 10; i++ {
    go func() {
        tracer := mgr.Tracer("worker")
        ctx, span := tracer.Start(context.Background(), "task")
        defer span.End()
    }()
}

常见问题

Q: 为什么 Metrics 和 Logs 不发送数据?

A: 当前版本的 Metrics 和 Logs 使用 noop provider,不会将数据发送到 OTLP 端点。此功能为预留接口,未来版本将支持完整的 Metrics 和 Logs 导出。

Q: 如何验证 OTel 集成是否正常工作?

A: 可以通过以下方式验证:

  1. 检查 mgr.Health() 是否返回错误
  2. 在 Jaeger 或其他收集器中查看是否有 span 数据
  3. 查看管理器日志,确认 exporter 初始化成功
Q: OTel 端点连接失败会怎样?

A: 如果 OTel 端点连接失败,NewTelemetryManagerOtelImpl 会返回错误。建议在创建管理器时检查错误。

Q: 如何在生产环境使用 TLS 连接?

A: 在配置中不设置 insecure 或设置为 false

config := map[string]any{
    "endpoint": "otel-collector.example.com:4317",
    "insecure": false,  // 使用 TLS
}
Q: 是否支持多个 OTel 端点?

A: 当前版本不支持多个端点。如果需要发送到多个端点,需要使用 OpenTelemetry Collector 作为中间聚合层。

相关文档

Documentation

Overview

Package telemetrymgr 提供统一的可观测性管理功能,支持 Traces、Metrics、Logs 三大信号。

核心特性:

  • 统一接口 - 提供 TelemetryManager 接口,统一管理可观测性组件
  • 多驱动支持 - 支持 none(空实现)和 otel(OpenTelemetry)两种驱动
  • 生命周期管理 - 集成 OnStart/OnStop 生命周期钩子,支持优雅关闭
  • 灵活配置 - 支持从配置提供者或直接配置创建管理器实例
  • 可观测性集成 - 完整支持链路追踪、指标收集和结构化日志

基本用法:

loggermgr "github.com/lite-lake/litecore-go/component/manager/loggermgr"

loggerMgr := loggermgr.GetLoggerManager()
logger := loggerMgr.Ins()

// 使用默认的 none 驱动创建管理器
mgr, err := telemetrymgr.Build("none", nil)
if err != nil {
    logger.Fatal("Failed to create telemetry manager", "error", err)
}
defer mgr.Shutdown(context.Background())

// 使用 OpenTelemetry 驱动
mgr, err = telemetrymgr.Build("otel", map[string]any{
    "endpoint": "localhost:4317",
    "insecure": true,
})
if err != nil {
    logger.Fatal("Failed to create telemetry manager", "error", err)
}
defer mgr.Shutdown(context.Background())

驱动类型:

支持 "none" 和 "otel" 两种驱动:

  • none: 空实现,不产生任何可观测性数据,适用于不需要遥测的场景
  • otel: OpenTelemetry 实现,连接到 OTLP 收集器(如 Jaeger、Tempo 等)

从配置提供者创建:

// 从配置提供者读取配置
mgr, err := telemetrymgr.BuildWithConfigProvider(configProvider)
if err != nil {
    logger.Fatal("Failed to create telemetry manager from config provider", "error", err)
}

配置路径:

  • telemetry.driver: 驱动类型 ("otel", "none")
  • telemetry.otel_config: OTel 驱动配置(当 driver=otel 时使用)

使用 Tracer:

tracer := mgr.Tracer("my-service")
ctx, span := tracer.Start(ctx, "operation-name")
defer span.End()
span.SetAttributes(attribute.String("key", "value"))

使用 Meter:

meter := mgr.Meter("my-service")
counter, _ := meter.Float64Counter("requests_total")
counter.Add(ctx, 1, attribute.String("path", "/api/users"))

使用 Logger:

logger := mgr.Logger("my-service")
logger.Emit(context.Background(), log.Record{...})

优雅关闭:

// OnStop 会自动调用 Shutdown,也可以手动调用
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
mgr.Shutdown(ctx)

Index

Constants

View Source
const (
	// 默认值
	DefaultOtelEndpoint = "localhost:4317"
	DefaultOtelInsecure = false
)

Variables

This section is empty.

Functions

func ValidateContext

func ValidateContext(ctx context.Context) error

ValidateContext 验证上下文是否有效

Types

type FeatureConfig

type FeatureConfig struct {
	Enabled bool `yaml:"enabled"`
}

FeatureConfig 功能配置

type ITelemetryManager

type ITelemetryManager interface {
	common.IBaseManager

	// ========== Tracing ==========
	// Tracer 获取 Tracer 实例
	Tracer(name string) trace.Tracer

	// TracerProvider 获取 TracerProvider
	TracerProvider() *sdktrace.TracerProvider

	// ========== Metrics ==========
	// Meter 获取 Meter 实例
	Meter(name string) metric.Meter

	// MeterProvider 获取 MeterProvider
	MeterProvider() *sdkmetric.MeterProvider

	// ========== Logging ==========
	// Logger 获取 Logger 实例
	Logger(name string) log.Logger

	// LoggerProvider 获取 LoggerProvider
	LoggerProvider() *sdklog.LoggerProvider

	// ========== 生命周期 ==========
	// Shutdown 关闭观测管理器,刷新所有待处理的数据
	Shutdown(ctx context.Context) error
}

ITelemetryManager 观测管理器接口 统一提供 Traces、Metrics、Logs 三大观测能力

func Build

func Build(
	driverType string,
	driverConfig map[string]any,
) (ITelemetryManager, error)

Build 创建观测管理器实例 driverType: 驱动类型 ("otel", "none") driverConfig: 驱动配置 (根据驱动类型不同而不同)

  • otel: 传递给 parseOtelConfig 的 map[string]any
  • none: 忽略

返回 ITelemetryManager 接口实例和可能的错误

func BuildWithConfigProvider

func BuildWithConfigProvider(configProvider configmgr.IConfigManager) (ITelemetryManager, error)

BuildWithConfigProvider 从配置提供者创建观测管理器实例 自动从配置提供者读取 telemetry.driver 和对应驱动配置 配置路径:

  • telemetry.driver: 驱动类型 ("otel", "none")
  • telemetry.otel_config: OTEL 驱动配置(当 driver=otel 时使用)

返回 ITelemetryManager 接口实例和可能的错误

func NewTelemetryManagerNoneImpl

func NewTelemetryManagerNoneImpl() ITelemetryManager

NewTelemetryManagerNoneImpl 创建空观测管理器实现

func NewTelemetryManagerOtelImpl

func NewTelemetryManagerOtelImpl(cfg *TelemetryConfig) (ITelemetryManager, error)

NewTelemetryManagerOtelImpl 创建 OTEL 观测管理器实现

type OtelConfig

type OtelConfig struct {
	Endpoint           string              `yaml:"endpoint"`            // OTLP 端点,如 http://localhost:4317
	Insecure           bool                `yaml:"insecure"`            // 是否使用不安全连接(默认false,使用TLS)
	ResourceAttributes []ResourceAttribute `yaml:"resource_attributes"` // 资源属性
	Headers            map[string]string   `yaml:"headers"`             // 请求头(用于认证)
	Traces             *FeatureConfig      `yaml:"traces"`              // 链路追踪配置
	Metrics            *FeatureConfig      `yaml:"metrics"`             // 指标配置
	Logs               *FeatureConfig      `yaml:"logs"`                // 日志配置
}

OtelConfig OpenTelemetry 配置

type ResourceAttribute

type ResourceAttribute struct {
	Key   string `yaml:"key"`
	Value string `yaml:"value"`
}

ResourceAttribute 资源属性

type TelemetryConfig

type TelemetryConfig struct {
	Driver     string      `yaml:"driver"`      // 驱动类型: none, otel
	OtelConfig *OtelConfig `yaml:"otel_config"` // OTEL 驱动配置
}

TelemetryConfig 观测管理配置

func DefaultConfig

func DefaultConfig() *TelemetryConfig

DefaultConfig 返回默认配置(禁用观测)

func ParseTelemetryConfigFromMap

func ParseTelemetryConfigFromMap(cfg map[string]any) (*TelemetryConfig, error)

ParseTelemetryConfigFromMap 从 ConfigMap 解析观测配置

func (*TelemetryConfig) Validate

func (c *TelemetryConfig) Validate() error

Validate 验证配置

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL