diff --git a/packages/opentelemetry-core/src/common/time.ts b/packages/opentelemetry-core/src/common/time.ts index 13416ca2d79..13fdec0450f 100644 --- a/packages/opentelemetry-core/src/common/time.ts +++ b/packages/opentelemetry-core/src/common/time.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { otperformance as performance } from '../platform'; import { TimeOriginLegacy } from './types'; @@ -25,7 +25,7 @@ const SECOND_TO_NANOSECONDS = Math.pow(10, NANOSECOND_DIGITS); * Converts a number to HrTime * @param epochMillis */ -function numberToHrtime(epochMillis: number): types.HrTime { +function numberToHrtime(epochMillis: number): api.HrTime { const epochSeconds = epochMillis / 1000; // Decimals only. const seconds = Math.trunc(epochSeconds); @@ -49,7 +49,7 @@ function getTimeOrigin(): number { * Returns an hrtime calculated via performance component. * @param performanceNow */ -export function hrTime(performanceNow?: number): types.HrTime { +export function hrTime(performanceNow?: number): api.HrTime { const timeOrigin = numberToHrtime(getTimeOrigin()); const now = numberToHrtime( typeof performanceNow === 'number' ? performanceNow : performance.now() @@ -72,10 +72,10 @@ export function hrTime(performanceNow?: number): types.HrTime { * Converts a TimeInput to an HrTime, defaults to _hrtime(). * @param time */ -export function timeInputToHrTime(time: types.TimeInput): types.HrTime { +export function timeInputToHrTime(time: api.TimeInput): api.HrTime { // process.hrtime if (isTimeInputHrTime(time)) { - return time as types.HrTime; + return time as api.HrTime; } else if (typeof time === 'number') { // Must be a performance.now() if it's smaller than process start time. if (time < getTimeOrigin()) { @@ -97,9 +97,9 @@ export function timeInputToHrTime(time: types.TimeInput): types.HrTime { * @param endTime */ export function hrTimeDuration( - startTime: types.HrTime, - endTime: types.HrTime -): types.HrTime { + startTime: api.HrTime, + endTime: api.HrTime +): api.HrTime { let seconds = endTime[0] - startTime[0]; let nanos = endTime[1] - startTime[1]; @@ -117,7 +117,7 @@ export function hrTimeDuration( * Convert hrTime to timestamp, for example "2019-05-14T17:00:00.000123456Z" * @param hrTime */ -export function hrTimeToTimeStamp(hrTime: types.HrTime): string { +export function hrTimeToTimeStamp(hrTime: api.HrTime): string { const precision = NANOSECOND_DIGITS; const tmp = `${'0'.repeat(precision)}${hrTime[1]}Z`; const nanoString = tmp.substr(tmp.length - precision - 1); @@ -129,7 +129,7 @@ export function hrTimeToTimeStamp(hrTime: types.HrTime): string { * Convert hrTime to nanoseconds. * @param hrTime */ -export function hrTimeToNanoseconds(hrTime: types.HrTime): number { +export function hrTimeToNanoseconds(hrTime: api.HrTime): number { return hrTime[0] * SECOND_TO_NANOSECONDS + hrTime[1]; } @@ -137,7 +137,7 @@ export function hrTimeToNanoseconds(hrTime: types.HrTime): number { * Convert hrTime to milliseconds. * @param hrTime */ -export function hrTimeToMilliseconds(hrTime: types.HrTime): number { +export function hrTimeToMilliseconds(hrTime: api.HrTime): number { return Math.round(hrTime[0] * 1e3 + hrTime[1] / 1e6); } @@ -145,7 +145,7 @@ export function hrTimeToMilliseconds(hrTime: types.HrTime): number { * Convert hrTime to microseconds. * @param hrTime */ -export function hrTimeToMicroseconds(hrTime: types.HrTime): number { +export function hrTimeToMicroseconds(hrTime: api.HrTime): number { return Math.round(hrTime[0] * 1e6 + hrTime[1] / 1e3); } diff --git a/packages/opentelemetry-core/src/context/propagation/B3Propagator.ts b/packages/opentelemetry-core/src/context/propagation/B3Propagator.ts index 9a6f38f67d5..27689c5de9f 100644 --- a/packages/opentelemetry-core/src/context/propagation/B3Propagator.ts +++ b/packages/opentelemetry-core/src/context/propagation/B3Propagator.ts @@ -26,7 +26,7 @@ import { getParentSpanContext, setExtractedSpanContext } from '../context'; export const X_B3_TRACE_ID = 'x-b3-traceid'; export const X_B3_SPAN_ID = 'x-b3-spanid'; export const X_B3_SAMPLED = 'x-b3-sampled'; -const VALID_TRACEID_REGEX = /^[0-9a-f]{32}$/i; +const VALID_TRACEID_REGEX = /^([0-9a-f]{16}){1,2}$/i; const VALID_SPANID_REGEX = /^[0-9a-f]{16}$/i; const INVALID_ID_REGEX = /^0+$/i; @@ -72,16 +72,21 @@ export class B3Propagator implements HttpTextPropagator { const traceIdHeader = getter(carrier, X_B3_TRACE_ID); const spanIdHeader = getter(carrier, X_B3_SPAN_ID); const sampledHeader = getter(carrier, X_B3_SAMPLED); - const traceId = Array.isArray(traceIdHeader) + + const traceIdHeaderValue = Array.isArray(traceIdHeader) ? traceIdHeader[0] : traceIdHeader; const spanId = Array.isArray(spanIdHeader) ? spanIdHeader[0] : spanIdHeader; + const options = Array.isArray(sampledHeader) ? sampledHeader[0] : sampledHeader; - if (typeof traceId !== 'string' || typeof spanId !== 'string') + if (typeof traceIdHeaderValue !== 'string' || typeof spanId !== 'string') { return context; + } + + const traceId = traceIdHeaderValue.padStart(32, '0'); if (isValidTraceId(traceId) && isValidSpanId(spanId)) { return setExtractedSpanContext(context, { diff --git a/packages/opentelemetry-core/src/trace/TraceState.ts b/packages/opentelemetry-core/src/trace/TraceState.ts index cb42e83b64d..951b04964be 100644 --- a/packages/opentelemetry-core/src/trace/TraceState.ts +++ b/packages/opentelemetry-core/src/trace/TraceState.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { validateKey, validateValue } from '../internal/validators'; const MAX_TRACE_STATE_ITEMS = 32; @@ -31,7 +31,7 @@ const LIST_MEMBER_KEY_VALUE_SPLITTER = '='; * - The value of any key can be updated. Modified keys MUST be moved to the * beginning of the list. */ -export class TraceState implements types.TraceState { +export class TraceState implements api.TraceState { private _internalState: Map = new Map(); constructor(rawTraceState?: string) { diff --git a/packages/opentelemetry-core/test/common/time.test.ts b/packages/opentelemetry-core/test/common/time.test.ts index 54bfa6e09e3..07c404c8c98 100644 --- a/packages/opentelemetry-core/test/common/time.test.ts +++ b/packages/opentelemetry-core/test/common/time.test.ts @@ -17,7 +17,7 @@ import * as assert from 'assert'; import { otperformance as performance } from '../../src/platform'; import * as sinon from 'sinon'; -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { hrTime, timeInputToHrTime, @@ -141,16 +141,16 @@ describe('time', () => { describe('#hrTimeDuration', () => { it('should return duration', () => { - const startTime: types.HrTime = [22, 400000000]; - const endTime: types.HrTime = [32, 800000000]; + const startTime: api.HrTime = [22, 400000000]; + const endTime: api.HrTime = [32, 800000000]; const output = hrTimeDuration(startTime, endTime); assert.deepStrictEqual(output, [10, 400000000]); }); it('should handle nanosecond overflow', () => { - const startTime: types.HrTime = [22, 400000000]; - const endTime: types.HrTime = [32, 200000000]; + const startTime: api.HrTime = [22, 400000000]; + const endTime: api.HrTime = [32, 200000000]; const output = hrTimeDuration(startTime, endTime); assert.deepStrictEqual(output, [9, 800000000]); @@ -159,7 +159,7 @@ describe('time', () => { describe('#hrTimeToTimeStamp', () => { it('should return timestamp', () => { - const time: types.HrTime = [1573513121, 123456]; + const time: api.HrTime = [1573513121, 123456]; const output = hrTimeToTimeStamp(time); assert.deepStrictEqual(output, '2019-11-11T22:58:41.000123456Z'); diff --git a/packages/opentelemetry-core/test/context/B3Propagator.test.ts b/packages/opentelemetry-core/test/context/B3Propagator.test.ts index f403bc72a08..7b779c3b949 100644 --- a/packages/opentelemetry-core/test/context/B3Propagator.test.ts +++ b/packages/opentelemetry-core/test/context/B3Propagator.test.ts @@ -289,5 +289,21 @@ describe('B3Propagator', () => { assert.ok(ctx2 === Context.ROOT_CONTEXT); assert.ok(ctx3 === Context.ROOT_CONTEXT); }); + + it('should left-pad 64 bit trace ids with 0', () => { + carrier[X_B3_TRACE_ID] = '8448eb211c80319c'; + carrier[X_B3_SPAN_ID] = 'b7ad6b7169203331'; + carrier[X_B3_SAMPLED] = '1'; + const extractedSpanContext = getExtractedSpanContext( + b3Propagator.extract(Context.ROOT_CONTEXT, carrier, defaultGetter) + ); + + assert.deepStrictEqual(extractedSpanContext, { + spanId: 'b7ad6b7169203331', + traceId: '00000000000000008448eb211c80319c', + isRemote: true, + traceFlags: TraceFlags.SAMPLED, + }); + }); }); }); diff --git a/packages/opentelemetry-exporter-jaeger/src/types.ts b/packages/opentelemetry-exporter-jaeger/src/types.ts index c902cfd3095..45987a2ee7d 100644 --- a/packages/opentelemetry-exporter-jaeger/src/types.ts +++ b/packages/opentelemetry-exporter-jaeger/src/types.ts @@ -14,13 +14,13 @@ * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; /** * Options for Jaeger configuration */ export interface ExporterConfig { - logger?: types.Logger; + logger?: api.Logger; serviceName: string; tags?: Tag[]; host?: string; // default: 'localhost' diff --git a/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts b/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts index 1ff6808a136..9ceaf1bc982 100644 --- a/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts +++ b/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts @@ -17,7 +17,7 @@ import * as assert from 'assert'; import { JaegerExporter } from '../src'; import { ExportResult, NoopLogger } from '@opentelemetry/core'; -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { ThriftProcess } from '../src/types'; import { ReadableSpan } from '@opentelemetry/tracing'; import { TraceFlags } from '@opentelemetry/api'; @@ -130,13 +130,13 @@ describe('JaegerExporter', () => { }; const readableSpan: ReadableSpan = { name: 'my-span1', - kind: types.SpanKind.CLIENT, + kind: api.SpanKind.CLIENT, spanContext, startTime: [1566156729, 709], endTime: [1566156731, 709], ended: true, status: { - code: types.CanonicalCode.DATA_LOSS, + code: api.CanonicalCode.DATA_LOSS, }, attributes: {}, links: [], diff --git a/packages/opentelemetry-exporter-jaeger/test/transform.test.ts b/packages/opentelemetry-exporter-jaeger/test/transform.test.ts index c79fb6d1b65..58477ad0fb4 100644 --- a/packages/opentelemetry-exporter-jaeger/test/transform.test.ts +++ b/packages/opentelemetry-exporter-jaeger/test/transform.test.ts @@ -18,7 +18,7 @@ import * as assert from 'assert'; import { spanToThrift } from '../src/transform'; import { ReadableSpan } from '@opentelemetry/tracing'; import { Resource } from '@opentelemetry/resources'; -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { ThriftUtils, Utils, ThriftReferenceType } from '../src/types'; import { hrTimeToMicroseconds } from '@opentelemetry/core'; import { TraceFlags } from '@opentelemetry/api'; @@ -34,13 +34,13 @@ describe('transform', () => { it('should convert an OpenTelemetry span to a Thrift', () => { const readableSpan: ReadableSpan = { name: 'my-span', - kind: types.SpanKind.INTERNAL, + kind: api.SpanKind.INTERNAL, spanContext, startTime: [1566156729, 709], endTime: [1566156731, 709], ended: true, status: { - code: types.CanonicalCode.OK, + code: api.CanonicalCode.OK, }, attributes: { testBool: true, @@ -155,13 +155,13 @@ describe('transform', () => { it('should convert an OpenTelemetry span to a Thrift when links, events and attributes are empty', () => { const readableSpan: ReadableSpan = { name: 'my-span1', - kind: types.SpanKind.CLIENT, + kind: api.SpanKind.CLIENT, spanContext, startTime: [1566156729, 709], endTime: [1566156731, 709], ended: true, status: { - code: types.CanonicalCode.DATA_LOSS, + code: api.CanonicalCode.DATA_LOSS, message: 'data loss', }, attributes: {}, @@ -213,13 +213,13 @@ describe('transform', () => { it('should convert an OpenTelemetry span to a Thrift with ThriftReference', () => { const readableSpan: ReadableSpan = { name: 'my-span', - kind: types.SpanKind.INTERNAL, + kind: api.SpanKind.INTERNAL, spanContext, startTime: [1566156729, 709], endTime: [1566156731, 709], ended: true, status: { - code: types.CanonicalCode.OK, + code: api.CanonicalCode.OK, }, attributes: {}, parentSpanId: '3e0c63257de34c92', @@ -255,7 +255,7 @@ describe('transform', () => { it('should left pad trace ids', () => { const readableSpan: ReadableSpan = { name: 'my-span1', - kind: types.SpanKind.CLIENT, + kind: api.SpanKind.CLIENT, spanContext: { traceId: '92b449d5929fda1b', spanId: '6e0c63257de34c92', @@ -265,7 +265,7 @@ describe('transform', () => { endTime: [1566156731, 709], ended: true, status: { - code: types.CanonicalCode.DATA_LOSS, + code: api.CanonicalCode.DATA_LOSS, message: 'data loss', }, attributes: {}, diff --git a/packages/opentelemetry-exporter-prometheus/src/export/types.ts b/packages/opentelemetry-exporter-prometheus/src/export/types.ts index bfdc74cc19f..c3a04f5d531 100644 --- a/packages/opentelemetry-exporter-prometheus/src/export/types.ts +++ b/packages/opentelemetry-exporter-prometheus/src/export/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; /** * Configuration interface for prometheus exporter @@ -49,5 +49,5 @@ export interface ExporterConfig { startServer?: boolean; /** Standard logging interface */ - logger?: types.Logger; + logger?: api.Logger; } diff --git a/packages/opentelemetry-exporter-prometheus/src/prometheus.ts b/packages/opentelemetry-exporter-prometheus/src/prometheus.ts index a9a5b2588dc..9e745f62669 100644 --- a/packages/opentelemetry-exporter-prometheus/src/prometheus.ts +++ b/packages/opentelemetry-exporter-prometheus/src/prometheus.ts @@ -29,7 +29,7 @@ import { ObserverAggregator, Sum, } from '@opentelemetry/metrics'; -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { createServer, IncomingMessage, Server, ServerResponse } from 'http'; import { Counter, Gauge, labelValues, Metric, Registry } from 'prom-client'; import * as url from 'url'; @@ -44,7 +44,7 @@ export class PrometheusExporter implements MetricExporter { }; private readonly _registry = new Registry(); - private readonly _logger: types.Logger; + private readonly _logger: api.Logger; private readonly _port: number; private readonly _endpoint: string; private readonly _server: Server; @@ -159,7 +159,7 @@ export class PrometheusExporter implements MetricExporter { // TODO: only counter and gauge are implemented in metrics so far } - private _getLabelValues(keys: string[], labels: types.Labels) { + private _getLabelValues(keys: string[], labels: api.Labels) { const labelValues: labelValues = {}; for (let i = 0; i < keys.length; i++) { if (labels[keys[i]] !== null) { diff --git a/packages/opentelemetry-exporter-zipkin/src/transform.ts b/packages/opentelemetry-exporter-zipkin/src/transform.ts index b52e152f7af..b92d3e2f231 100644 --- a/packages/opentelemetry-exporter-zipkin/src/transform.ts +++ b/packages/opentelemetry-exporter-zipkin/src/transform.ts @@ -14,19 +14,19 @@ * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { ReadableSpan } from '@opentelemetry/tracing'; import { hrTimeToMicroseconds } from '@opentelemetry/core'; import * as zipkinTypes from './types'; import { Resource } from '@opentelemetry/resources'; const ZIPKIN_SPAN_KIND_MAPPING = { - [types.SpanKind.CLIENT]: zipkinTypes.SpanKind.CLIENT, - [types.SpanKind.SERVER]: zipkinTypes.SpanKind.SERVER, - [types.SpanKind.CONSUMER]: zipkinTypes.SpanKind.CONSUMER, - [types.SpanKind.PRODUCER]: zipkinTypes.SpanKind.PRODUCER, + [api.SpanKind.CLIENT]: zipkinTypes.SpanKind.CLIENT, + [api.SpanKind.SERVER]: zipkinTypes.SpanKind.SERVER, + [api.SpanKind.CONSUMER]: zipkinTypes.SpanKind.CONSUMER, + [api.SpanKind.PRODUCER]: zipkinTypes.SpanKind.PRODUCER, // When absent, the span is local. - [types.SpanKind.INTERNAL]: undefined, + [api.SpanKind.INTERNAL]: undefined, }; export const statusCodeTagName = 'ot.status_code'; @@ -68,8 +68,8 @@ export function toZipkinSpan( /** Converts OpenTelemetry Attributes and Status to Zipkin Tags format. */ export function _toZipkinTags( - attributes: types.Attributes, - status: types.Status, + attributes: api.Attributes, + status: api.Status, statusCodeTagName: string, statusDescriptionTagName: string, resource: Resource @@ -78,7 +78,7 @@ export function _toZipkinTags( for (const key of Object.keys(attributes)) { tags[key] = String(attributes[key]); } - tags[statusCodeTagName] = String(types.CanonicalCode[status.code]); + tags[statusCodeTagName] = String(api.CanonicalCode[status.code]); if (status.message) { tags[statusDescriptionTagName] = status.message; } @@ -94,7 +94,7 @@ export function _toZipkinTags( * Converts OpenTelemetry Events to Zipkin Annotations format. */ export function _toZipkinAnnotations( - events: types.TimedEvent[] + events: api.TimedEvent[] ): zipkinTypes.Annotation[] { return events.map(event => ({ timestamp: hrTimeToMicroseconds(event.time), diff --git a/packages/opentelemetry-exporter-zipkin/src/types.ts b/packages/opentelemetry-exporter-zipkin/src/types.ts index 343faf09b64..051673d5829 100644 --- a/packages/opentelemetry-exporter-zipkin/src/types.ts +++ b/packages/opentelemetry-exporter-zipkin/src/types.ts @@ -14,13 +14,13 @@ * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; /** * Exporter config */ export interface ExporterConfig { - logger?: types.Logger; + logger?: api.Logger; serviceName: string; url?: string; // Optional mapping overrides for OpenTelemetry status code and description. diff --git a/packages/opentelemetry-exporter-zipkin/src/zipkin.ts b/packages/opentelemetry-exporter-zipkin/src/zipkin.ts index ca57625fdd2..39906b3d76d 100644 --- a/packages/opentelemetry-exporter-zipkin/src/zipkin.ts +++ b/packages/opentelemetry-exporter-zipkin/src/zipkin.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import * as http from 'http'; import * as https from 'https'; import * as url from 'url'; @@ -32,7 +32,7 @@ import { OT_REQUEST_HEADER } from './utils'; */ export class ZipkinExporter implements SpanExporter { static readonly DEFAULT_URL = 'http://localhost:9411/api/v2/spans'; - private readonly _logger: types.Logger; + private readonly _logger: api.Logger; private readonly _serviceName: string; private readonly _statusCodeTagName: string; private readonly _statusDescriptionTagName: string; diff --git a/packages/opentelemetry-exporter-zipkin/test/transform.test.ts b/packages/opentelemetry-exporter-zipkin/test/transform.test.ts index 6f5854d2e6b..60761e67797 100644 --- a/packages/opentelemetry-exporter-zipkin/test/transform.test.ts +++ b/packages/opentelemetry-exporter-zipkin/test/transform.test.ts @@ -15,7 +15,7 @@ */ import * as assert from 'assert'; -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { Span, BasicTracerProvider } from '@opentelemetry/tracing'; import { NoopLogger, @@ -38,10 +38,10 @@ const tracer = new BasicTracerProvider({ logger, }).getTracer('default'); const parentId = '5c1c63257de34c67'; -const spanContext: types.SpanContext = { +const spanContext: api.SpanContext = { traceId: 'd4cda95b652f4a1592b449d5929fda1b', spanId: '6e0c63257de34c92', - traceFlags: types.TraceFlags.SAMPLED, + traceFlags: api.TraceFlags.SAMPLED, }; const DUMMY_RESOUCE = new Resource({ @@ -57,7 +57,7 @@ describe('transform', () => { tracer, 'my-span', spanContext, - types.SpanKind.SERVER, + api.SpanKind.SERVER, parentId ); span.setAttributes({ @@ -107,7 +107,7 @@ describe('transform', () => { tracer, 'my-span', spanContext, - types.SpanKind.SERVER + api.SpanKind.SERVER ); span.end(); @@ -141,14 +141,14 @@ describe('transform', () => { }); // SpanKind mapping tests [ - { ot: types.SpanKind.CLIENT, zipkin: 'CLIENT' }, - { ot: types.SpanKind.SERVER, zipkin: 'SERVER' }, - { ot: types.SpanKind.CONSUMER, zipkin: 'CONSUMER' }, - { ot: types.SpanKind.PRODUCER, zipkin: 'PRODUCER' }, - { ot: types.SpanKind.INTERNAL, zipkin: undefined }, + { ot: api.SpanKind.CLIENT, zipkin: 'CLIENT' }, + { ot: api.SpanKind.SERVER, zipkin: 'SERVER' }, + { ot: api.SpanKind.CONSUMER, zipkin: 'CONSUMER' }, + { ot: api.SpanKind.PRODUCER, zipkin: 'PRODUCER' }, + { ot: api.SpanKind.INTERNAL, zipkin: undefined }, ].forEach(item => it(`should map OpenTelemetry SpanKind ${ - types.SpanKind[item.ot] + api.SpanKind[item.ot] } to Zipkin ${item.zipkin}`, () => { const span = new Span(tracer, 'my-span', spanContext, item.ot); span.end(); @@ -190,7 +190,7 @@ describe('transform', () => { tracer, 'my-span', spanContext, - types.SpanKind.SERVER, + api.SpanKind.SERVER, parentId ); span.setAttributes({ @@ -219,11 +219,11 @@ describe('transform', () => { tracer, 'my-span', spanContext, - types.SpanKind.SERVER, + api.SpanKind.SERVER, parentId ); - const status: types.Status = { - code: types.CanonicalCode.ABORTED, + const status: api.Status = { + code: api.CanonicalCode.ABORTED, }; span.setStatus(status); span.setAttributes({ @@ -249,11 +249,11 @@ describe('transform', () => { tracer, 'my-span', spanContext, - types.SpanKind.SERVER, + api.SpanKind.SERVER, parentId ); - const status: types.Status = { - code: types.CanonicalCode.ABORTED, + const status: api.Status = { + code: api.CanonicalCode.ABORTED, message: 'my-message', }; span.setStatus(status); @@ -284,7 +284,7 @@ describe('transform', () => { tracer, 'my-span', spanContext, - types.SpanKind.SERVER, + api.SpanKind.SERVER, parentId ); span.addEvent('my-event1'); diff --git a/packages/opentelemetry-exporter-zipkin/test/zipkin.test.ts b/packages/opentelemetry-exporter-zipkin/test/zipkin.test.ts index 6f0c06087a2..2adbca51e58 100644 --- a/packages/opentelemetry-exporter-zipkin/test/zipkin.test.ts +++ b/packages/opentelemetry-exporter-zipkin/test/zipkin.test.ts @@ -22,7 +22,7 @@ import { NoopLogger, hrTimeToMicroseconds, } from '@opentelemetry/core'; -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { Resource } from '@opentelemetry/resources'; import { ZipkinExporter } from '../src'; import * as zipkinTypes from '../src/types'; @@ -36,7 +36,7 @@ function getReadableSpan() { const duration = 2000; const readableSpan: ReadableSpan = { name: 'my-span', - kind: types.SpanKind.INTERNAL, + kind: api.SpanKind.INTERNAL, spanContext: { traceId: 'd4cda95b652f4a1592b449d5929fda1b', spanId: '6e0c63257de34c92', @@ -47,7 +47,7 @@ function getReadableSpan() { ended: true, duration: [duration, 0], status: { - code: types.CanonicalCode.OK, + code: api.CanonicalCode.OK, }, attributes: {}, links: [], @@ -133,7 +133,7 @@ describe('ZipkinExporter', () => { const span1: ReadableSpan = { name: 'my-span', - kind: types.SpanKind.INTERNAL, + kind: api.SpanKind.INTERNAL, parentSpanId, spanContext: { traceId: 'd4cda95b652f4a1592b449d5929fda1b', @@ -145,7 +145,7 @@ describe('ZipkinExporter', () => { ended: true, duration: [duration, 0], status: { - code: types.CanonicalCode.OK, + code: api.CanonicalCode.OK, }, attributes: { key1: 'value1', @@ -163,7 +163,7 @@ describe('ZipkinExporter', () => { }; const span2: ReadableSpan = { name: 'my-span', - kind: types.SpanKind.SERVER, + kind: api.SpanKind.SERVER, spanContext: { traceId: 'd4cda95b652f4a1592b449d5929fda1b', spanId: '6e0c63257de34c92', @@ -174,7 +174,7 @@ describe('ZipkinExporter', () => { ended: true, duration: [duration, 0], status: { - code: types.CanonicalCode.OK, + code: api.CanonicalCode.OK, }, attributes: {}, links: [], diff --git a/packages/opentelemetry-metrics/src/BoundInstrument.ts b/packages/opentelemetry-metrics/src/BoundInstrument.ts index e7db73dd401..94338a29eb4 100644 --- a/packages/opentelemetry-metrics/src/BoundInstrument.ts +++ b/packages/opentelemetry-metrics/src/BoundInstrument.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { Aggregator } from './export/types'; import { ObserverResult } from './ObserverResult'; @@ -23,16 +23,16 @@ import { ObserverResult } from './ObserverResult'; * the TimeSeries. */ export class BaseBoundInstrument { - protected _labels: types.Labels; - protected _logger: types.Logger; + protected _labels: api.Labels; + protected _logger: api.Logger; protected _monotonic: boolean; constructor( - labels: types.Labels, - logger: types.Logger, + labels: api.Labels, + logger: api.Logger, monotonic: boolean, private readonly _disabled: boolean, - private readonly _valueType: types.ValueType, + private readonly _valueType: api.ValueType, private readonly _aggregator: Aggregator ) { this._labels = labels; @@ -43,7 +43,7 @@ export class BaseBoundInstrument { update(value: number): void { if (this._disabled) return; - if (this._valueType === types.ValueType.INT && !Number.isInteger(value)) { + if (this._valueType === api.ValueType.INT && !Number.isInteger(value)) { this._logger.warn( `INT value type cannot accept a floating-point value for ${Object.values( this._labels @@ -55,7 +55,7 @@ export class BaseBoundInstrument { this._aggregator.update(value); } - getLabels(): types.Labels { + getLabels(): api.Labels { return this._labels; } @@ -69,13 +69,13 @@ export class BaseBoundInstrument { * value of single instrument in the `Counter` associated with specified Labels. */ export class BoundCounter extends BaseBoundInstrument - implements types.BoundCounter { + implements api.BoundCounter { constructor( - labels: types.Labels, + labels: api.Labels, disabled: boolean, monotonic: boolean, - valueType: types.ValueType, - logger: types.Logger, + valueType: api.ValueType, + logger: api.Logger, aggregator: Aggregator ) { super(labels, logger, monotonic, disabled, valueType, aggregator); @@ -97,16 +97,16 @@ export class BoundCounter extends BaseBoundInstrument * BoundMeasure is an implementation of the {@link BoundMeasure} interface. */ export class BoundMeasure extends BaseBoundInstrument - implements types.BoundMeasure { + implements api.BoundMeasure { private readonly _absolute: boolean; constructor( - labels: types.Labels, + labels: api.Labels, disabled: boolean, monotonic: boolean, absolute: boolean, - valueType: types.ValueType, - logger: types.Logger, + valueType: api.ValueType, + logger: api.Logger, aggregator: Aggregator ) { super(labels, logger, monotonic, disabled, valueType, aggregator); @@ -115,8 +115,8 @@ export class BoundMeasure extends BaseBoundInstrument record( value: number, - correlationContext?: types.CorrelationContext, - spanContext?: types.SpanContext + correlationContext?: api.CorrelationContext, + spanContext?: api.SpanContext ): void { if (this._absolute && value < 0) { this._logger.error( @@ -135,19 +135,19 @@ export class BoundMeasure extends BaseBoundInstrument * BoundObserver is an implementation of the {@link BoundObserver} interface. */ export class BoundObserver extends BaseBoundInstrument - implements types.BoundObserver { + implements api.BoundObserver { constructor( - labels: types.Labels, + labels: api.Labels, disabled: boolean, monotonic: boolean, - valueType: types.ValueType, - logger: types.Logger, + valueType: api.ValueType, + logger: api.Logger, aggregator: Aggregator ) { super(labels, logger, monotonic, disabled, valueType, aggregator); } - setCallback(callback: (observerResult: types.ObserverResult) => void): void { + setCallback(callback: (observerResult: api.ObserverResult) => void): void { const observerResult = new ObserverResult(); callback(observerResult); } diff --git a/packages/opentelemetry-metrics/src/Meter.ts b/packages/opentelemetry-metrics/src/Meter.ts index 091a96b435d..425af55c20c 100644 --- a/packages/opentelemetry-metrics/src/Meter.ts +++ b/packages/opentelemetry-metrics/src/Meter.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { ConsoleLogger } from '@opentelemetry/core'; import { Resource } from '@opentelemetry/resources'; import { BaseBoundInstrument } from './BoundInstrument'; @@ -32,8 +32,8 @@ import { NoopExporter } from './export/NoopExporter'; /** * Meter is an implementation of the {@link Meter} interface. */ -export class Meter implements types.Meter { - private readonly _logger: types.Logger; +export class Meter implements api.Meter { + private readonly _logger: api.Logger; private readonly _metrics = new Map>(); private readonly _batcher: Batcher; private readonly _resource: Resource; @@ -58,13 +58,13 @@ export class Meter implements types.Meter { */ createMeasure( name: string, - options?: types.MetricOptions - ): types.Metric { + options?: api.MetricOptions + ): api.Metric { if (!this._isValidName(name)) { this._logger.warn( `Invalid metric name ${name}. Defaulting to noop metric implementation.` ); - return types.NOOP_MEASURE_METRIC; + return api.NOOP_MEASURE_METRIC; } const opt: MetricOptions = { absolute: true, // Measures are defined as absolute by default @@ -88,13 +88,13 @@ export class Meter implements types.Meter { */ createCounter( name: string, - options?: types.MetricOptions - ): types.Metric { + options?: api.MetricOptions + ): api.Metric { if (!this._isValidName(name)) { this._logger.warn( `Invalid metric name ${name}. Defaulting to noop metric implementation.` ); - return types.NOOP_COUNTER_METRIC; + return api.NOOP_COUNTER_METRIC; } const opt: MetricOptions = { monotonic: true, // Counters are defined as monotonic by default @@ -115,13 +115,13 @@ export class Meter implements types.Meter { */ createObserver( name: string, - options?: types.MetricOptions - ): types.Metric { + options?: api.MetricOptions + ): api.Metric { if (!this._isValidName(name)) { this._logger.warn( `Invalid metric name ${name}. Defaulting to noop metric implementation.` ); - return types.NOOP_OBSERVER_METRIC; + return api.NOOP_OBSERVER_METRIC; } const opt: MetricOptions = { monotonic: false, // Observers are defined as non-monotonic by default diff --git a/packages/opentelemetry-metrics/src/MeterProvider.ts b/packages/opentelemetry-metrics/src/MeterProvider.ts index 09bd9f8e66a..0315a76e35d 100644 --- a/packages/opentelemetry-metrics/src/MeterProvider.ts +++ b/packages/opentelemetry-metrics/src/MeterProvider.ts @@ -15,7 +15,7 @@ */ import { ConsoleLogger } from '@opentelemetry/core'; -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { Resource } from '@opentelemetry/resources'; import { Meter } from '.'; import { DEFAULT_CONFIG, MeterConfig } from './types'; @@ -23,13 +23,19 @@ import { DEFAULT_CONFIG, MeterConfig } from './types'; /** * This class represents a meter provider which platform libraries can extend */ -export class MeterProvider implements types.MeterProvider { +export class MeterProvider implements api.MeterProvider { + private readonly _config: MeterConfig; private readonly _meters: Map = new Map(); - readonly resource: Resource = Resource.createTelemetrySDKResource(); - readonly logger: types.Logger; + readonly resource: Resource; + readonly logger: api.Logger; - constructor(private _config: MeterConfig = DEFAULT_CONFIG) { - this.logger = _config.logger || new ConsoleLogger(_config.logLevel); + constructor(config: MeterConfig = DEFAULT_CONFIG) { + this.logger = config.logger ?? new ConsoleLogger(config.logLevel); + this.resource = config.resource ?? Resource.createTelemetrySDKResource(); + this._config = Object.assign({}, config, { + logger: this.logger, + resource: this.resource, + }); } /** diff --git a/packages/opentelemetry-metrics/src/Metric.ts b/packages/opentelemetry-metrics/src/Metric.ts index cd666a210e1..0fce307d6ae 100644 --- a/packages/opentelemetry-metrics/src/Metric.ts +++ b/packages/opentelemetry-metrics/src/Metric.ts @@ -35,7 +35,7 @@ export abstract class Metric protected readonly _disabled: boolean; protected readonly _valueType: api.ValueType; protected readonly _logger: api.Logger; - private readonly _descriptor: MetricDescriptor; + protected readonly _descriptor: MetricDescriptor; private readonly _instruments: Map = new Map(); constructor( @@ -124,7 +124,7 @@ export class CounterMetric extends Metric this._valueType, this._logger, // @todo: consider to set to CounterSumAggregator always. - this._batcher.aggregatorFor(MetricKind.COUNTER) + this._batcher.aggregatorFor(this._descriptor) ); } @@ -161,7 +161,7 @@ export class MeasureMetric extends Metric this._absolute, this._valueType, this._logger, - this._batcher.aggregatorFor(MetricKind.MEASURE) + this._batcher.aggregatorFor(this._descriptor) ); } @@ -191,7 +191,7 @@ export class ObserverMetric extends Metric this._monotonic, this._valueType, this._logger, - this._batcher.aggregatorFor(MetricKind.OBSERVER) + this._batcher.aggregatorFor(this._descriptor) ); } diff --git a/packages/opentelemetry-metrics/src/export/Batcher.ts b/packages/opentelemetry-metrics/src/export/Batcher.ts index 2e09a3a0f59..7b2fbd417f5 100644 --- a/packages/opentelemetry-metrics/src/export/Batcher.ts +++ b/packages/opentelemetry-metrics/src/export/Batcher.ts @@ -19,7 +19,12 @@ import { MeasureExactAggregator, ObserverAggregator, } from './aggregators'; -import { MetricRecord, MetricKind, Aggregator } from './types'; +import { + MetricRecord, + MetricKind, + Aggregator, + MetricDescriptor, +} from './types'; /** * Base class for all batcher types. @@ -31,8 +36,8 @@ import { MetricRecord, MetricKind, Aggregator } from './types'; export abstract class Batcher { protected readonly _batchMap = new Map(); - /** Returns an aggregator based off metric kind. */ - abstract aggregatorFor(metricKind: MetricKind): Aggregator; + /** Returns an aggregator based off metric descriptor. */ + abstract aggregatorFor(metricKind: MetricDescriptor): Aggregator; /** Stores record information to be ready for exporting. */ abstract process(record: MetricRecord): void; @@ -47,8 +52,8 @@ export abstract class Batcher { * passes them for exporting. */ export class UngroupedBatcher extends Batcher { - aggregatorFor(metricKind: MetricKind): Aggregator { - switch (metricKind) { + aggregatorFor(metricDescriptor: MetricDescriptor): Aggregator { + switch (metricDescriptor.metricKind) { case MetricKind.COUNTER: return new CounterSumAggregator(); case MetricKind.OBSERVER: diff --git a/packages/opentelemetry-metrics/test/Batcher.test.ts b/packages/opentelemetry-metrics/test/Batcher.test.ts index c09998bd32d..5c2e00b3fbe 100644 --- a/packages/opentelemetry-metrics/test/Batcher.test.ts +++ b/packages/opentelemetry-metrics/test/Batcher.test.ts @@ -15,16 +15,16 @@ */ import * as assert from 'assert'; -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { NoopLogger } from '@opentelemetry/core'; import { Meter, MeterProvider } from '../src'; describe('Batcher', () => { describe('Ungrouped', () => { let meter: Meter; - let fooCounter: types.BoundCounter; - let barCounter: types.BoundCounter; - let counter: types.Metric; + let fooCounter: api.BoundCounter; + let barCounter: api.BoundCounter; + let counter: api.Metric; beforeEach(() => { meter = new MeterProvider({ logger: new NoopLogger(), diff --git a/packages/opentelemetry-metrics/test/Meter.test.ts b/packages/opentelemetry-metrics/test/Meter.test.ts index 7de77a69848..ffa85fe6345 100644 --- a/packages/opentelemetry-metrics/test/Meter.test.ts +++ b/packages/opentelemetry-metrics/test/Meter.test.ts @@ -28,8 +28,9 @@ import { MetricRecord, Aggregator, MetricObservable, + MetricDescriptor, } from '../src'; -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { NoopLogger, hrTime, hrTimeToNanoseconds } from '@opentelemetry/core'; import { CounterSumAggregator, @@ -44,7 +45,7 @@ describe('Meter', () => { let meter: Meter; const keya = 'keya'; const keyb = 'keyb'; - const labels: types.Labels = { [keyb]: 'value2', [keya]: 'value1' }; + const labels: api.Labels = { [keyb]: 'value2', [keya]: 'value1' }; beforeEach(() => { meter = new MeterProvider({ @@ -199,7 +200,7 @@ describe('Meter', () => { // should skip below metric const counter2 = meter.createCounter('name1', { - valueType: types.ValueType.INT, + valueType: api.ValueType.INT, }) as CounterMetric; counter2.bind(labels).add(500); @@ -232,19 +233,19 @@ describe('Meter', () => { it('should return no op metric if name is an empty string', () => { const counter = meter.createCounter(''); - assert.ok(counter instanceof types.NoopMetric); + assert.ok(counter instanceof api.NoopMetric); }); it('should return no op metric if name does not start with a letter', () => { const counter1 = meter.createCounter('1name'); const counter_ = meter.createCounter('_name'); - assert.ok(counter1 instanceof types.NoopMetric); - assert.ok(counter_ instanceof types.NoopMetric); + assert.ok(counter1 instanceof api.NoopMetric); + assert.ok(counter_ instanceof api.NoopMetric); }); it('should return no op metric if name is an empty string contain only letters, numbers, ".", "_", and "-"', () => { const counter = meter.createCounter('name with invalid characters^&*('); - assert.ok(counter instanceof types.NoopMetric); + assert.ok(counter instanceof api.NoopMetric); }); }); }); @@ -291,19 +292,19 @@ describe('Meter', () => { describe('names', () => { it('should return no op metric if name is an empty string', () => { const measure = meter.createMeasure(''); - assert.ok(measure instanceof types.NoopMetric); + assert.ok(measure instanceof api.NoopMetric); }); it('should return no op metric if name does not start with a letter', () => { const measure1 = meter.createMeasure('1name'); const measure_ = meter.createMeasure('_name'); - assert.ok(measure1 instanceof types.NoopMetric); - assert.ok(measure_ instanceof types.NoopMetric); + assert.ok(measure1 instanceof api.NoopMetric); + assert.ok(measure_ instanceof api.NoopMetric); }); it('should return no op metric if name is an empty string contain only letters, numbers, ".", "_", and "-"', () => { const measure = meter.createMeasure('name with invalid characters^&*('); - assert.ok(measure instanceof types.NoopMetric); + assert.ok(measure instanceof api.NoopMetric); }); }); @@ -454,7 +455,7 @@ describe('Meter', () => { const metricObservable = new MetricObservable(); - measure.setCallback((observerResult: types.ObserverResult) => { + measure.setCallback((observerResult: api.ObserverResult) => { observerResult.observe(getCpuUsage, { pid: '123', core: '1' }); observerResult.observe(getCpuUsage, { pid: '123', core: '2' }); observerResult.observe(getCpuUsage, { pid: '123', core: '3' }); @@ -526,7 +527,7 @@ describe('Meter', () => { const counter = meter.createCounter('counter', { description: 'test', labelKeys: [key], - valueType: types.ValueType.INT, + valueType: api.ValueType.INT, }); const labels = { [key]: 'counter-value' }; const boundCounter = counter.bind(labels); @@ -566,7 +567,7 @@ class CustomBatcher extends Batcher { process(record: MetricRecord): void { throw new Error('process method not implemented.'); } - aggregatorFor(metricKind: MetricKind): Aggregator { + aggregatorFor(metricKind: MetricDescriptor): Aggregator { throw new Error('aggregatorFor method not implemented.'); } } diff --git a/packages/opentelemetry-metrics/test/MeterProvider.test.ts b/packages/opentelemetry-metrics/test/MeterProvider.test.ts index 82877759b36..45c54db6bb7 100644 --- a/packages/opentelemetry-metrics/test/MeterProvider.test.ts +++ b/packages/opentelemetry-metrics/test/MeterProvider.test.ts @@ -15,7 +15,7 @@ */ import * as assert from 'assert'; -import { MeterProvider, Meter } from '../src'; +import { MeterProvider, Meter, CounterMetric } from '../src'; import { NoopLogger } from '@opentelemetry/core'; describe('MeterProvider', () => { @@ -39,6 +39,14 @@ describe('MeterProvider', () => { assert.ok(meter instanceof Meter); }); + it('should propagate resources', () => { + const meterProvider = new MeterProvider(); + const meter = meterProvider.getMeter('test-meter-provider'); + const counter = meter.createCounter('test-counter') as CounterMetric; + assert.strictEqual((meter as any)._resource, meterProvider.resource); + assert.strictEqual(counter.resource, meterProvider.resource); + }); + it('should return the meter with default version without a version option', () => { const provider = new MeterProvider(); const meter1 = provider.getMeter('default'); diff --git a/packages/opentelemetry-plugin-https/test/functionals/https-disable.test.ts b/packages/opentelemetry-plugin-https/test/functionals/https-disable.test.ts index 572ea6ea1a9..d323be77ba7 100644 --- a/packages/opentelemetry-plugin-https/test/functionals/https-disable.test.ts +++ b/packages/opentelemetry-plugin-https/test/functionals/https-disable.test.ts @@ -25,7 +25,7 @@ import * as sinon from 'sinon'; import { plugin } from '../../src/https'; import { httpsRequest } from '../utils/httpsRequest'; import { NodeTracerProvider } from '@opentelemetry/node'; -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; describe('HttpsPlugin', () => { let server: https.Server; @@ -37,7 +37,7 @@ describe('HttpsPlugin', () => { logger, }); // const tracer = provider.getTracer('test-https') - let tracer: types.Tracer; + let tracer: api.Tracer; before(() => { nock.cleanAll(); nock.enableNetConnect(); diff --git a/packages/opentelemetry-plugin-xml-http-request/src/types.ts b/packages/opentelemetry-plugin-xml-http-request/src/types.ts index c8b36457cf4..0fb63f676ac 100644 --- a/packages/opentelemetry-plugin-xml-http-request/src/types.ts +++ b/packages/opentelemetry-plugin-xml-http-request/src/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; /** * method "open" from XMLHttpRequest @@ -51,11 +51,11 @@ export interface XhrMem { status?: number; statusText?: string; // span assigned to xhr - span: types.Span; + span: api.Span; // span url - not available on types.Span spanUrl?: string; // startTime of send function - used to filter cors preflight requests - sendStartTime?: types.HrTime; + sendStartTime?: api.HrTime; // resources created between send and end plus some additional timeout createdResources?: { observer: PerformanceObserver; diff --git a/packages/opentelemetry-plugin-xml-http-request/test/xhr.test.ts b/packages/opentelemetry-plugin-xml-http-request/test/xhr.test.ts index 270762ca216..08b0b209eea 100644 --- a/packages/opentelemetry-plugin-xml-http-request/test/xhr.test.ts +++ b/packages/opentelemetry-plugin-xml-http-request/test/xhr.test.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { B3Propagator, LogLevel, @@ -101,23 +101,23 @@ describe('xhr', () => { beforeEach(() => { contextManager = new ZoneContextManager().enable(); - types.context.setGlobalContextManager(contextManager); + api.context.setGlobalContextManager(contextManager); }); afterEach(() => { - types.context.disable(); + api.context.disable(); }); before(() => { - types.propagation.setGlobalPropagator(new B3Propagator()); + api.propagation.setGlobalPropagator(new B3Propagator()); }); describe('when request is successful', () => { - let webTracerWithZone: types.Tracer; + let webTracerWithZone: api.Tracer; let webTracerProviderWithZone: WebTracerProvider; let dummySpanExporter: DummySpanExporter; let exportSpy: any; - let rootSpan: types.Span; + let rootSpan: api.Span; let spyEntries: any; const url = `${window.location.origin}/xml-http-request.js`; let fakeNow = 0; @@ -212,11 +212,7 @@ describe('xhr', () => { it('span should have correct kind', () => { const span: tracing.ReadableSpan = exportSpy.args[0][0][0]; - assert.strictEqual( - span.kind, - types.SpanKind.CLIENT, - 'span has wrong kind' - ); + assert.strictEqual(span.kind, api.SpanKind.CLIENT, 'span has wrong kind'); }); it('span should have correct attributes', () => { @@ -335,7 +331,7 @@ describe('xhr', () => { describe('AND origin match with window.location', () => { it('should set trace headers', () => { - const span: types.Span = exportSpy.args[0][0][0]; + const span: api.Span = exportSpy.args[0][0][0]; assert.strictEqual( requests[0].requestHeaders[X_B3_TRACE_ID], span.context().traceId, @@ -367,7 +363,7 @@ describe('xhr', () => { ); }); it('should set trace headers', () => { - const span: types.Span = exportSpy.args[0][0][0]; + const span: api.Span = exportSpy.args[0][0][0]; assert.strictEqual( requests[0].requestHeaders[X_B3_TRACE_ID], span.context().traceId, @@ -420,10 +416,10 @@ describe('xhr', () => { describe('when request is NOT successful', () => { let webTracerWithZoneProvider: WebTracerProvider; - let webTracerWithZone: types.Tracer; + let webTracerWithZone: api.Tracer; let dummySpanExporter: DummySpanExporter; let exportSpy: any; - let rootSpan: types.Span; + let rootSpan: api.Span; let spyEntries: any; const url = 'https://raw.githubusercontent.com/open-telemetry/opentelemetry-js/master/package.json'; diff --git a/packages/opentelemetry-tracing/src/BasicTracerProvider.ts b/packages/opentelemetry-tracing/src/BasicTracerProvider.ts index fe44199e617..375f998aa75 100644 --- a/packages/opentelemetry-tracing/src/BasicTracerProvider.ts +++ b/packages/opentelemetry-tracing/src/BasicTracerProvider.ts @@ -27,6 +27,7 @@ import { Resource } from '@opentelemetry/resources'; * This class represents a basic tracer provider which platform libraries can extend */ export class BasicTracerProvider implements api.TracerProvider { + private readonly _config: TracerConfig; private readonly _registeredSpanProcessors: SpanProcessor[] = []; private readonly _tracers: Map = new Map(); @@ -34,9 +35,13 @@ export class BasicTracerProvider implements api.TracerProvider { readonly logger: api.Logger; readonly resource: Resource; - constructor(private _config: TracerConfig = DEFAULT_CONFIG) { - this.logger = _config.logger || new ConsoleLogger(_config.logLevel); - this.resource = _config.resource || Resource.createTelemetrySDKResource(); + constructor(config: TracerConfig = DEFAULT_CONFIG) { + this.logger = config.logger ?? new ConsoleLogger(config.logLevel); + this.resource = config.resource ?? Resource.createTelemetrySDKResource(); + this._config = Object.assign({}, config, { + logger: this.logger, + resource: this.resource, + }); } getTracer(name: string, version = '*', config?: TracerConfig): Tracer { diff --git a/packages/opentelemetry-tracing/src/Span.ts b/packages/opentelemetry-tracing/src/Span.ts index 4028564a4d0..c2f08461d5a 100644 --- a/packages/opentelemetry-tracing/src/Span.ts +++ b/packages/opentelemetry-tracing/src/Span.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { hrTime, hrTimeDuration, @@ -30,25 +30,25 @@ import { TraceParams } from './types'; /** * This class represents a span. */ -export class Span implements types.Span, ReadableSpan { +export class Span implements api.Span, ReadableSpan { // Below properties are included to implement ReadableSpan for export // purposes but are not intended to be written-to directly. - readonly spanContext: types.SpanContext; - readonly kind: types.SpanKind; + readonly spanContext: api.SpanContext; + readonly kind: api.SpanKind; readonly parentSpanId?: string; - readonly attributes: types.Attributes = {}; - readonly links: types.Link[] = []; - readonly events: types.TimedEvent[] = []; - readonly startTime: types.HrTime; + readonly attributes: api.Attributes = {}; + readonly links: api.Link[] = []; + readonly events: api.TimedEvent[] = []; + readonly startTime: api.HrTime; readonly resource: Resource; name: string; - status: types.Status = { - code: types.CanonicalCode.OK, + status: api.Status = { + code: api.CanonicalCode.OK, }; - endTime: types.HrTime = [0, 0]; + endTime: api.HrTime = [0, 0]; private _ended = false; - private _duration: types.HrTime = [-1, -1]; - private readonly _logger: types.Logger; + private _duration: api.HrTime = [-1, -1]; + private readonly _logger: api.Logger; private readonly _spanProcessor: SpanProcessor; private readonly _traceParams: TraceParams; @@ -56,11 +56,11 @@ export class Span implements types.Span, ReadableSpan { constructor( parentTracer: Tracer, spanName: string, - spanContext: types.SpanContext, - kind: types.SpanKind, + spanContext: api.SpanContext, + kind: api.SpanKind, parentSpanId?: string, - links: types.Link[] = [], - startTime: types.TimeInput = hrTime() + links: api.Link[] = [], + startTime: api.TimeInput = hrTime() ) { this.name = spanName; this.spanContext = spanContext; @@ -75,7 +75,7 @@ export class Span implements types.Span, ReadableSpan { this._spanProcessor.onStart(this); } - context(): types.SpanContext { + context(): api.SpanContext { return this.spanContext; } @@ -98,7 +98,7 @@ export class Span implements types.Span, ReadableSpan { return this; } - setAttributes(attributes: types.Attributes): this { + setAttributes(attributes: api.Attributes): this { Object.keys(attributes).forEach(key => { this.setAttribute(key, attributes[key]); }); @@ -114,8 +114,8 @@ export class Span implements types.Span, ReadableSpan { */ addEvent( name: string, - attributesOrStartTime?: types.Attributes | types.TimeInput, - startTime?: types.TimeInput + attributesOrStartTime?: api.Attributes | api.TimeInput, + startTime?: api.TimeInput ): this { if (this._isSpanEnded()) return this; if (this.events.length >= this._traceParams.numberOfEventsPerSpan!) { @@ -124,7 +124,7 @@ export class Span implements types.Span, ReadableSpan { } if (isTimeInput(attributesOrStartTime)) { if (typeof startTime === 'undefined') { - startTime = attributesOrStartTime as types.TimeInput; + startTime = attributesOrStartTime as api.TimeInput; } attributesOrStartTime = undefined; } @@ -133,13 +133,13 @@ export class Span implements types.Span, ReadableSpan { } this.events.push({ name, - attributes: attributesOrStartTime as types.Attributes, + attributes: attributesOrStartTime as api.Attributes, time: timeInputToHrTime(startTime), }); return this; } - setStatus(status: types.Status): this { + setStatus(status: api.Status): this { if (this._isSpanEnded()) return this; this.status = status; return this; @@ -151,7 +151,7 @@ export class Span implements types.Span, ReadableSpan { return this; } - end(endTime: types.TimeInput = hrTime()): void { + end(endTime: api.TimeInput = hrTime()): void { if (this._isSpanEnded()) { this._logger.error('You can only call end() on a span once.'); return; @@ -179,7 +179,7 @@ export class Span implements types.Span, ReadableSpan { return this; } - get duration(): types.HrTime { + get duration(): api.HrTime { return this._duration; } diff --git a/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts b/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts index 4b38b090462..6de7339798d 100644 --- a/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts +++ b/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts @@ -121,6 +121,14 @@ describe('BasicTracerProvider', () => { assert.ok(span instanceof Span); }); + it('should propagate resources', () => { + const tracerProvider = new BasicTracerProvider(); + const tracer = tracerProvider.getTracer('default'); + const span = tracer.startSpan('my-span') as Span; + assert.strictEqual(tracer.resource, tracerProvider.resource); + assert.strictEqual(span.resource, tracerProvider.resource); + }); + it('should start a span with name and options', () => { const tracer = new BasicTracerProvider().getTracer('default'); const span = tracer.startSpan('my-span', {}); diff --git a/packages/opentelemetry-web/src/utils.ts b/packages/opentelemetry-web/src/utils.ts index 0beec8d9f0b..e5a3cd43fed 100644 --- a/packages/opentelemetry-web/src/utils.ts +++ b/packages/opentelemetry-web/src/utils.ts @@ -16,7 +16,7 @@ import { PerformanceEntries, PerformanceResourceTimingInfo } from './types'; import { PerformanceTimingNames as PTN } from './enums/PerformanceTimingNames'; -import * as types from '@opentelemetry/api'; +import * as api from '@opentelemetry/api'; import { hrTimeToNanoseconds, timeInputToHrTime } from '@opentelemetry/core'; /** @@ -35,10 +35,10 @@ export function hasKey(obj: O, key: keyof any): key is keyof O { * @param entries */ export function addSpanNetworkEvent( - span: types.Span, + span: api.Span, performanceName: string, entries: PerformanceEntries -): types.Span | undefined { +): api.Span | undefined { if ( hasKey(entries, performanceName) && typeof entries[performanceName] === 'number' @@ -82,8 +82,8 @@ export function sortResources(filteredResources: PerformanceResourceTiming[]) { */ export function getResource( spanUrl: string, - startTimeHR: types.HrTime, - endTimeHR: types.HrTime, + startTimeHR: api.HrTime, + endTimeHR: api.HrTime, resources: PerformanceResourceTiming[], ignoredResources: WeakSet = new WeakSet< PerformanceResourceTiming @@ -147,7 +147,7 @@ export function getResource( function findMainRequest( resources: PerformanceResourceTiming[], corsPreFlightRequestEndTime: number, - spanEndTimeHR: types.HrTime + spanEndTimeHR: api.HrTime ): PerformanceResourceTiming { const spanEndTime = hrTimeToNanoseconds(spanEndTimeHR); const minTime = hrTimeToNanoseconds( @@ -189,8 +189,8 @@ function findMainRequest( */ function filterResourcesForSpan( spanUrl: string, - startTimeHR: types.HrTime, - endTimeHR: types.HrTime, + startTimeHR: api.HrTime, + endTimeHR: api.HrTime, resources: PerformanceResourceTiming[], ignoredResources: WeakSet ) {