@loongsuite/cms_exporters
简介
CMS Exporters 提供多种数据导出器,用于将追踪数据发送到不同的后端系统。支持控制台输出、OTLP 协议导出等多种方式,满足开发调试和生产环境的不同需求。
特性
- 📊 控制台导出: 开发调试时的控制台输出
- 🌐 OTLP 导出: 标准 OTLP 协议支持
- 🔄 批量处理: 高效的批量数据导出
- 📦 多种格式: 支持 protobuf 和 JSON 格式
- 🔧 可配置: 灵活的配置选项
- 🚀 高性能: 异步非阻塞导出
安装
anpm add @loongsuite/cms_exporters
npm install @loongsuite/cms_exporters
导出器类型
ConsoleSpanExporter
将 Span 数据输出到控制台,主要用于开发和调试。
import { ConsoleSpanExporter } from '@loongsuite/cms_exporters';
const exporter = new ConsoleSpanExporter({
  
  prettyPrint: true,  
  maxItems: 100       
});
await exporter.export([span], () => {
  console.log('Export completed');
});
await exporter.shutdown();
OTLPTraceExporter
将追踪数据以 OTLP 协议导出到收集器,支持生产环境使用。
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', 
  timeoutMillis: 5000,
  compression: 'gzip' 
});
主要导出
import {
  ConsoleSpanExporter,
  OTLPTraceExporter,
  SpanExporter,
  ExportResult,
  ExportResultCode
} from '@loongsuite/cms_exporters';
使用示例
控制台导出示例
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');
const span = tracer.startSpan('user-operation', {
  attributes: {
    'user.id': '12345',
    'operation.type': 'login'
  }
});
setTimeout(() => {
  span.setStatus({ code: 1, message: 'Success' });
  span.end();
}, 100);
OTLP 导出示例
import { TracerManager, BatchSpanProcessor } from '@loongsuite/cms_trace';
import { OTLPTraceExporter } from '@loongsuite/cms_exporters';
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');
const parentSpan = tracer.startSpan('http-request', {
  kind: 1, 
  attributes: {
    'http.method': 'GET',
    'http.url': '/api/users',
    'http.status_code': 200
  }
});
const childSpan = tracer.startSpan('database-query', {
  kind: 2, 
  attributes: {
    'db.system': 'postgresql',
    'db.operation': 'SELECT',
    'db.table': 'users'
  }
});
setTimeout(() => {
  childSpan.end();
  parentSpan.end();
}, 50);
多导出器配置
import { TracerManager, BatchSpanProcessor } from '@loongsuite/cms_trace';
import { ConsoleSpanExporter, OTLPTraceExporter } from '@loongsuite/cms_exporters';
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
    })
  ]
});
自定义导出器
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
    };
    
    
    console.log('Sending to custom backend:', payload);
  }
}
const customExporter = new CustomSpanExporter();
const tracerManager = new TracerManager({
  spanProcessors: [
    new BatchSpanProcessor(customExporter)
  ]
});
配置选项
ConsoleSpanExporter 选项
interface ConsoleSpanExporterOptions {
  prettyPrint?: boolean;  
  maxItems?: number;     
}
OTLPTraceExporter 选项
interface OTLPTraceExporterOptions {
  url: string;                    
  headers?: Record<string, string>; 
  contentType?: 'protobuf' | 'json'; 
  timeoutMillis?: number;         
  compression?: 'gzip' | 'none'; 
}
性能优化
批量处理配置
import { BatchSpanProcessor } from '@loongsuite/cms_trace';
const processor = new BatchSpanProcessor(exporter, {
  scheduledDelayMillis: 1000,  
  maxExportBatchSize: 512,     
  maxQueueSize: 2048,          
  exportTimeoutMillis: 30000   
});
错误处理
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 集成
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();
故障排除
常见问题
- 导出失败: 检查网络连接和端点配置
- 性能问题: 调整批量处理参数
- 内存泄漏: 确保正确关闭导出器
调试技巧
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