Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add baggage support to the opentracing shim #918

Merged
merged 9 commits into from
Jul 27, 2020
79 changes: 60 additions & 19 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 {
dyladan marked this conversation as resolved.
Show resolved Hide resolved
return this._correlationContext;
}

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

getBaggageItem(key: string): string | undefined {
const entry: api.EntryValue = this._correlationContext[key];
obecny marked this conversation as resolved.
Show resolved Hide resolved
return entry === undefined ? undefined : entry.value;
}

setBaggageItem(key: string, value: string) {
this._correlationContext = Object.assign(
{ [key]: { value } },
obecny marked this conversation as resolved.
Show resolved Hide resolved
this._correlationContext
);
}
}

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

let correlationContext: api.CorrelationContext = {};
if (options.childOf) {
obecny marked this conversation as resolved.
Show resolved Hide resolved
if (options.childOf instanceof SpanShim) {
const shimContext = options.childOf.context() as SpanContextShim;
correlationContext = shimContext.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 oTelSpanContext: api.SpanContext = (spanContext as SpanContextShim).getSpanContext();
obecny marked this conversation as resolved.
Show resolved Hide resolved
const oTelSpanCorrelationContext: api.CorrelationContext = (spanContext as 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 +191,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 +202,16 @@ export class TracerShim extends opentracing.Tracer {
switch (format) {
case opentracing.FORMAT_HTTP_HEADERS:
case opentracing.FORMAT_TEXT_MAP: {
const context = getExtractedSpanContext(
const context: api.Context = api.propagation.extract(carrier);
const spanContext = getExtractedSpanContext(context);
const correlationContext = getCorrelationContext(
api.propagation.extract(carrier)
);
if (!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 +229,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.
*/
*
* */
obecny marked this conversation as resolved.
Show resolved Hide resolved
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,
correlationalCtx: api.CorrelationContext
mayurkale22 marked this conversation as resolved.
Show resolved Hide resolved
) {
super();
this._span = span;
this._contextShim = new SpanContextShim(span.context());
this._contextShim = new SpanContextShim(span.context(), correlationalCtx);
mayurkale22 marked this conversation as resolved.
Show resolved Hide resolved
this._tracerShim = tracerShim;
}

Expand Down Expand Up @@ -295,12 +337,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
17 changes: 15 additions & 2 deletions packages/opentelemetry-shim-opentracing/test/Shim.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,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 +190,20 @@ describe('OpenTracing Shim', () => {

it('can set and retrieve baggage', () => {
obecny marked this conversation as resolved.
Show resolved Hide resolved
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 childr baggage item.
assert.equal(span.getBaggageItem('key2'), undefined);
});
});
});