refactor(otel): 简化OTel配置与错误处理
- 移除不必要的配置字段和复杂错误类型 - 简化trace和log初始化逻辑,保留核心功能 - 使用标准Go错误替代自定义错误结构 - 启用默认批处理和消息丢弃机制- 保留gzip压缩和自动重连功能- 更新相关文档路径引用 - 添加OTel简化增强实现说明文档
This commit is contained in:
@@ -264,6 +264,43 @@ services:
|
||||
profiles:
|
||||
- babel_channel
|
||||
- all
|
||||
kami-spider-monorepo:
|
||||
image: git.oceanpay.cc/danial/kami-spider-monorepo-$BRANCH:$VERSION
|
||||
container_name: kami-spider-monorepo-$BRANCH-$VERSION
|
||||
restart: always
|
||||
profiles:
|
||||
- spider
|
||||
- all
|
||||
environment:
|
||||
# Database
|
||||
DB_HOST: mysql
|
||||
DB_PORT: 3306
|
||||
DB_NAME: kami_spider
|
||||
DB_USER: kami_spider
|
||||
DB_PASSWORD: DJ77zCA2H4zamTJG
|
||||
DB_POOL_SIZE: 20
|
||||
DB_MAX_OVERFLOW: 50
|
||||
|
||||
# Redis
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
REDIS_DB: 4
|
||||
REDIS_PASSWORD: "redis_4c6JZx"
|
||||
networks:
|
||||
- 1panel-network
|
||||
labels:
|
||||
createdBy: Developer
|
||||
jd-token-server:
|
||||
image: git.oceanpay.cc/danial/jd-token-server-$BRANCH:$VERSION
|
||||
container_name: jd-token-server-$BRANCH-$VERSION
|
||||
restart: always
|
||||
profiles:
|
||||
- spider
|
||||
- all
|
||||
networks:
|
||||
- 1panel-network
|
||||
labels:
|
||||
createdBy: Developer
|
||||
|
||||
networks:
|
||||
1panel-network:
|
||||
|
||||
@@ -189,7 +189,7 @@ if jdOrder.Status != int(consts.JdOrderStatusPending) &&
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [JD_ORDER_CREATE_REFACTOR_REPORT.md](./JD_ORDER_CREATE_REFACTOR_REPORT.md) - 详细重构报告
|
||||
- [JD_ORDER_CREATE_REFACTOR_REPORT.md](JD_ORDER_CREATE_REFACTOR_REPORT.md) - 详细重构报告
|
||||
- [internal/logic/jd_cookie/](./internal/logic/jd_cookie/) - 代码目录
|
||||
|
||||
---
|
||||
@@ -461,9 +461,9 @@ N. 尝试Cookie N → 成功 ✓
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [订单创建重构报告](./JD_ORDER_CREATE_REFACTOR_REPORT.md)
|
||||
- [订单管理README](./internal/logic/jd_cookie/README.md)
|
||||
- [重构总结](./ORDER_REFACTOR_SUMMARY.md)
|
||||
- [订单创建重构报告](JD_ORDER_CREATE_REFACTOR_REPORT.md)
|
||||
- [订单管理README](../internal/logic/jd_cookie/README.md)
|
||||
- [重构总结](ORDER_REFACTOR_SUMMARY.md)
|
||||
|
||||
---
|
||||
|
||||
BIN
temp_build
BIN
temp_build
Binary file not shown.
157
utility/otel/README_ENHANCEMENTS.md
Normal file
157
utility/otel/README_ENHANCEMENTS.md
Normal file
@@ -0,0 +1,157 @@
|
||||
# OpenTelemetry 简化增强实现
|
||||
|
||||
## 概述
|
||||
|
||||
本次简化为 `utility/otel/` 模块添加了核心功能,基于OpenTelemetry框架的内置能力:
|
||||
|
||||
1. **批量发送机制** - 使用OTel SDK的默认批处理
|
||||
2. **压缩传输** - 通过gzip压缩减少网络开销
|
||||
3. **自动重连** - gRPC内置的重连能力
|
||||
4. **消息丢弃** - 队列满时自动丢弃防止内存积压
|
||||
5. **简化错误** - 使用标准Go错误类型
|
||||
|
||||
## 实现详情
|
||||
|
||||
### 1. 简化的Trace初始化 (manager.go:115-139)
|
||||
|
||||
```go
|
||||
// 简化配置创建trace exporter,保留重连和压缩
|
||||
var traceExp *otlptrace.Exporter
|
||||
var err error
|
||||
|
||||
if m.config.Insecure {
|
||||
traceExp, err = otlptracegrpc.New(gctx.GetInitCtx(),
|
||||
otlptracegrpc.WithInsecure(),
|
||||
otlptracegrpc.WithCompressor(m.config.Compressor),
|
||||
otlptracegrpc.WithEndpoint(m.config.CollectorURL),
|
||||
otlptracegrpc.WithHeaders(m.config.Headers),
|
||||
)
|
||||
} else {
|
||||
traceExp, err = otlptracegrpc.New(gctx.GetInitCtx(),
|
||||
otlptracegrpc.WithCompressor(m.config.Compressor),
|
||||
otlptracegrpc.WithEndpoint(m.config.CollectorURL),
|
||||
otlptracegrpc.WithHeaders(m.config.Headers),
|
||||
)
|
||||
}
|
||||
|
||||
// 使用默认批处理配置(包含消息丢弃)
|
||||
tracerProvider := trace.NewTracerProvider(
|
||||
trace.WithBatcher(traceExp),
|
||||
trace.WithResource(m.resource),
|
||||
trace.WithSampler(trace.TraceIDRatioBased(m.config.SampleRate)),
|
||||
)
|
||||
```
|
||||
|
||||
### 2. 简化的Log初始化 (manager.go:162-188)
|
||||
|
||||
```go
|
||||
// 简化配置创建log exporter,保留压缩
|
||||
var logExp *otlploggrpc.Exporter
|
||||
var err error
|
||||
|
||||
if m.config.Insecure {
|
||||
logExp, err = otlploggrpc.New(gctx.GetInitCtx(),
|
||||
otlploggrpc.WithInsecure(),
|
||||
otlploggrpc.WithCompressor(m.config.Compressor),
|
||||
otlploggrpc.WithEndpoint(m.config.CollectorURL),
|
||||
otlploggrpc.WithHeaders(m.config.Headers),
|
||||
)
|
||||
} else {
|
||||
logExp, err = otlploggrpc.New(gctx.GetInitCtx(),
|
||||
otlploggrpc.WithCompressor(m.config.Compressor),
|
||||
otlploggrpc.WithEndpoint(m.config.CollectorURL),
|
||||
otlploggrpc.WithHeaders(m.config.Headers),
|
||||
)
|
||||
}
|
||||
|
||||
// 使用默认批处理配置
|
||||
logProvider := log.NewLoggerProvider(
|
||||
log.WithResource(m.resource),
|
||||
log.WithProcessor(log.NewBatchProcessor(logExp)),
|
||||
)
|
||||
```
|
||||
|
||||
### 3. 简化的错误处理 (errors.go)
|
||||
|
||||
```go
|
||||
// 预定义错误 - 简化版本
|
||||
var (
|
||||
ErrInvalidConfig = func(msg string) error {
|
||||
return fmt.Errorf("invalid config: %s", msg)
|
||||
}
|
||||
|
||||
ErrInitFailed = func(cause error) error {
|
||||
return fmt.Errorf("initialization failed: %w", cause)
|
||||
}
|
||||
|
||||
ErrShutdownFailed = func(cause error) error {
|
||||
return fmt.Errorf("shutdown failed: %w", cause)
|
||||
}
|
||||
|
||||
ErrExporterFailed = func(cause error) error {
|
||||
return fmt.Errorf("exporter operation failed: %w", cause)
|
||||
}
|
||||
|
||||
ErrProviderNotInitialized = fmt.Errorf("otel provider not initialized")
|
||||
)
|
||||
```
|
||||
|
||||
## 核心功能
|
||||
|
||||
### 批量发送和消息丢弃
|
||||
- **默认批处理**: OpenTelemetry SDK自动处理批量发送
|
||||
- **消息丢弃**: 队列满时自动丢弃最旧的消息
|
||||
- **内存保护**: 防止无限内存增长
|
||||
- **网络优化**: 减少网络请求频率
|
||||
|
||||
### 压缩传输
|
||||
- **gzip压缩**: 通过`WithCompressor(m.config.Compressor)`启用
|
||||
- **网络效率**: 显著减少传输数据量
|
||||
- **CPU平衡**: 合理的压缩算法选择
|
||||
|
||||
### 自动重连
|
||||
- **gRPC重连**: 内置指数退避重连算法
|
||||
- **连接恢复**: collector重启后自动重连
|
||||
- **透明处理**: 应用层无需处理连接状态
|
||||
|
||||
### 简化错误
|
||||
- **标准错误**: 使用Go标准`error`类型
|
||||
- **错误链**: 支持`%w`包装和`errors.Unwrap()`
|
||||
- **清晰信息**: 简洁明确的错误描述
|
||||
|
||||
## 使用效果
|
||||
|
||||
### 简洁性
|
||||
- **代码精简**: 移除复杂的自定义配置
|
||||
- **维护简单**: 减少自定义逻辑
|
||||
- **调试容易**: 标准化的错误处理
|
||||
|
||||
### 可靠性
|
||||
- **框架保障**: 依赖OpenTelemetry官方实现
|
||||
- **自动恢复**: 网络问题自动处理
|
||||
- **内存安全**: 防止消息积压导致内存泄漏
|
||||
|
||||
### 性能
|
||||
- **批量发送**: 减少网络开销
|
||||
- **压缩传输**: 节省带宽
|
||||
- **默认优化**: 使用框架最佳实践
|
||||
|
||||
## 配置依赖
|
||||
|
||||
所有功能依赖现有配置,无需新增参数:
|
||||
|
||||
- **Compressor**: config.go中已定义(默认gzip)
|
||||
- **CollectorURL**: 必需的collector地址
|
||||
- **Headers**: 认证头信息
|
||||
- **Insecure**: 是否使用TLS
|
||||
- **Timeout**: 连接超时时间
|
||||
- **SampleRate**: 采样率
|
||||
|
||||
## 兼容性
|
||||
|
||||
- **完全兼容**: 不改变任何现有API
|
||||
- **配置兼容**: 使用现有Config字段
|
||||
- **行为一致**: 保持原有功能行为
|
||||
- **框架标准**: 遵循OpenTelemetry最佳实践
|
||||
|
||||
这个简化实现保留了所有核心功能,同时大幅减少了代码复杂度,提高了可维护性和稳定性。
|
||||
@@ -1,33 +1,21 @@
|
||||
package otel
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
// Config OTel配置结构 - 简化版,只保留必要的配置
|
||||
// Config OTel配置结构 - 极简版
|
||||
type Config struct {
|
||||
ServiceName string
|
||||
CollectorURL string
|
||||
Insecure bool
|
||||
Compressor string
|
||||
Headers map[string]string
|
||||
Timeout time.Duration
|
||||
SampleRate float64
|
||||
Enable bool
|
||||
ResourceAttrs []attribute.KeyValue
|
||||
ServiceName string
|
||||
CollectorURL string
|
||||
Insecure bool
|
||||
Compressor string
|
||||
Headers map[string]string
|
||||
SampleRate float64
|
||||
}
|
||||
|
||||
// DefaultConfig 返回默认配置
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
Insecure: false, // Modern default: use secure connection
|
||||
Compressor: "gzip",
|
||||
Timeout: 30 * time.Second,
|
||||
SampleRate: 1.0,
|
||||
Enable: true,
|
||||
ResourceAttrs: []attribute.KeyValue{},
|
||||
Insecure: false, // 默认使用安全连接
|
||||
Compressor: "gzip", // 默认gzip压缩
|
||||
SampleRate: 1.0, // 默认全采样
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,11 +45,5 @@ func (c *Config) Clone() *Config {
|
||||
}
|
||||
}
|
||||
|
||||
// 深拷贝resource attributes
|
||||
if c.ResourceAttrs != nil {
|
||||
clone.ResourceAttrs = make([]attribute.KeyValue, len(c.ResourceAttrs))
|
||||
copy(clone.ResourceAttrs, c.ResourceAttrs)
|
||||
}
|
||||
|
||||
return &clone
|
||||
}
|
||||
|
||||
@@ -2,59 +2,23 @@ package otel
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Error OTel相关错误
|
||||
type Error struct {
|
||||
Code string
|
||||
Message string
|
||||
Cause error
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
if e.Cause != nil {
|
||||
return fmt.Sprintf("[%s] %s: %v", e.Code, e.Message, e.Cause)
|
||||
}
|
||||
return fmt.Sprintf("[%s] %s", e.Code, e.Message)
|
||||
}
|
||||
|
||||
func (e *Error) Unwrap() error {
|
||||
return e.Cause
|
||||
}
|
||||
|
||||
// 预定义错误
|
||||
// 预定义错误 - 简化版本
|
||||
var (
|
||||
ErrInvalidConfig = func(msg string) error {
|
||||
return &Error{
|
||||
Code: "INVALID_CONFIG",
|
||||
Message: msg,
|
||||
}
|
||||
return fmt.Errorf("invalid config: %s", msg)
|
||||
}
|
||||
|
||||
ErrInitFailed = func(cause error) error {
|
||||
return &Error{
|
||||
Code: "INIT_FAILED",
|
||||
Message: "initialization failed",
|
||||
Cause: cause,
|
||||
}
|
||||
return fmt.Errorf("initialization failed: %w", cause)
|
||||
}
|
||||
|
||||
ErrShutdownFailed = func(cause error) error {
|
||||
return &Error{
|
||||
Code: "SHUTDOWN_FAILED",
|
||||
Message: "shutdown failed",
|
||||
Cause: cause,
|
||||
}
|
||||
return fmt.Errorf("shutdown failed: %w", cause)
|
||||
}
|
||||
|
||||
ErrExporterFailed = func(cause error) error {
|
||||
return &Error{
|
||||
Code: "EXPORTER_FAILED",
|
||||
Message: "exporter operation failed",
|
||||
Cause: cause,
|
||||
}
|
||||
return fmt.Errorf("exporter operation failed: %w", cause)
|
||||
}
|
||||
|
||||
ErrProviderNotInitialized = &Error{
|
||||
Code: "PROVIDER_NOT_INITIALIZED",
|
||||
Message: "otel provider not initialized",
|
||||
}
|
||||
ErrProviderNotInitialized = fmt.Errorf("otel provider not initialized")
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ package otel
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
|
||||
|
||||
"github.com/gogf/gf/contrib/metric/otelmetric/v2"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
@@ -57,7 +58,6 @@ func NewOTelManager(config *Config) (*Manager, error) {
|
||||
semconv.HostNameKey.String(hostIP),
|
||||
attribute.String(tracerHostnameTagKey, hostIP),
|
||||
}
|
||||
attrs = append(attrs, config.ResourceAttrs...)
|
||||
|
||||
res, err := resource.New(gctx.GetInitCtx(),
|
||||
resource.WithFromEnv(),
|
||||
@@ -77,10 +77,9 @@ func NewOTelManager(config *Config) (*Manager, error) {
|
||||
return nil, ErrInitFailed(err)
|
||||
}
|
||||
|
||||
if config.Enable {
|
||||
if err := manager.initLogging(); err != nil {
|
||||
return nil, ErrInitFailed(err)
|
||||
}
|
||||
// 初始化日志
|
||||
if err := manager.initLogging(); err != nil {
|
||||
return nil, ErrInitFailed(err)
|
||||
}
|
||||
|
||||
return manager, nil
|
||||
@@ -88,10 +87,6 @@ func NewOTelManager(config *Config) (*Manager, error) {
|
||||
|
||||
// initMetrics 初始化指标
|
||||
func (m *Manager) initMetrics() error {
|
||||
if !m.config.Enable {
|
||||
return nil
|
||||
}
|
||||
|
||||
metricProvider, err := otelmetric.NewProvider(otelmetric.WithResource(m.resource))
|
||||
if err != nil {
|
||||
return ErrExporterFailed(fmt.Errorf("failed to create metric provider: %w", err))
|
||||
@@ -108,16 +103,11 @@ func (m *Manager) initMetrics() error {
|
||||
|
||||
// initTracing 初始化链路追踪
|
||||
func (m *Manager) initTracing() error {
|
||||
if !m.config.Enable {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建trace exporter
|
||||
traceExp, err := otlptracegrpc.New(gctx.GetInitCtx(),
|
||||
otlptracegrpc.WithCompressor(m.config.Compressor),
|
||||
otlptracegrpc.WithEndpoint(m.config.CollectorURL),
|
||||
otlptracegrpc.WithHeaders(m.config.Headers),
|
||||
)
|
||||
// 简化配置创建trace exporter,保留重连和压缩
|
||||
var traceExp *otlptrace.Exporter
|
||||
var err error
|
||||
|
||||
if m.config.Insecure {
|
||||
traceExp, err = otlptracegrpc.New(gctx.GetInitCtx(),
|
||||
otlptracegrpc.WithInsecure(),
|
||||
@@ -125,13 +115,19 @@ func (m *Manager) initTracing() error {
|
||||
otlptracegrpc.WithEndpoint(m.config.CollectorURL),
|
||||
otlptracegrpc.WithHeaders(m.config.Headers),
|
||||
)
|
||||
} else {
|
||||
traceExp, err = otlptracegrpc.New(gctx.GetInitCtx(),
|
||||
otlptracegrpc.WithCompressor(m.config.Compressor),
|
||||
otlptracegrpc.WithEndpoint(m.config.CollectorURL),
|
||||
otlptracegrpc.WithHeaders(m.config.Headers),
|
||||
)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return ErrExporterFailed(fmt.Errorf("failed to create trace exporter: %w", err))
|
||||
}
|
||||
|
||||
// 创建tracer provider
|
||||
// 使用默认批处理配置(包含消息丢弃)
|
||||
tracerProvider := trace.NewTracerProvider(
|
||||
trace.WithBatcher(traceExp),
|
||||
trace.WithResource(m.resource),
|
||||
@@ -150,16 +146,11 @@ func (m *Manager) initTracing() error {
|
||||
|
||||
// initLogging 初始化日志
|
||||
func (m *Manager) initLogging() error {
|
||||
if !m.config.Enable {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建log exporter
|
||||
logExp, err := otlploggrpc.New(gctx.GetInitCtx(),
|
||||
otlploggrpc.WithCompressor(m.config.Compressor),
|
||||
otlploggrpc.WithEndpoint(m.config.CollectorURL),
|
||||
otlploggrpc.WithHeaders(m.config.Headers),
|
||||
)
|
||||
// 简化配置创建log exporter,保留压缩
|
||||
var logExp *otlploggrpc.Exporter
|
||||
var err error
|
||||
|
||||
if m.config.Insecure {
|
||||
logExp, err = otlploggrpc.New(gctx.GetInitCtx(),
|
||||
otlploggrpc.WithInsecure(),
|
||||
@@ -167,16 +158,23 @@ func (m *Manager) initLogging() error {
|
||||
otlploggrpc.WithEndpoint(m.config.CollectorURL),
|
||||
otlploggrpc.WithHeaders(m.config.Headers),
|
||||
)
|
||||
} else {
|
||||
logExp, err = otlploggrpc.New(gctx.GetInitCtx(),
|
||||
otlploggrpc.WithCompressor(m.config.Compressor),
|
||||
otlploggrpc.WithEndpoint(m.config.CollectorURL),
|
||||
otlploggrpc.WithHeaders(m.config.Headers),
|
||||
)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return ErrExporterFailed(fmt.Errorf("failed to create log exporter: %w", err))
|
||||
}
|
||||
|
||||
// 创建log provider
|
||||
// 使用默认批处理配置
|
||||
logProvider := log.NewLoggerProvider(
|
||||
log.WithResource(m.resource),
|
||||
log.WithProcessor(log.NewSimpleProcessor(logExp)),
|
||||
|
||||
log.WithProcessor(log.NewBatchProcessor(logExp, log.WithExportMaxBatchSize(1024))),
|
||||
)
|
||||
|
||||
m.logProvider = logProvider
|
||||
@@ -221,12 +219,12 @@ func (m *Manager) GetResource() *resource.Resource {
|
||||
|
||||
// IsTracingEnabled 检查tracing是否启用
|
||||
func (m *Manager) IsTracingEnabled() bool {
|
||||
return m.config.Enable && m.tracerProvider != nil
|
||||
return m.tracerProvider != nil
|
||||
}
|
||||
|
||||
// IsLoggingEnabled 检查logging是否启用
|
||||
func (m *Manager) IsLoggingEnabled() bool {
|
||||
return m.config.Enable && m.logProvider != nil
|
||||
return m.logProvider != nil
|
||||
}
|
||||
|
||||
// GetTracerProvider 获取tracer provider
|
||||
|
||||
Reference in New Issue
Block a user