npm package: @loongsuite/cms_propagators
Description: ## 简介
Latest version: 1.0.0

# @loongsuite/cms_propagators

## 简介

CMS Propagators 提供上下文传播器和传播管理器，实现分布式追踪中的上下文信息在服务间的传递。支持 W3C Trace Context、W3C Baggage 等标准协议，以及组合传播功能。

## 特性

- 🌐 **W3C 标准**: 支持 W3C Trace Context 和 Baggage 标准
- 🔄 **组合传播**: 支持多种传播器的组合使用
- 🎯 **灵活配置**: 可配置的传播管理器
- ⚡ **高性能**: 高效的上下文注入和提取
- 🔧 **类型安全**: 完整的 TypeScript 类型支持
- 📊 **标准化**: 遵循 OpenTelemetry 传播规范

## 安装

```bash
# 使用 anpm (推荐)
anpm add @loongsuite/cms_propagators

# 或使用 npm
npm install @loongsuite/cms_propagators
```

## 核心概念

### 传播器 (Propagator)

传播器负责在服务间传播上下文信息，主要包括：

1. **W3CTraceContextPropagator**: W3C Trace Context 传播器
2. **W3CBaggagePropagator**: W3C Baggage 传播器
3. **CompositePropagator**: 组合传播器

### 传播管理器 (PropagatorManager)

传播管理器统一管理传播器的注入和提取操作。

## 主要导出

```typescript
import {
  W3CTraceContextPropagator,
  W3CBaggagePropagator,
  PropagatorManager,
  CompositePropagator
} from '@loongsuite/cms_propagators';
```

## 使用示例

### W3C Trace Context 传播

```typescript
import { W3CTraceContextPropagator } from '@loongsuite/cms_propagators';
import { TracerManager } from '@loongsuite/cms_trace';
import { AsyncLocalStorageContextManager } from '@loongsuite/cms_context';

// 创建传播器
const tracerManager = new TracerManager({
  contextManager: new AsyncLocalStorageContextManager()
});
const traceContextPropagator = new W3CTraceContextPropagator(tracerManager);

// 创建 span
const tracer = tracerManager.getTracer('my-service');
const span = tracer.startSpan('outgoing-request');

// 注入上下文到 HTTP 请求头
const headers: Record<string, string> = {};
traceContextPropagator.inject(
  tracerManager.setSpan(tracerManager.getContextManager().active(), span),
  headers
);

console.log('Trace Context Headers:', headers);
// 输出类似: { 'traceparent': '00-abc123...-def456...-01' }

span.end();
```

### W3C Baggage 传播

```typescript
import { W3CBaggagePropagator } from '@loongsuite/cms_propagators';
import { AsyncLocalStorageContextManager } from '@loongsuite/cms_context';

// 创建 Baggage 传播器
const contextManager = new AsyncLocalStorageContextManager();
const baggagePropagator = new W3CBaggagePropagator();

// 设置 Baggage 信息
const baggageContext = {
  'user-id': '12345',
  'tenant-id': 'tenant-abc',
  'request-source': 'mobile-app'
};

// 注入 Baggage 到请求头
const headers: Record<string, string> = {};
baggagePropagator.inject(baggageContext, headers);

console.log('Baggage Headers:', headers);
// 输出类似: { 'baggage': 'user-id=12345,tenant-id=tenant-abc,request-source=mobile-app' }
```

### 组合传播器

```typescript
import { 
  W3CTraceContextPropagator, 
  W3CBaggagePropagator,
  CompositePropagator 
} from '@loongsuite/cms_propagators';
import { TracerManager } from '@loongsuite/cms_trace';
import { AsyncLocalStorageContextManager } from '@loongsuite/cms_context';

// 创建组合传播器
const contextManager = new AsyncLocalStorageContextManager();
const tracerManager = new TracerManager({ contextManager });

const traceContextPropagator = new W3CTraceContextPropagator(tracerManager);
const baggagePropagator = new W3CBaggagePropagator();

const compositePropagator = new CompositePropagator({
  propagators: [traceContextPropagator, baggagePropagator]
});

// 创建包含追踪和 Baggage 的上下文
const tracer = tracerManager.getTracer('my-service');
const span = tracer.startSpan('outgoing-request');
const contextWithSpan = tracerManager.setSpan(contextManager.active(), span);

const contextWithBaggage = {
  ...contextWithSpan,
  baggage: {
    'user-id': '12345',
    'tenant-id': 'tenant-abc'
  }
};

// 注入组合上下文
const headers: Record<string, string> = {};
compositePropagator.inject(contextWithBaggage, headers);

console.log('Combined Headers:', headers);
// 输出:
// {
//   'traceparent': '00-abc123...-def456...-01',
//   'baggage': 'user-id=12345,tenant-id=tenant-abc'
// }
```

### 传播管理器

```typescript
import { 
  PropagatorManager,
  W3CTraceContextPropagator,
  W3CBaggagePropagator,
  CompositePropagator 
} from '@loongsuite/cms_propagators';
import { TracerManager } from '@loongsuite/cms_trace';
import { AsyncLocalStorageContextManager } from '@loongsuite/cms_context';

// 创建传播管理器
const contextManager = new AsyncLocalStorageContextManager();
const tracerManager = new TracerManager({ contextManager });

const traceContextPropagator = new W3CTraceContextPropagator(tracerManager);
const baggagePropagator = new W3CBaggagePropagator();
const compositePropagator = new CompositePropagator({
  propagators: [traceContextPropagator, baggagePropagator]
});

const propagatorManager = new PropagatorManager({
  contextManager,
  propagator: compositePropagator
});

// 使用传播管理器
const tracer = tracerManager.getTracer('my-service');

// 服务端：从请求头提取上下文
const incomingHeaders = {
  'traceparent': '00-abc123...-def456...-01',
  'baggage': 'user-id=12345,tenant-id=tenant-abc'
};

const extractedContext = propagatorManager.extract(incomingHeaders);
contextManager.with(extractedContext, () => {
  const span = tracer.startSpan('incoming-request');
  
  // 获取 Baggage 信息
  const baggage = propagatorManager.getBaggage();
  console.log('Extracted Baggage:', baggage);
  
  span.end();
});

// 客户端：注入上下文到请求头
const outgoingHeaders: Record<string, string> = {};
propagatorManager.inject(outgoingHeaders);

console.log('Outgoing Headers:', outgoingHeaders);
```

### HTTP 服务示例

```typescript
import { 
  PropagatorManager,
  W3CTraceContextPropagator,
  W3CBaggagePropagator,
  CompositePropagator 
} from '@loongsuite/cms_propagators';
import { TracerManager, BatchSpanProcessor } from '@loongsuite/cms_trace';
import { ConsoleSpanExporter } from '@loongsuite/cms_exporters';
import { AsyncLocalStorageContextManager } from '@loongsuite/cms_context';
import * as http from 'http';

// 设置传播管理器
const contextManager = new AsyncLocalStorageContextManager();
const tracerManager = new TracerManager({
  contextManager,
  spanProcessors: [new BatchSpanProcessor(new ConsoleSpanExporter())]
});

const traceContextPropagator = new W3CTraceContextPropagator(tracerManager);
const baggagePropagator = new W3CBaggagePropagator();
const compositePropagator = new CompositePropagator({
  propagators: [traceContextPropagator, baggagePropagator]
});

const propagatorManager = new PropagatorManager({
  contextManager,
  propagator: compositePropagator
});

const tracer = tracerManager.getTracer('http-service');

// 创建 HTTP 服务器
const server = http.createServer((req, res) => {
  // 从请求头提取上下文
  const extractedContext = propagatorManager.extract(req.headers as any);
  
  contextManager.with(extractedContext, () => {
    const span = tracer.startSpan(`${req.method} ${req.url}`, {
      kind: 1 // SERVER
    });
    
    try {
      // 获取 Baggage 信息
      const baggage = propagatorManager.getBaggage();
      if (baggage) {
        span.setAttributes({
          'user.id': baggage.getEntry('user-id')?.value,
          'tenant.id': baggage.getEntry('tenant-id')?.value
        });
      }
      
      // 业务逻辑
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      res.end('Hello World');
      
    } finally {
      span.end();
    }
  });
});

server.listen(3000, () => {
  console.log('Server running on port 3000');
});
```

### HTTP 客户端示例

```typescript
import { 
  PropagatorManager,
  W3CTraceContextPropagator,
  W3CBaggagePropagator,
  CompositePropagator 
} from '@loongsuite/cms_propagators';
import { TracerManager, BatchSpanProcessor } from '@loongsuite/cms_trace';
import { ConsoleSpanExporter } from '@loongsuite/cms_exporters';
import { AsyncLocalStorageContextManager } from '@loongsuite/cms_context';
import * as http from 'http';

// 设置传播管理器
const contextManager = new AsyncLocalStorageContextManager();
const tracerManager = new TracerManager({
  contextManager,
  spanProcessors: [new BatchSpanProcessor(new ConsoleSpanExporter())]
});

const traceContextPropagator = new W3CTraceContextPropagator(tracerManager);
const baggagePropagator = new W3CBaggagePropagator();
const compositePropagator = new CompositePropagator({
  propagators: [traceContextPropagator, baggagePropagator]
});

const propagatorManager = new PropagatorManager({
  contextManager,
  propagator: compositePropagator
});

const tracer = tracerManager.getTracer('http-client');

// 创建 HTTP 请求
function makeHttpRequest(url: string, options: http.RequestOptions = {}) {
  const span = tracer.startSpan(`HTTP ${options.method || 'GET'}`, {
    kind: 2 // CLIENT
  });
  
  try {
    // 设置 Baggage
    propagatorManager.setBaggage({
      'request-source': 'client-app',
      'user-id': '12345'
    });
    
    // 注入上下文到请求头
    const headers = { ...options.headers };
    propagatorManager.inject(headers);
    
    // 发送请求
    const req = http.request(url, {
      ...options,
      headers
    }, (res) => {
      span.setAttributes({
        'http.status_code': res.statusCode,
        'http.response_size': res.headers['content-length']
      });
      
      res.on('end', () => {
        span.end();
      });
    });
    
    req.on('error', (error) => {
      span.setStatus({ code: 2, message: error.message });
      span.end();
    });
    
    req.end();
    
  } catch (error) {
    span.setStatus({ code: 2, message: error.message });
    span.end();
  }
}

// 使用示例
makeHttpRequest('http://localhost:3000/api/users', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json'
  }
});
```

## 配置选项

### CompositePropagator 配置

```typescript
interface CompositePropagatorConfig {
  propagators: TextMapPropagator[];
}
```

### PropagatorManager 配置

```typescript
interface PropagatorManagerConfig {
  contextManager: IContextManager;
  propagator: TextMapPropagator;
}
```

## 性能考虑

### 传播器选择

- **W3CTraceContextPropagator**: 标准追踪上下文传播，性能最佳
- **W3CBaggagePropagator**: Baggage 信息传播，适合元数据传递
- **CompositePropagator**: 组合传播，功能最全但性能稍差

### 最佳实践

```typescript
// 好的做法：按需使用传播器
const propagators = [traceContextPropagator];
if (needBaggage) {
  propagators.push(baggagePropagator);
}
const compositePropagator = new CompositePropagator({ propagators });

// 避免：不必要的传播器
const allPropagators = new CompositePropagator({
  propagators: [traceContextPropagator, baggagePropagator, customPropagator]
});
```

## 与 NodeSDK 集成

```typescript
import { NodeSDK } from '@loongsuite/cms_node_sdk';
import { 
  PropagatorManager,
  W3CTraceContextPropagator,
  W3CBaggagePropagator,
  CompositePropagator 
} from '@loongsuite/cms_propagators';

const sdk = new NodeSDK({
  serviceName: 'my-service',
  // 传播管理器会自动配置
});

sdk.start();

// 获取传播管理器
const propagatorManager = sdk.getPropagatorManager();
console.log(propagatorManager instanceof PropagatorManager); // true
```

## 故障排除

### 常见问题

1. **上下文丢失**: 确保正确使用传播管理器
2. **Baggage 不生效**: 检查 Baggage 传播器是否正确配置
3. **性能问题**: 避免使用不必要的传播器

### 调试技巧

```typescript
// 调试传播过程
const debugPropagator = {
  inject: (context: Context, carrier: Carrier) => {
    console.log('Injecting context:', context);
    console.log('Into carrier:', carrier);
    compositePropagator.inject(context, carrier);
    console.log('Result carrier:', carrier);
  },
  
  extract: (context: Context, carrier: Carrier) => {
    console.log('Extracting from carrier:', carrier);
    const result = compositePropagator.extract(context, carrier);
    console.log('Extracted context:', result);
    return result;
  }
};
```

## 依赖

- `@loongsuite/cms_core`: 核心类型和接口定义

## 许可证

MIT License