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

# @loongsuite/cms_exporters

## 简介

CMS Exporters 提供多种数据导出器，用于将追踪数据发送到不同的后端系统。支持控制台输出、OTLP 协议导出等多种方式，满足开发调试和生产环境的不同需求。

## 特性

- 📊 **控制台导出**: 开发调试时的控制台输出
- 🌐 **OTLP 导出**: 标准 OTLP 协议支持
- 🔄 **批量处理**: 高效的批量数据导出
- 📦 **多种格式**: 支持 protobuf 和 JSON 格式
- 🔧 **可配置**: 灵活的配置选项
- 🚀 **高性能**: 异步非阻塞导出

## 安装

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

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

## 导出器类型

### ConsoleSpanExporter

将 Span 数据输出到控制台，主要用于开发和调试。

```typescript
import { ConsoleSpanExporter } from '@loongsuite/cms_exporters';

const exporter = new ConsoleSpanExporter({
  // 可选配置
  prettyPrint: true,  // 美化输出格式
  maxItems: 100       // 最大输出条目数
});

// 导出单个 span
await exporter.export([span], () => {
  console.log('Export completed');
});

// 关闭导出器
await exporter.shutdown();
```

### OTLPTraceExporter

将追踪数据以 OTLP 协议导出到收集器，支持生产环境使用。

```typescript
import { OTLPTraceExporter } from '@loongsuite/cms_exporters';

const exporter = new OTLPTraceExporter({
  url: 'http://collector:4318/v1/traces',
  headers: {
    'Authorization': 'Bearer your-token',
    'Content-Type': 'application/x-protobuf'
  },
  contentType: 'protobuf', // 或 'json'
  timeoutMillis: 5000,
  compression: 'gzip' // 可选压缩
});
```

## 主要导出

```typescript
import {
  ConsoleSpanExporter,
  OTLPTraceExporter,
  SpanExporter,
  ExportResult,
  ExportResultCode
} from '@loongsuite/cms_exporters';
```

## 使用示例

### 控制台导出示例

```typescript
import { TracerManager, BatchSpanProcessor } from '@loongsuite/cms_trace';
import { ConsoleSpanExporter } from '@loongsuite/cms_exporters';

// 创建控制台导出器
const consoleExporter = new ConsoleSpanExporter({
  prettyPrint: true
});

// 创建追踪器管理器
const tracerManager = new TracerManager({
  spanProcessors: [
    new BatchSpanProcessor(consoleExporter, {
      scheduledDelayMillis: 200,
      maxExportBatchSize: 100,
      maxQueueSize: 1000
    })
  ]
});

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

// 创建 span
const span = tracer.startSpan('user-operation', {
  attributes: {
    'user.id': '12345',
    'operation.type': 'login'
  }
});

// 模拟业务逻辑
setTimeout(() => {
  span.setStatus({ code: 1, message: 'Success' });
  span.end();
}, 100);

// 输出示例:
// {
//   "traceId": "abc123...",
//   "spanId": "def456...",
//   "name": "user-operation",
//   "attributes": {
//     "user.id": "12345",
//     "operation.type": "login"
//   },
//   "status": { "code": 1, "message": "Success" }
// }
```

### OTLP 导出示例

```typescript
import { TracerManager, BatchSpanProcessor } from '@loongsuite/cms_trace';
import { OTLPTraceExporter } from '@loongsuite/cms_exporters';

// 创建 OTLP 导出器
const otlpExporter = new OTLPTraceExporter({
  url: 'http://jaeger-collector:14268/api/traces',
  headers: {
    'Authorization': 'Bearer your-api-key'
  },
  contentType: 'json',
  timeoutMillis: 10000
});

const tracerManager = new TracerManager({
  spanProcessors: [
    new BatchSpanProcessor(otlpExporter, {
      scheduledDelayMillis: 1000,
      maxExportBatchSize: 512,
      maxQueueSize: 2048
    })
  ]
});

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

// 创建复杂的 span
const parentSpan = tracer.startSpan('http-request', {
  kind: 1, // SERVER
  attributes: {
    'http.method': 'GET',
    'http.url': '/api/users',
    'http.status_code': 200
  }
});

// 创建子 span
const childSpan = tracer.startSpan('database-query', {
  kind: 2, // CLIENT
  attributes: {
    'db.system': 'postgresql',
    'db.operation': 'SELECT',
    'db.table': 'users'
  }
});

// 模拟数据库查询
setTimeout(() => {
  childSpan.end();
  parentSpan.end();
}, 50);
```

### 多导出器配置

```typescript
import { TracerManager, BatchSpanProcessor } from '@loongsuite/cms_trace';
import { ConsoleSpanExporter, OTLPTraceExporter } from '@loongsuite/cms_exporters';

// 开发环境：控制台 + OTLP
const consoleExporter = new ConsoleSpanExporter();
const otlpExporter = new OTLPTraceExporter({
  url: process.env.OTLP_ENDPOINT || 'http://localhost:4318/v1/traces'
});

const tracerManager = new TracerManager({
  spanProcessors: [
    // 开发环境输出到控制台
    new BatchSpanProcessor(consoleExporter, {
      scheduledDelayMillis: 100
    }),
    // 同时发送到收集器
    new BatchSpanProcessor(otlpExporter, {
      scheduledDelayMillis: 2000
    })
  ]
});
```

### 自定义导出器

```typescript
import { SpanExporter, ExportResult, ExportResultCode } from '@loongsuite/cms_exporters';

class CustomSpanExporter implements SpanExporter {
  async export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): Promise<void> {
    try {
      // 自定义导出逻辑
      for (const span of spans) {
        await this.sendToCustomBackend(span);
      }
      
      resultCallback({ code: ExportResultCode.SUCCESS });
    } catch (error) {
      console.error('Export failed:', error);
      resultCallback({ 
        code: ExportResultCode.FAILURE,
        error: error as Error
      });
    }
  }

  async shutdown(): Promise<void> {
    // 清理资源
  }

  private async sendToCustomBackend(span: ReadableSpan): Promise<void> {
    // 发送到自定义后端
    const payload = {
      traceId: span.spanContext().traceId,
      spanId: span.spanContext().spanId,
      name: span.name,
      attributes: span.attributes,
      events: span.events,
      status: span.status
    };
    
    // 发送 HTTP 请求或其他操作
    console.log('Sending to custom backend:', payload);
  }
}

// 使用自定义导出器
const customExporter = new CustomSpanExporter();
const tracerManager = new TracerManager({
  spanProcessors: [
    new BatchSpanProcessor(customExporter)
  ]
});
```

## 配置选项

### ConsoleSpanExporter 选项

```typescript
interface ConsoleSpanExporterOptions {
  prettyPrint?: boolean;  // 是否美化输出，默认 false
  maxItems?: number;     // 最大输出条目数，默认无限制
}
```

### OTLPTraceExporter 选项

```typescript
interface OTLPTraceExporterOptions {
  url: string;                    // 导出端点 URL
  headers?: Record<string, string>; // HTTP 请求头
  contentType?: 'protobuf' | 'json'; // 内容类型，默认 'protobuf'
  timeoutMillis?: number;         // 超时时间（毫秒），默认 10000
  compression?: 'gzip' | 'none'; // 压缩方式，默认 'none'
}
```

## 性能优化

### 批量处理配置

```typescript
import { BatchSpanProcessor } from '@loongsuite/cms_trace';

const processor = new BatchSpanProcessor(exporter, {
  scheduledDelayMillis: 1000,  // 批量导出间隔
  maxExportBatchSize: 512,     // 每批最大数量
  maxQueueSize: 2048,          // 队列最大大小
  exportTimeoutMillis: 30000   // 导出超时时间
});
```

### 错误处理

```typescript
const exporter = new OTLPTraceExporter({
  url: 'http://collector:4318/v1/traces',
  timeoutMillis: 5000
});

// 监听导出错误
exporter.export(spans, (result) => {
  if (result.code === ExportResultCode.FAILURE) {
    console.error('Export failed:', result.error);
    // 实现重试逻辑或降级处理
  }
});
```

## 与 NodeSDK 集成

```typescript
import { NodeSDK } from '@loongsuite/cms_node_sdk';
import { ConsoleSpanExporter, OTLPTraceExporter } from '@loongsuite/cms_exporters';
import { BatchSpanProcessor } from '@loongsuite/cms_trace';

const sdk = new NodeSDK({
  serviceName: 'my-service',
  spanProcessors: [
    // 开发环境
    new BatchSpanProcessor(new ConsoleSpanExporter({ prettyPrint: true })),
    // 生产环境
    new BatchSpanProcessor(new OTLPTraceExporter({
      url: process.env.OTLP_ENDPOINT,
      headers: { 'Authorization': process.env.OTLP_TOKEN }
    }))
  ]
});

sdk.start();
```

## 故障排除

### 常见问题

1. **导出失败**: 检查网络连接和端点配置
2. **性能问题**: 调整批量处理参数
3. **内存泄漏**: 确保正确关闭导出器

### 调试技巧

```typescript
// 启用详细日志
const exporter = new OTLPTraceExporter({
  url: 'http://collector:4318/v1/traces',
  // 添加调试头
  headers: {
    'X-Debug': 'true'
  }
});

// 监听导出结果
exporter.export(spans, (result) => {
  console.log('Export result:', result);
});
```

## 依赖

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

## 许可证

MIT License