Skip to content

Commit

Permalink
feat: add baggage support to the opentracing shim (open-telemetry#918)
Browse files Browse the repository at this point in the history
Co-authored-by: Mayur Kale <mayurkale@google.com>
  • Loading branch information
2 people authored and jonahrosenblum committed Aug 6, 2020
1 parent 6f4de1e commit 5597957
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 24 deletions.
80 changes: 59 additions & 21 deletions packages/opentelemetry-shim-opentracing/src/shim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ import {
getExtractedSpanContext,
NoopLogger,
setExtractedSpanContext,
setCorrelationContext,
setActiveSpan,
getCorrelationContext,
} from '@opentelemetry/core';
import * as opentracing from 'opentracing';
import { defaultSetter } from '@opentelemetry/api';

function translateReferences(references: opentracing.Reference[]): api.Link[] {
const links: api.Link[] = [];
Expand Down Expand Up @@ -72,10 +73,15 @@ function getContextWithParent(options: opentracing.SpanOptions) {
*/
export class SpanContextShim extends opentracing.SpanContext {
private readonly _spanContext: api.SpanContext;
private _correlationContext: api.CorrelationContext;

constructor(spanContext: api.SpanContext) {
constructor(
spanContext: api.SpanContext,
correlationContext: api.CorrelationContext
) {
super();
this._spanContext = spanContext;
this._correlationContext = correlationContext;
}

/**
Expand All @@ -85,6 +91,13 @@ export class SpanContextShim extends opentracing.SpanContext {
return this._spanContext;
}

/**
* Returns the underlying {@link api.CorrelationContext}
*/
getCorrelationContext(): api.CorrelationContext {
return this._correlationContext;
}

/**
* Returns the trace ID as a string.
*/
Expand All @@ -98,6 +111,16 @@ export class SpanContextShim extends opentracing.SpanContext {
toSpanId(): string {
return this._spanContext.spanId;
}

getBaggageItem(key: string): string | undefined {
return this._correlationContext[key]?.value;
}

setBaggageItem(key: string, value: string) {
this._correlationContext = Object.assign({}, this._correlationContext, {
[key]: { value },
});
}
}

/**
Expand Down Expand Up @@ -125,29 +148,40 @@ export class TracerShim extends opentracing.Tracer {
getContextWithParent(options)
);

let correlationContext: api.CorrelationContext = {};
if (options.childOf instanceof SpanShim) {
const shimContext = options.childOf.context() as SpanContextShim;
correlationContext = shimContext.getCorrelationContext();
} else if (options.childOf instanceof SpanContextShim) {
correlationContext = options.childOf.getCorrelationContext();
}

if (options.tags) {
span.setAttributes(options.tags);
}

return new SpanShim(this, span);
return new SpanShim(this, span, correlationContext);
}

_inject(
spanContext: opentracing.SpanContext,
format: string,
carrier: unknown
): void {
const opentelemSpanContext: api.SpanContext = (spanContext as SpanContextShim).getSpanContext();
const spanContextShim: SpanContextShim = spanContext as SpanContextShim;
const oTelSpanContext: api.SpanContext = spanContextShim.getSpanContext();
const oTelSpanCorrelationContext: api.CorrelationContext = spanContextShim.getCorrelationContext();

if (!carrier || typeof carrier !== 'object') return;
switch (format) {
case opentracing.FORMAT_HTTP_HEADERS:
case opentracing.FORMAT_TEXT_MAP: {
api.propagation.inject(
carrier,
defaultSetter,
setExtractedSpanContext(
api.Context.ROOT_CONTEXT,
opentelemSpanContext
api.defaultSetter,
setCorrelationContext(
setExtractedSpanContext(api.Context.ROOT_CONTEXT, oTelSpanContext),
oTelSpanCorrelationContext
)
);
return;
Expand All @@ -156,7 +190,7 @@ export class TracerShim extends opentracing.Tracer {
this._logger.warn(
'OpentracingShim.inject() does not support FORMAT_BINARY'
);
// @todo: Implement binary format
// @todo: Implement binary formats
return;
}
default:
Expand All @@ -167,13 +201,14 @@ export class TracerShim extends opentracing.Tracer {
switch (format) {
case opentracing.FORMAT_HTTP_HEADERS:
case opentracing.FORMAT_TEXT_MAP: {
const context = getExtractedSpanContext(
api.propagation.extract(carrier)
);
if (!context) {
const context: api.Context = api.propagation.extract(carrier);
const spanContext = getExtractedSpanContext(context);
const correlationContext = getCorrelationContext(context);

if (!spanContext) {
return null;
}
return new SpanContextShim(context);
return new SpanContextShim(spanContext, correlationContext || {});
}
case opentracing.FORMAT_BINARY: {
// @todo: Implement binary format
Expand All @@ -191,19 +226,23 @@ export class TracerShim extends opentracing.Tracer {
/**
* SpanShim wraps an {@link types.Span} and implements the OpenTracing Span API
* around it.
* @todo: Out of band baggage propagation is not currently supported.
*/
*
**/
export class SpanShim extends opentracing.Span {
// _span is the original OpenTelemetry span that we are wrapping with
// an opentracing interface.
private readonly _span: api.Span;
private readonly _contextShim: SpanContextShim;
private readonly _tracerShim: TracerShim;

constructor(tracerShim: TracerShim, span: api.Span) {
constructor(
tracerShim: TracerShim,
span: api.Span,
correlationContext: api.CorrelationContext
) {
super();
this._span = span;
this._contextShim = new SpanContextShim(span.context());
this._contextShim = new SpanContextShim(span.context(), correlationContext);
this._tracerShim = tracerShim;
}

Expand Down Expand Up @@ -295,12 +334,11 @@ export class SpanShim extends opentracing.Span {
}

getBaggageItem(key: string): string | undefined {
// TODO: should this go into the context?
return undefined;
return this._contextShim.getBaggageItem(key);
}

setBaggageItem(key: string, value: string): this {
// TODO: should this go into the context?
this._contextShim.setBaggageItem(key, value);
return this;
}

Expand Down
60 changes: 57 additions & 3 deletions packages/opentelemetry-shim-opentracing/test/Shim.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
INVALID_SPAN_CONTEXT,
timeInputToHrTime,
HttpTraceContext,
CompositePropagator,
HttpCorrelationContext,
} from '@opentelemetry/core';
import { propagation } from '@opentelemetry/api';
import { performance } from 'perf_hooks';
Expand All @@ -32,7 +34,11 @@ describe('OpenTracing Shim', () => {
provider.getTracer('default')
);
opentracing.initGlobalTracer(shimTracer);
propagation.setGlobalPropagator(new HttpTraceContext());
const compositePropagator = new CompositePropagator({
propagators: [new HttpTraceContext(), new HttpCorrelationContext()],
});

propagation.setGlobalPropagator(compositePropagator);

describe('TracerShim', () => {
let span: opentracing.Span;
Expand Down Expand Up @@ -86,6 +92,25 @@ describe('OpenTracing Shim', () => {
/* const extractedContext = shimTracer.extract(opentracing.FORMAT_BINARY, { buffer: new Uint8Array(carrier)}); */
/* assert.strictEqual(context.toSpanId(), extractedContext.toSpanId()) */
});

it('injects/extracts a span with baggage', () => {
const carrier: { [key: string]: unknown } = {};
span.setBaggageItem('baggage1', 'value1');
span.setBaggageItem('baggage2', 'value2');
shimTracer.inject(span, opentracing.FORMAT_HTTP_HEADERS, carrier);
const extractedContext = shimTracer.extract(
opentracing.FORMAT_HTTP_HEADERS,
carrier
) as SpanContextShim;
const childSpan = shimTracer.startSpan('other-span', {
childOf: extractedContext,
}) as SpanShim;
assert.ok(extractedContext !== null);
assert.strictEqual(context.toTraceId(), extractedContext!.toTraceId());
assert.strictEqual(context.toSpanId(), extractedContext!.toSpanId());
assert.strictEqual(childSpan.getBaggageItem('baggage1'), 'value1');
assert.strictEqual(childSpan.getBaggageItem('baggage2'), 'value2');
});
});

it('creates parent/child relationship using a span object', () => {
Expand Down Expand Up @@ -135,7 +160,7 @@ describe('OpenTracing Shim', () => {

describe('SpanContextShim', () => {
it('returns the correct context', () => {
const shim = new SpanContextShim(INVALID_SPAN_CONTEXT);
const shim = new SpanContextShim(INVALID_SPAN_CONTEXT, {});
assert.strictEqual(shim.getSpanContext(), INVALID_SPAN_CONTEXT);
assert.strictEqual(shim.toTraceId(), INVALID_SPAN_CONTEXT.traceId);
assert.strictEqual(shim.toSpanId(), INVALID_SPAN_CONTEXT.spanId);
Expand Down Expand Up @@ -190,7 +215,36 @@ describe('OpenTracing Shim', () => {

it('can set and retrieve baggage', () => {
span.setBaggageItem('baggage', 'item');
// TODO: baggage
const value = span.getBaggageItem('baggage');
assert.equal('item', value);

const childSpan = shimTracer.startSpan('child-span1', {
childOf: span,
});
childSpan.setBaggageItem('key2', 'item2');

// child should have parent baggage items.
assert.equal('item', childSpan.getBaggageItem('baggage'));
assert.equal('item2', childSpan.getBaggageItem('key2'));

// Parent shouldn't have the child baggage item.
assert.equal(span.getBaggageItem('key2'), undefined);
});

it('can set and retrieve baggage with same key', () => {
span.setBaggageItem('key1', 'value1');
const value = span.getBaggageItem('key1');
assert.equal('value1', value);

const childSpan = shimTracer.startSpan('child-span1', {
childOf: span,
});
childSpan.setBaggageItem('key2', 'value2');
childSpan.setBaggageItem('key1', 'value3');

// child should have parent baggage items.
assert.equal('value3', childSpan.getBaggageItem('key1'));
assert.equal('value2', childSpan.getBaggageItem('key2'));
});
});
});

0 comments on commit 5597957

Please sign in to comment.