Skip to content
This repository has been archived by the owner on Sep 23, 2024. It is now read-only.

[feat]: add resource labels attribs as span tags and use service.name #6

Merged
merged 1 commit into from
Sep 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,12 @@ function createSpan(
): typeof Span {
// convert to datadog span
const [ddTraceId, ddSpanId, ddParentId] = getTraceContext(span);
const [ddResourceTags, ddResourceServiceName] = getResourceInfo(span);

// generate datadog span base
const ddSpanBase = new Span(NOOP_TRACER, null, SAMPLER, null, {
startTime: hrTimeToMilliseconds(span.startTime),
tags: tags,
tags: Object.assign(tags, ddResourceTags),
operationName: createSpanName(span),
});
const ddSpanBaseContext = ddSpanBase.context();
Expand All @@ -95,7 +96,14 @@ function createSpan(
addSpanType(ddSpanBase, span);

// set datadog specific env and version tags
addDatadogTags(ddSpanBase, span, serviceName, env, version);
addDatadogTags(
ddSpanBase,
span,
serviceName,
env,
version,
ddResourceServiceName
);

// set sampling rate
setSamplingRate(ddSpanBase, span);
Expand Down Expand Up @@ -164,12 +172,13 @@ function addDatadogTags(
span: ReadableSpan,
serviceName?: string | undefined,
env?: string | undefined,
version?: string | undefined
version?: string | undefined,
ddResourceServiceName?: string | undefined
): void {
// set reserved service and resource tags
ddSpanBase.addTags({
[DatadogDefaults.RESOURCE_TAG]: createResource(span),
[DatadogDefaults.SERVICE_TAG]: serviceName,
[DatadogDefaults.SERVICE_TAG]: ddResourceServiceName || serviceName,
});

// set env tag
Expand Down Expand Up @@ -334,3 +343,28 @@ function setSamplingRate(ddSpanBase: typeof Span, span: ReadableSpan): void {
ddSpanBase.setTag(DatadogDefaults.SAMPLE_RATE_METRIC_KEY, samplingRate);
}
}

function getResourceInfo(span: ReadableSpan): any[] {
// extract the resource labels/attributes and potential service name to use for spans
const ddResourceTags: { [key: string]: any } = {};
let resourceServiceName: any;
const resource: any = span.resource;

if (!resource) return [ddResourceTags, resourceServiceName];

const resourceTags: { [key: string]: string | number } | undefined =
resource['labels'] || resource['attributes'];

if (!resourceTags) return [ddResourceTags, resourceServiceName];

// the spec around whether this is labels or attributes varies between versions
for (const [key, value] of Object.entries(resourceTags)) {
if (key === 'service.name') {
resourceServiceName = value.toString();
} else {
ddResourceTags[key] = value.toString();
}
}

return [ddResourceTags, resourceServiceName];
}
55 changes: 53 additions & 2 deletions test/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import * as api from '@opentelemetry/api';
import { Resource } from '@opentelemetry/resources';
import { TraceState } from '@opentelemetry/core';

export const mockResourceServiceName = 'otel-resource-service-name';

export const mockSpanContextUnsampled = {
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
spanId: '6e0c63257de34c92',
Expand Down Expand Up @@ -89,8 +91,57 @@ export const mockExandedReadableSpan: any = {
],
duration: [32, 800000000],
resource: new Resource({
service: 'ui',
version: 1,
zervice: 'ui',
otherInfo: 'one',
cost: 112.12,
}),
instrumentationLibrary: {
name: 'default',
version: '0.0.1',
},
};

export const mockExandedReadableSpanWithResourceService: any = {
name: 'my-span',
kind: api.SpanKind.INTERNAL,
spanContext: mockSpanContextUnsampled,
startTime: [1566156729, 709],
endTime: [1566156731, 709],
ended: true,
status: {
code: api.CanonicalCode.OK,
},
attributes: {
testBool: true,
testString: 'test',
testNum: '3.142',
},
links: [
{
context: {
traceId: 'a4cda95b652f4a1592b449d5929fda1b',
spanId: '3e0c63257de34c92',
},
attributes: {
testBool: true,
testString: 'test',
testNum: 3.142,
},
},
],
events: [
{
name: 'something happened',
attributes: {
error: true,
},
time: [1566156729, 809],
},
],
duration: [32, 800000000],
resource: new Resource({
'service.name': mockResourceServiceName,
otherInfo: 'one',
cost: 112.12,
}),
instrumentationLibrary: {
Expand Down
26 changes: 24 additions & 2 deletions test/transform.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
mockSpanContextSampled,
mockSpanContextOrigin,
mockExandedReadableSpan,
mockExandedReadableSpanWithResourceService,
mockResourceServiceName,
} from './mocks';

describe('transform', () => {
Expand All @@ -36,8 +38,18 @@ describe('transform', () => {
return otelSpans;
};

const generateOtelSpansWithResourceService = function (
options: any
): ReadableSpan[] {
const otelSpans = [];
const span: ReadableSpan = mockExandedReadableSpanWithResourceService;
const updatedSpan = Object.assign(span, options);
otelSpans.push(updatedSpan);
return otelSpans;
};

describe('translateToDatadog', () => {
it('should convert an OpenTelemetry span and its properties to a finished DatadogSpan', () => {
it('should convert an OpenTelemetry span and its properties, including resource info, to a finished DatadogSpan', () => {
const spans = generateOtelSpans({ spanContext: spanContextUnsampled });
const datadogSpans = translateToDatadog(spans, serviceName);
const datadogSpan = datadogSpans[0];
Expand Down Expand Up @@ -66,7 +78,8 @@ describe('transform', () => {
datadogSpan.start,
Math.round(hrTimeToMilliseconds(spans[0].startTime) * 1e6)
);
assert.strictEqual(Object.keys(datadogSpan.meta).length, 4);

assert.strictEqual(Object.keys(datadogSpan.meta).length, 7);
assert.strictEqual(Object.keys(datadogSpan.metrics).length, 1);
assert.strictEqual(
datadogSpan.metrics['_sample_rate'],
Expand Down Expand Up @@ -157,5 +170,14 @@ describe('transform', () => {
const datadogSpan = datadogSpans[0];
assert.strictEqual(datadogSpan.metrics['_sample_rate'], -1);
});

it('should set the resource service.name as dd span service if it exists', () => {
const spans = generateOtelSpansWithResourceService({
spanContext: spanContextSampled,
});
const datadogSpans = translateToDatadog(spans, serviceName);
const datadogSpan = datadogSpans[0];
assert.strictEqual(datadogSpan.service, mockResourceServiceName);
});
});
});