SDK Resource (#846)
* feat: add Resource.empty() method * feat: add resource to BasicTracerProvider and assign to Spans * feat: add Resource.createLibraryResource method * refactor: rename LIBARY_RESOURCE -> TELEMETRY_SDK_RESOURCE * feat: add resource to ReadableSpan interface * feat: add Resource to NodeTracerProvider * feat: add Resource to WebTracerProvider * refactor: move resource-assertions * feat: add Resource to instruments * refactor: add SDK_INFO to core; simplify SDK resource creation * chore: docs and cleanup * docs: no need to update the copyright * chore: move resources to devDependencies where applicable * refactor: add resource to TraceConfig * refactor: add resource to MeterConfig * refactor: change resource visibility on Meter * refactor: move resource-assertions to test/util
This commit is contained in:
parent
69d738c21b
commit
abd191bef3
|
|
@ -3,6 +3,10 @@
|
|||
"version": "0.4.0",
|
||||
"description": "OpenTelemetry base provides base code for the SDK packages",
|
||||
"main": "build/src/index.js",
|
||||
"browser": {
|
||||
"./src/platform/index.ts": "./src/platform/browser/index.ts",
|
||||
"./build/src/platform/index.js": "./build/src/platform/browser/index.js"
|
||||
},
|
||||
"types": "build/src/index.d.ts",
|
||||
"repository": "open-telemetry/opentelemetry-js",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -15,3 +15,4 @@
|
|||
*/
|
||||
|
||||
export * from './ExportResult';
|
||||
export * from './platform';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* Copyright 2020, 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 { VERSION } from '../../version';
|
||||
|
||||
/** Constants describing the SDK in use */
|
||||
export const SDK_INFO = {
|
||||
NAME: 'opentelemetry',
|
||||
RUNTIME: 'browser',
|
||||
LANGUAGE: 'webjs',
|
||||
VERSION: VERSION,
|
||||
};
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/*!
|
||||
* Copyright 2020, 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.
|
||||
*/
|
||||
|
||||
export * from './constants';
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/*!
|
||||
* Copyright 2020, 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.
|
||||
*/
|
||||
|
||||
// Use the node platform by default. The "browser" field of package.json is used
|
||||
// to override this file to use `./browser/index.ts` when packaged with
|
||||
// webpack, Rollup, etc.
|
||||
export * from './node';
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* Copyright 2020, 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 { VERSION } from '../../version';
|
||||
|
||||
/** Constants describing the SDK in use */
|
||||
export const SDK_INFO = {
|
||||
NAME: 'opentelemetry',
|
||||
RUNTIME: 'node',
|
||||
LANGUAGE: 'nodejs',
|
||||
VERSION: VERSION,
|
||||
};
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/*!
|
||||
* Copyright 2020, 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.
|
||||
*/
|
||||
|
||||
export * from './constants';
|
||||
|
|
@ -50,6 +50,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.6.0",
|
||||
"@opentelemetry/resources": "^0.4.0",
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "^12.6.8",
|
||||
"@types/sinon": "^7.0.13",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
import { TraceFlags } from '@opentelemetry/api';
|
||||
import * as core from '@opentelemetry/core';
|
||||
import { ReadableSpan } from '@opentelemetry/tracing';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import * as assert from 'assert';
|
||||
import * as transform from '../src/transform';
|
||||
import * as collectorTypes from '../src/types';
|
||||
|
|
@ -68,6 +69,7 @@ export const mockedReadableSpan: ReadableSpan = {
|
|||
},
|
||||
],
|
||||
duration: [0, 8885000],
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
|
||||
export function ensureSpanIsCorrect(span: collectorTypes.Span) {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@opentelemetry/resources": "^0.4.0",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^12.6.9",
|
||||
"codecov": "^3.6.1",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import { ThriftProcess } from '../src/types';
|
|||
import { ReadableSpan } from '@opentelemetry/tracing';
|
||||
import { ExportResult } from '@opentelemetry/base';
|
||||
import { TraceFlags } from '@opentelemetry/api';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
|
||||
describe('JaegerExporter', () => {
|
||||
describe('constructor', () => {
|
||||
|
|
@ -127,6 +128,7 @@ describe('JaegerExporter', () => {
|
|||
links: [],
|
||||
events: [],
|
||||
duration: [32, 800000000],
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
|
||||
exporter.export([readableSpan], (result: ExportResult) => {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,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 { ThriftUtils, Utils, ThriftReferenceType } from '../src/types';
|
||||
import { hrTimeToMicroseconds } from '@opentelemetry/core';
|
||||
|
|
@ -69,6 +70,7 @@ describe('transform', () => {
|
|||
},
|
||||
],
|
||||
duration: [32, 800000000],
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
|
||||
const thriftSpan = spanToThrift(readableSpan);
|
||||
|
|
@ -143,6 +145,7 @@ describe('transform', () => {
|
|||
links: [],
|
||||
events: [],
|
||||
duration: [32, 800000000],
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
|
||||
const thriftSpan = spanToThrift(readableSpan);
|
||||
|
|
@ -207,6 +210,7 @@ describe('transform', () => {
|
|||
],
|
||||
events: [],
|
||||
duration: [32, 800000000],
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
|
||||
const thriftSpan = spanToThrift(readableSpan);
|
||||
|
|
@ -245,6 +249,7 @@ describe('transform', () => {
|
|||
links: [],
|
||||
events: [],
|
||||
duration: [32, 800000000],
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
|
||||
const thriftSpan = spanToThrift(readableSpan);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@opentelemetry/resources": "^0.4.0",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/nock": "^11.1.0",
|
||||
"@types/node": "^12.6.9",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
import { ExportResult } from '@opentelemetry/base';
|
||||
import { ConsoleLogger, LogLevel } from '@opentelemetry/core';
|
||||
import { ReadableSpan } from '@opentelemetry/tracing';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import * as types from '@opentelemetry/api';
|
||||
import * as assert from 'assert';
|
||||
import * as nock from 'nock';
|
||||
|
|
@ -121,6 +122,7 @@ describe('Stackdriver Trace Exporter', () => {
|
|||
isRemote: true,
|
||||
},
|
||||
status: { code: types.CanonicalCode.OK },
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
|
||||
const result = await new Promise((resolve, reject) => {
|
||||
|
|
@ -155,6 +157,7 @@ describe('Stackdriver Trace Exporter', () => {
|
|||
isRemote: true,
|
||||
},
|
||||
status: { code: types.CanonicalCode.OK },
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
|
||||
getClientShouldFail = true;
|
||||
|
|
@ -188,6 +191,7 @@ describe('Stackdriver Trace Exporter', () => {
|
|||
isRemote: true,
|
||||
},
|
||||
status: { code: types.CanonicalCode.OK },
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
|
||||
batchWriteShouldFail = true;
|
||||
|
|
@ -219,6 +223,7 @@ describe('Stackdriver Trace Exporter', () => {
|
|||
isRemote: true,
|
||||
},
|
||||
status: { code: types.CanonicalCode.OK },
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
|
||||
await exporter['_projectId'];
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
import { VERSION as CORE_VERSION } from '@opentelemetry/core';
|
||||
import { ReadableSpan } from '@opentelemetry/tracing';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import * as types from '@opentelemetry/api';
|
||||
import * as assert from 'assert';
|
||||
import { getReadableSpanTransformer } from '../src/transform';
|
||||
|
|
@ -50,6 +51,7 @@ describe('transform', () => {
|
|||
name: 'my-span',
|
||||
spanContext,
|
||||
status: { code: types.CanonicalCode.OK },
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@opentelemetry/resources": "^0.4.0",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/nock": "^10.0.3",
|
||||
"@types/node": "^12.6.9",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import { ReadableSpan } from '@opentelemetry/tracing';
|
|||
import { ExportResult } from '@opentelemetry/base';
|
||||
import { NoopLogger, hrTimeToMicroseconds } from '@opentelemetry/core';
|
||||
import * as types from '@opentelemetry/api';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import { ZipkinExporter } from '../src';
|
||||
import * as zipkinTypes from '../src/types';
|
||||
import { OT_REQUEST_HEADER } from '../src/utils';
|
||||
|
|
@ -48,6 +49,7 @@ function getReadableSpan() {
|
|||
attributes: {},
|
||||
links: [],
|
||||
events: [],
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
return readableSpan;
|
||||
}
|
||||
|
|
@ -154,6 +156,7 @@ describe('ZipkinExporter', () => {
|
|||
attributes: { key3: 'value3' },
|
||||
},
|
||||
],
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
const span2: ReadableSpan = {
|
||||
name: 'my-span',
|
||||
|
|
@ -173,6 +176,7 @@ describe('ZipkinExporter', () => {
|
|||
attributes: {},
|
||||
links: [],
|
||||
events: [],
|
||||
resource: Resource.empty(),
|
||||
};
|
||||
|
||||
const exporter = new ZipkinExporter({
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
"dependencies": {
|
||||
"@opentelemetry/api": "^0.4.0",
|
||||
"@opentelemetry/base": "^0.4.0",
|
||||
"@opentelemetry/core": "^0.4.0"
|
||||
"@opentelemetry/core": "^0.4.0",
|
||||
"@opentelemetry/resources": "^0.4.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
import * as types from '@opentelemetry/api';
|
||||
import { ConsoleLogger } from '@opentelemetry/core';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import { BaseBoundInstrument } from './BoundInstrument';
|
||||
import { Metric, CounterMetric, MeasureMetric, ObserverMetric } from './Metric';
|
||||
import {
|
||||
|
|
@ -36,6 +37,7 @@ export class Meter implements types.Meter {
|
|||
private readonly _logger: types.Logger;
|
||||
private readonly _metrics = new Map<string, Metric<BaseBoundInstrument>>();
|
||||
private readonly _batcher: Batcher;
|
||||
private readonly _resource: Resource;
|
||||
readonly labels = Meter.labels;
|
||||
|
||||
/**
|
||||
|
|
@ -44,6 +46,7 @@ export class Meter implements types.Meter {
|
|||
constructor(config: MeterConfig = DEFAULT_CONFIG) {
|
||||
this._logger = config.logger || new ConsoleLogger(config.logLevel);
|
||||
this._batcher = new UngroupedBatcher();
|
||||
this._resource = config.resource || Resource.createTelemetrySDKResource();
|
||||
// start the push controller
|
||||
const exporter = config.exporter || new NoopExporter();
|
||||
const interval = config.interval;
|
||||
|
|
@ -73,7 +76,7 @@ export class Meter implements types.Meter {
|
|||
...options,
|
||||
};
|
||||
|
||||
const measure = new MeasureMetric(name, opt, this._batcher);
|
||||
const measure = new MeasureMetric(name, opt, this._batcher, this._resource);
|
||||
this._registerMetric(name, measure);
|
||||
return measure;
|
||||
}
|
||||
|
|
@ -102,7 +105,7 @@ export class Meter implements types.Meter {
|
|||
...DEFAULT_METRIC_OPTIONS,
|
||||
...options,
|
||||
};
|
||||
const counter = new CounterMetric(name, opt, this._batcher);
|
||||
const counter = new CounterMetric(name, opt, this._batcher, this._resource);
|
||||
this._registerMetric(name, counter);
|
||||
return counter;
|
||||
}
|
||||
|
|
@ -129,7 +132,12 @@ export class Meter implements types.Meter {
|
|||
...DEFAULT_METRIC_OPTIONS,
|
||||
...options,
|
||||
};
|
||||
const observer = new ObserverMetric(name, opt, this._batcher);
|
||||
const observer = new ObserverMetric(
|
||||
name,
|
||||
opt,
|
||||
this._batcher,
|
||||
this._resource
|
||||
);
|
||||
this._registerMetric(name, observer);
|
||||
return observer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
import { ConsoleLogger } from '@opentelemetry/core';
|
||||
import * as types from '@opentelemetry/api';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import { Meter } from '.';
|
||||
import { DEFAULT_CONFIG, MeterConfig } from './types';
|
||||
|
||||
|
|
@ -24,6 +25,7 @@ import { DEFAULT_CONFIG, MeterConfig } from './types';
|
|||
*/
|
||||
export class MeterProvider implements types.MeterProvider {
|
||||
private readonly _meters: Map<string, Meter> = new Map();
|
||||
readonly resource: Resource = Resource.createTelemetrySDKResource();
|
||||
readonly logger: types.Logger;
|
||||
|
||||
constructor(private _config: MeterConfig = DEFAULT_CONFIG) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
import * as types from '@opentelemetry/api';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import {
|
||||
BoundCounter,
|
||||
BaseBoundInstrument,
|
||||
|
|
@ -39,7 +40,8 @@ export abstract class Metric<T extends BaseBoundInstrument>
|
|||
constructor(
|
||||
private readonly _name: string,
|
||||
private readonly _options: MetricOptions,
|
||||
private readonly _kind: MetricKind
|
||||
private readonly _kind: MetricKind,
|
||||
readonly resource: Resource
|
||||
) {
|
||||
this._monotonic = _options.monotonic;
|
||||
this._disabled = _options.disabled;
|
||||
|
|
@ -108,9 +110,10 @@ export class CounterMetric extends Metric<BoundCounter>
|
|||
constructor(
|
||||
name: string,
|
||||
options: MetricOptions,
|
||||
private readonly _batcher: Batcher
|
||||
private readonly _batcher: Batcher,
|
||||
resource: Resource
|
||||
) {
|
||||
super(name, options, MetricKind.COUNTER);
|
||||
super(name, options, MetricKind.COUNTER, resource);
|
||||
}
|
||||
protected _makeInstrument(labelSet: types.LabelSet): BoundCounter {
|
||||
return new BoundCounter(
|
||||
|
|
@ -141,9 +144,10 @@ export class MeasureMetric extends Metric<BoundMeasure>
|
|||
constructor(
|
||||
name: string,
|
||||
options: MetricOptions,
|
||||
private readonly _batcher: Batcher
|
||||
private readonly _batcher: Batcher,
|
||||
resource: Resource
|
||||
) {
|
||||
super(name, options, MetricKind.MEASURE);
|
||||
super(name, options, MetricKind.MEASURE, resource);
|
||||
|
||||
this._absolute = options.absolute !== undefined ? options.absolute : true; // Absolute default is true
|
||||
}
|
||||
|
|
@ -172,9 +176,10 @@ export class ObserverMetric extends Metric<BoundObserver>
|
|||
constructor(
|
||||
name: string,
|
||||
options: MetricOptions,
|
||||
private readonly _batcher: Batcher
|
||||
private readonly _batcher: Batcher,
|
||||
resource: Resource
|
||||
) {
|
||||
super(name, options, MetricKind.OBSERVER);
|
||||
super(name, options, MetricKind.OBSERVER, resource);
|
||||
}
|
||||
|
||||
protected _makeInstrument(labelSet: types.LabelSet): BoundObserver {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
import { LogLevel } from '@opentelemetry/core';
|
||||
import { Logger, ValueType } from '@opentelemetry/api';
|
||||
import { MetricExporter } from './export/types';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
|
||||
/** Options needed for SDK metric creation. */
|
||||
export interface MetricOptions {
|
||||
|
|
@ -64,6 +65,9 @@ export interface MeterConfig {
|
|||
|
||||
/** Metric collect interval */
|
||||
interval?: number;
|
||||
|
||||
/** Resource associated with metric telemetry */
|
||||
resource?: Resource;
|
||||
}
|
||||
|
||||
/** Default Meter configuration. */
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import {
|
|||
ObserverAggregator,
|
||||
} from '../src/export/Aggregator';
|
||||
import { ValueType } from '@opentelemetry/api';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
|
||||
describe('Meter', () => {
|
||||
let meter: Meter;
|
||||
|
|
@ -88,6 +89,11 @@ describe('Meter', () => {
|
|||
assert.strictEqual(record1.aggregator.value(), 20);
|
||||
});
|
||||
|
||||
it('should return counter with resource', () => {
|
||||
const counter = meter.createCounter('name') as CounterMetric;
|
||||
assert.ok(counter.resource instanceof Resource);
|
||||
});
|
||||
|
||||
describe('.bind()', () => {
|
||||
it('should create a counter instrument', () => {
|
||||
const counter = meter.createCounter('name') as CounterMetric;
|
||||
|
|
@ -275,6 +281,11 @@ describe('Meter', () => {
|
|||
assert.strictEqual((measure as MeasureMetric)['_absolute'], false);
|
||||
});
|
||||
|
||||
it('should return a measure with resource', () => {
|
||||
const measure = meter.createMeasure('name') as MeasureMetric;
|
||||
assert.ok(measure.resource instanceof Resource);
|
||||
});
|
||||
|
||||
describe('names', () => {
|
||||
it('should return no op metric if name is an empty string', () => {
|
||||
const measure = meter.createMeasure('');
|
||||
|
|
@ -457,6 +468,11 @@ describe('Meter', () => {
|
|||
ensureMetric(metric3);
|
||||
ensureMetric(metric4);
|
||||
});
|
||||
|
||||
it('should return an observer with resource', () => {
|
||||
const observer = meter.createObserver('name') as ObserverMetric;
|
||||
assert.ok(observer.resource instanceof Resource);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getMetrics', () => {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@opentelemetry/resources": "^0.4.0",
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "^12.6.8",
|
||||
"@opentelemetry/scope-base": "^0.4.0",
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import {
|
|||
} from '@opentelemetry/core';
|
||||
import { AsyncHooksScopeManager } from '@opentelemetry/scope-async-hooks';
|
||||
import { Span } from '@opentelemetry/tracing';
|
||||
import { Resource, TELEMETRY_SDK_RESOURCE } from '@opentelemetry/resources';
|
||||
import * as assert from 'assert';
|
||||
import * as path from 'path';
|
||||
import { ScopeManager } from '../../opentelemetry-scope-base/build/src';
|
||||
|
|
@ -158,6 +159,19 @@ describe('NodeTracerProvider', () => {
|
|||
assert.ok(span instanceof Span);
|
||||
assert.deepStrictEqual(span.attributes, defaultAttributes);
|
||||
});
|
||||
|
||||
it('should assign resource to span', () => {
|
||||
provider = new NodeTracerProvider({
|
||||
logger: new NoopLogger(),
|
||||
});
|
||||
const span = provider.getTracer('default').startSpan('my-span') as Span;
|
||||
assert.ok(span);
|
||||
assert.ok(span.resource instanceof Resource);
|
||||
assert.equal(
|
||||
span.resource.labels[TELEMETRY_SDK_RESOURCE.LANGUAGE],
|
||||
'nodejs'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getCurrentSpan()', () => {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
"typescript": "3.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentelemetry/api": "^0.4.0"
|
||||
"@opentelemetry/api": "^0.4.0",
|
||||
"@opentelemetry/base": "^0.4.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,11 +14,34 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SDK_INFO } from '@opentelemetry/base';
|
||||
import { TELEMETRY_SDK_RESOURCE } from './constants';
|
||||
|
||||
/**
|
||||
* A Resource describes the entity for which a signals (metrics or trace) are
|
||||
* collected.
|
||||
*/
|
||||
export class Resource {
|
||||
static readonly EMPTY = new Resource({});
|
||||
|
||||
/**
|
||||
* Returns an empty Resource
|
||||
*/
|
||||
static empty(): Resource {
|
||||
return Resource.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Resource that indentifies the SDK in use.
|
||||
*/
|
||||
static createTelemetrySDKResource(): Resource {
|
||||
return new Resource({
|
||||
[TELEMETRY_SDK_RESOURCE.LANGUAGE]: SDK_INFO.LANGUAGE,
|
||||
[TELEMETRY_SDK_RESOURCE.NAME]: SDK_INFO.NAME,
|
||||
[TELEMETRY_SDK_RESOURCE.VERSION]: SDK_INFO.VERSION,
|
||||
});
|
||||
}
|
||||
|
||||
constructor(
|
||||
/**
|
||||
* A dictionary of labels with string keys and values that provide information
|
||||
|
|
|
|||
|
|
@ -98,15 +98,15 @@ export const K8S_RESOURCE = {
|
|||
};
|
||||
|
||||
/** Attributes describing the telemetry library. */
|
||||
export const LIBRARY_RESOURCE = {
|
||||
export const TELEMETRY_SDK_RESOURCE = {
|
||||
/** The name of the telemetry library. */
|
||||
NAME: 'library.name',
|
||||
NAME: 'telemetry.sdk.name',
|
||||
|
||||
/** The language of telemetry library and of the code instrumented with it. */
|
||||
LANGUAGE: 'library.language',
|
||||
LANGUAGE: 'telemetry.sdk.language',
|
||||
|
||||
/** The version string of the library. */
|
||||
VERSION: 'library.version',
|
||||
/** The version string of the telemetry library */
|
||||
VERSION: 'telemetry.sdk.version',
|
||||
};
|
||||
|
||||
/** Attributes describing a service instance. */
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SDK_INFO } from '@opentelemetry/base';
|
||||
import * as assert from 'assert';
|
||||
import { Resource } from '../src/Resource';
|
||||
import { assertTelemetrySDKResource } from './util/resource-assertions';
|
||||
|
||||
describe('Resource', () => {
|
||||
const resource1 = new Resource({
|
||||
|
|
@ -86,4 +88,26 @@ describe('Resource', () => {
|
|||
assert.equal(resource.labels['custom.number'], 42);
|
||||
assert.equal(resource.labels['custom.boolean'], true);
|
||||
});
|
||||
|
||||
describe('.empty()', () => {
|
||||
it('should return an empty resource', () => {
|
||||
const resource = Resource.empty();
|
||||
assert.equal(Object.entries(resource.labels), 0);
|
||||
});
|
||||
|
||||
it('should return the same empty resource', () => {
|
||||
assert.strictEqual(Resource.empty(), Resource.empty());
|
||||
});
|
||||
});
|
||||
|
||||
describe('.createTelemetrySDKResource()', () => {
|
||||
it('should return a telemetry SDK resource', () => {
|
||||
const resource = Resource.createTelemetrySDKResource();
|
||||
assertTelemetrySDKResource(resource, {
|
||||
language: SDK_INFO.LANGUAGE,
|
||||
name: SDK_INFO.NAME,
|
||||
version: SDK_INFO.VERSION,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,13 +14,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SDK_INFO } from '@opentelemetry/base';
|
||||
import { Resource } from '../src/Resource';
|
||||
import {
|
||||
CLOUD_RESOURCE,
|
||||
CONTAINER_RESOURCE,
|
||||
HOST_RESOURCE,
|
||||
K8S_RESOURCE,
|
||||
LIBRARY_RESOURCE,
|
||||
TELEMETRY_SDK_RESOURCE,
|
||||
SERVICE_RESOURCE,
|
||||
} from '../src/constants';
|
||||
import {
|
||||
|
|
@ -28,7 +29,7 @@ import {
|
|||
assertContainerResource,
|
||||
assertHostResource,
|
||||
assertK8sResource,
|
||||
assertLibraryResource,
|
||||
assertTelemetrySDKResource,
|
||||
assertServiceResource,
|
||||
} from './util/resource-assertions';
|
||||
|
||||
|
|
@ -131,19 +132,23 @@ describe('assertK8sResource', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('assertLibraryResource', () => {
|
||||
it('requires one library label', () => {
|
||||
const resource = new Resource({ [LIBRARY_RESOURCE.NAME]: 'opentelemetry' });
|
||||
assertLibraryResource(resource, {});
|
||||
describe('assertTelemetrySDKResource', () => {
|
||||
it('uses default validations', () => {
|
||||
const resource = new Resource({
|
||||
[TELEMETRY_SDK_RESOURCE.NAME]: SDK_INFO.NAME,
|
||||
[TELEMETRY_SDK_RESOURCE.LANGUAGE]: SDK_INFO.LANGUAGE,
|
||||
[TELEMETRY_SDK_RESOURCE.VERSION]: SDK_INFO.VERSION,
|
||||
});
|
||||
assertTelemetrySDKResource(resource, {});
|
||||
});
|
||||
|
||||
it('validates optional labels', () => {
|
||||
const resource = new Resource({
|
||||
[LIBRARY_RESOURCE.NAME]: 'opentelemetry',
|
||||
[LIBRARY_RESOURCE.LANGUAGE]: 'nodejs',
|
||||
[LIBRARY_RESOURCE.VERSION]: '0.1.0',
|
||||
[TELEMETRY_SDK_RESOURCE.NAME]: 'opentelemetry',
|
||||
[TELEMETRY_SDK_RESOURCE.LANGUAGE]: 'nodejs',
|
||||
[TELEMETRY_SDK_RESOURCE.VERSION]: '0.1.0',
|
||||
});
|
||||
assertLibraryResource(resource, {
|
||||
assertTelemetrySDKResource(resource, {
|
||||
name: 'opentelemetry',
|
||||
language: 'nodejs',
|
||||
version: '0.1.0',
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SDK_INFO } from '@opentelemetry/base';
|
||||
import * as assert from 'assert';
|
||||
import { Resource } from '../../src/Resource';
|
||||
import {
|
||||
|
|
@ -21,9 +22,10 @@ import {
|
|||
CONTAINER_RESOURCE,
|
||||
HOST_RESOURCE,
|
||||
K8S_RESOURCE,
|
||||
LIBRARY_RESOURCE,
|
||||
TELEMETRY_SDK_RESOURCE,
|
||||
SERVICE_RESOURCE,
|
||||
} from '../../src/constants';
|
||||
|
||||
/**
|
||||
* Test utility method to validate a cloud resource
|
||||
*
|
||||
|
|
@ -180,12 +182,12 @@ export const assertK8sResource = (
|
|||
};
|
||||
|
||||
/**
|
||||
* Test utility method to validate a library resource
|
||||
* Test utility method to validate a telemetry sdk resource
|
||||
*
|
||||
* @param resource the Resource to validate
|
||||
* @param validations validations for the resource labels
|
||||
*/
|
||||
export const assertLibraryResource = (
|
||||
export const assertTelemetrySDKResource = (
|
||||
resource: Resource,
|
||||
validations: {
|
||||
name?: string;
|
||||
|
|
@ -193,20 +195,26 @@ export const assertLibraryResource = (
|
|||
version?: string;
|
||||
}
|
||||
) => {
|
||||
assertHasOneLabel(LIBRARY_RESOURCE, resource);
|
||||
const defaults = {
|
||||
name: SDK_INFO.NAME,
|
||||
language: SDK_INFO.LANGUAGE,
|
||||
version: SDK_INFO.VERSION,
|
||||
};
|
||||
validations = { ...defaults, ...validations };
|
||||
|
||||
if (validations.name)
|
||||
assert.strictEqual(
|
||||
resource.labels[LIBRARY_RESOURCE.NAME],
|
||||
resource.labels[TELEMETRY_SDK_RESOURCE.NAME],
|
||||
validations.name
|
||||
);
|
||||
if (validations.language)
|
||||
assert.strictEqual(
|
||||
resource.labels[LIBRARY_RESOURCE.LANGUAGE],
|
||||
resource.labels[TELEMETRY_SDK_RESOURCE.LANGUAGE],
|
||||
validations.language
|
||||
);
|
||||
if (validations.version)
|
||||
assert.strictEqual(
|
||||
resource.labels[LIBRARY_RESOURCE.VERSION],
|
||||
resource.labels[TELEMETRY_SDK_RESOURCE.VERSION],
|
||||
validations.version
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"@opentelemetry/api": "^0.4.0",
|
||||
"@opentelemetry/base": "^0.4.0",
|
||||
"@opentelemetry/core": "^0.4.0",
|
||||
"@opentelemetry/resources": "^0.4.0",
|
||||
"@opentelemetry/scope-base": "^0.4.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import { DEFAULT_CONFIG } from './config';
|
|||
import { MultiSpanProcessor } from './MultiSpanProcessor';
|
||||
import { NoopSpanProcessor } from './NoopSpanProcessor';
|
||||
import { SDKRegistrationConfig, TracerConfig } from './types';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
|
||||
/**
|
||||
* This class represents a basic tracer provider which platform libraries can extend
|
||||
|
|
@ -31,9 +32,11 @@ export class BasicTracerProvider implements api.TracerProvider {
|
|||
|
||||
activeSpanProcessor = new NoopSpanProcessor();
|
||||
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();
|
||||
}
|
||||
|
||||
getTracer(name: string, version = '*', config?: TracerConfig): Tracer {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import {
|
|||
isTimeInput,
|
||||
timeInputToHrTime,
|
||||
} from '@opentelemetry/core';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import { ReadableSpan } from './export/ReadableSpan';
|
||||
import { Tracer } from './Tracer';
|
||||
import { SpanProcessor } from './SpanProcessor';
|
||||
|
|
@ -39,6 +40,7 @@ export class Span implements types.Span, ReadableSpan {
|
|||
readonly links: types.Link[] = [];
|
||||
readonly events: types.TimedEvent[] = [];
|
||||
readonly startTime: types.HrTime;
|
||||
readonly resource: Resource;
|
||||
name: string;
|
||||
status: types.Status = {
|
||||
code: types.CanonicalCode.OK,
|
||||
|
|
@ -66,6 +68,7 @@ export class Span implements types.Span, ReadableSpan {
|
|||
this.kind = kind;
|
||||
this.links = links;
|
||||
this.startTime = timeInputToHrTime(startTime);
|
||||
this.resource = parentTracer.resource;
|
||||
this._logger = parentTracer.logger;
|
||||
this._traceParams = parentTracer.getActiveTraceParams();
|
||||
this._spanProcessor = parentTracer.getActiveSpanProcessor();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import {
|
|||
randomTraceId,
|
||||
setActiveSpan,
|
||||
} from '@opentelemetry/core';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import { BasicTracerProvider } from './BasicTracerProvider';
|
||||
import { DEFAULT_CONFIG } from './config';
|
||||
import { Span } from './Span';
|
||||
|
|
@ -38,6 +39,7 @@ export class Tracer implements api.Tracer {
|
|||
private readonly _defaultAttributes: api.Attributes;
|
||||
private readonly _sampler: api.Sampler;
|
||||
private readonly _traceParams: TraceParams;
|
||||
readonly resource: Resource;
|
||||
readonly logger: api.Logger;
|
||||
|
||||
/**
|
||||
|
|
@ -51,6 +53,7 @@ export class Tracer implements api.Tracer {
|
|||
this._defaultAttributes = localConfig.defaultAttributes;
|
||||
this._sampler = localConfig.sampler;
|
||||
this._traceParams = localConfig.traceParams;
|
||||
this.resource = _tracerProvider.resource;
|
||||
this.logger = config.logger || new ConsoleLogger(config.logLevel);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import {
|
|||
SpanContext,
|
||||
TimedEvent,
|
||||
} from '@opentelemetry/api';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
|
||||
export interface ReadableSpan {
|
||||
readonly name: string;
|
||||
|
|
@ -37,4 +38,5 @@ export interface ReadableSpan {
|
|||
readonly events: TimedEvent[];
|
||||
readonly duration: HrTime;
|
||||
readonly ended: boolean;
|
||||
readonly resource: Resource;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import {
|
|||
} from '@opentelemetry/api';
|
||||
import { LogLevel } from '@opentelemetry/core';
|
||||
import { ScopeManager } from '@opentelemetry/scope-base';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
|
||||
/**
|
||||
* TracerConfig provides an interface for configuring a Basic Tracer.
|
||||
|
|
@ -48,6 +49,9 @@ export interface TracerConfig {
|
|||
|
||||
/** Trace Parameters */
|
||||
traceParams?: TraceParams;
|
||||
|
||||
/** Resource associated with trace telemetry */
|
||||
resource?: Resource;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import {
|
|||
setExtractedSpanContext,
|
||||
TraceState,
|
||||
} from '@opentelemetry/core';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import { NoopScopeManager, ScopeManager } from '@opentelemetry/scope-base';
|
||||
import * as assert from 'assert';
|
||||
import { BasicTracerProvider, Span } from '../src';
|
||||
|
|
@ -305,6 +306,13 @@ describe('BasicTracerProvider', () => {
|
|||
assert.ok(span instanceof Span);
|
||||
assert.deepStrictEqual(span.attributes, defaultAttributes);
|
||||
});
|
||||
|
||||
it('should assign a resource', () => {
|
||||
const tracer = new BasicTracerProvider().getTracer('default');
|
||||
const span = tracer.startSpan('my-span') as Span;
|
||||
assert.ok(span);
|
||||
assert.ok(span.resource instanceof Resource);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getCurrentSpan()', () => {
|
||||
|
|
@ -342,4 +350,11 @@ describe('BasicTracerProvider', () => {
|
|||
return patchedFn();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.resource', () => {
|
||||
it('should return a Resource', () => {
|
||||
const tracerProvider = new BasicTracerProvider();
|
||||
assert.ok(tracerProvider.resource instanceof Resource);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.6.0",
|
||||
"@opentelemetry/resources": "^0.4.0",
|
||||
"@opentelemetry/scope-zone": "^0.4.0",
|
||||
"@types/jquery": "^3.3.31",
|
||||
"@types/mocha": "^5.2.5",
|
||||
|
|
|
|||
|
|
@ -15,10 +15,11 @@
|
|||
*/
|
||||
|
||||
import { context } from '@opentelemetry/api';
|
||||
import { BasePlugin } from '@opentelemetry/core';
|
||||
import { BasePlugin, NoopLogger } from '@opentelemetry/core';
|
||||
import { ScopeManager } from '@opentelemetry/scope-base';
|
||||
import { ZoneScopeManager } from '@opentelemetry/scope-zone';
|
||||
import { Tracer } from '@opentelemetry/tracing';
|
||||
import { Tracer, Span } from '@opentelemetry/tracing';
|
||||
import { Resource, TELEMETRY_SDK_RESOURCE } from '@opentelemetry/resources';
|
||||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import { WebTracerConfig } from '../src';
|
||||
|
|
@ -116,5 +117,20 @@ describe('WebTracerProvider', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.startSpan()', () => {
|
||||
it('should assign resource to span', () => {
|
||||
const provider = new WebTracerProvider({
|
||||
logger: new NoopLogger(),
|
||||
});
|
||||
const span = provider.getTracer('default').startSpan('my-span') as Span;
|
||||
assert.ok(span);
|
||||
assert.ok(span.resource instanceof Resource);
|
||||
assert.equal(
|
||||
span.resource.labels[TELEMETRY_SDK_RESOURCE.LANGUAGE],
|
||||
'webjs'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue