diff --git a/packages/opentelemetry-basic-tracer/src/export/SimpleSpanProcessor.ts b/packages/opentelemetry-basic-tracer/src/export/SimpleSpanProcessor.ts new file mode 100644 index 0000000000..301c392fbc --- /dev/null +++ b/packages/opentelemetry-basic-tracer/src/export/SimpleSpanProcessor.ts @@ -0,0 +1,42 @@ +/** + * Copyright 2019, OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TraceOptions } from '@opentelemetry/types'; +import { SpanProcessor } from '../SpanProcessor'; +import { SpanExporter } from './SpanExporter'; +import { Span } from '../Span'; + +/** + * An implementation of the {@link SpanProcessor} that converts the {@link Span} + * to {@link ReadableSpan} and passes it to the configured exporter. + * + * Only spans that are sampled are converted. + */ +export class SimpleSpanProcessor implements SpanProcessor { + constructor(private readonly _exporter: SpanExporter) {} + + // does nothing. + onStart(span: Span): void {} + + onEnd(span: Span): void { + if (span.context().traceOptions !== TraceOptions.SAMPLED) return; + this._exporter.export([span.toReadableSpan()], () => {}); + } + + shutdown(): void { + this._exporter.shutdown(); + } +} diff --git a/packages/opentelemetry-basic-tracer/test/export/SimpleSpanProcessor.test.ts b/packages/opentelemetry-basic-tracer/test/export/SimpleSpanProcessor.test.ts new file mode 100644 index 0000000000..b3ee89325a --- /dev/null +++ b/packages/opentelemetry-basic-tracer/test/export/SimpleSpanProcessor.test.ts @@ -0,0 +1,86 @@ +/** + * Copyright 2019, OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as assert from 'assert'; +import { SimpleSpanProcessor } from '../../src/export/SimpleSpanProcessor'; +import { Span, BasicTracer } from '../../src'; +import { SpanExporter } from '../../src/export/SpanExporter'; +import { ReadableSpan } from '../../src/export/ReadableSpan'; +import { SpanContext, SpanKind, TraceOptions } from '@opentelemetry/types'; +import { NoopScopeManager } from '@opentelemetry/scope-base'; + +class TestExporter implements SpanExporter { + spansDataList: ReadableSpan[] = []; + export(spans: ReadableSpan[]): void { + this.spansDataList.push(...spans); + } + + shutdown(): void { + this.spansDataList = []; + } +} + +describe('SimpleSpanProcessor', () => { + const tracer = new BasicTracer({ + scopeManager: new NoopScopeManager(), + }); + const exporter = new TestExporter(); + + describe('constructor', () => { + it('should create a SimpleSpanProcessor instance', () => { + const processor = new SimpleSpanProcessor(exporter); + assert.ok(processor instanceof SimpleSpanProcessor); + }); + }); + + describe('.onStart/.onEnd/.shutdown', () => { + it('should handle span started and ended when SAMPLED', () => { + const processor = new SimpleSpanProcessor(exporter); + const spanContext: SpanContext = { + traceId: 'a3cda95b652f4a1592b449d5929fda1b', + spanId: '5e0c63257de34c92', + traceOptions: TraceOptions.SAMPLED, + }; + const span = new Span(tracer, 'span-name', spanContext, SpanKind.CLIENT); + processor.onStart(span); + assert.strictEqual(exporter.spansDataList.length, 0); + + processor.onEnd(span); + assert.strictEqual(exporter.spansDataList.length, 1); + + processor.shutdown(); + assert.strictEqual(exporter.spansDataList.length, 0); + }); + + it('should handle span started and ended when UNSAMPLED', () => { + const processor = new SimpleSpanProcessor(exporter); + const spanContext: SpanContext = { + traceId: 'a3cda95b652f4a1592b449d5929fda1b', + spanId: '5e0c63257de34c92', + traceOptions: TraceOptions.UNSAMPLED, + }; + const span = new Span(tracer, 'span-name', spanContext, SpanKind.CLIENT); + processor.onStart(span); + assert.strictEqual(exporter.spansDataList.length, 0); + + processor.onEnd(span); + assert.strictEqual(exporter.spansDataList.length, 0); + + processor.shutdown(); + assert.strictEqual(exporter.spansDataList.length, 0); + }); + }); +});