diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d94358c94e..a7c43c82fdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,6 +93,11 @@ For semantic convention package changes, see the [semconv CHANGELOG](packages/se * (user-facing): `baggageUtils.parsePairKeyValue` was an internal utility function that was unintentionally exported. It has been removed without replacement. * (user-facing): `TimeOriginLegacy` has been removed without replacement. * (user-facing): `isAttributeKey` was an internal utility function that was unintentionally exported. It has been removed without replacement. +* feat(resource)!: Remove resource class export in favor of functions and types only to aid in cross-version compatibility [#5421](https://github.com/open-telemetry/opentelemetry-js/pull/5421) + * Renames `Resource` class to `ResourceImpl` and makes it package-private + * Renames `IResource` interface to `Resource` + * Export function `resourceFromAttributes` to create a `Resource` from a `DetectedAttributes` object + * Only export types and functions. This aids in cross-version compatibility and makes it more easily extensible in the future. ### :rocket: (Enhancement) diff --git a/README.md b/README.md index 37286a8ac06..9e1bac97b2a 100644 --- a/README.md +++ b/README.md @@ -75,14 +75,14 @@ const process = require('process'); const opentelemetry = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node'); const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-base'); -const { Resource } = require('@opentelemetry/resources'); +const { resourceFromAttributes } = require('@opentelemetry/resources'); const { SEMRESATTRS_SERVICE_NAME } = require('@opentelemetry/semantic-conventions'); // configure the SDK to export telemetry data to the console // enable all auto-instrumentations from the meta package const traceExporter = new ConsoleSpanExporter(); const sdk = new opentelemetry.NodeSDK({ - resource: new Resource({ + resource: resourceFromAttributes({ [SEMRESATTRS_SERVICE_NAME]: 'my-service', }), traceExporter, diff --git a/experimental/packages/opentelemetry-browser-detector/README.md b/experimental/packages/opentelemetry-browser-detector/README.md index bc0d0ad8a54..8dd0ec44a88 100644 --- a/experimental/packages/opentelemetry-browser-detector/README.md +++ b/experimental/packages/opentelemetry-browser-detector/README.md @@ -13,12 +13,12 @@ npm install --save @opentelemetry/opentelemetry-browser-detector ## Usage ```js -import { Resource, detectResources } from '@opentelemetry/resources'; +import { resourceFromAttributes, detectResources } from '@opentelemetry/resources'; import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; import { browserDetector } from '@opentelemetry/opentelemetry-browser-detector'; async function start(){ - let resource= new Resource({ + let resource = resourceFromAttributes({ [SEMRESATTRS_SERVICE_NAME]: 'Test App Name', }); let detectedResources= await detectResources({detectors:[browserDetector]}); diff --git a/experimental/packages/opentelemetry-browser-detector/src/BrowserDetector.ts b/experimental/packages/opentelemetry-browser-detector/src/BrowserDetector.ts index 84a60045e26..b1debc0cfef 100644 --- a/experimental/packages/opentelemetry-browser-detector/src/BrowserDetector.ts +++ b/experimental/packages/opentelemetry-browser-detector/src/BrowserDetector.ts @@ -18,8 +18,8 @@ import { Attributes, diag } from '@opentelemetry/api'; import { DetectedResource, ResourceDetector, - Resource, ResourceDetectionConfig, + EMPTY_RESOURCE, } from '@opentelemetry/resources'; import { BROWSER_ATTRIBUTES, UserAgentData } from './types'; @@ -30,7 +30,7 @@ class BrowserDetector implements ResourceDetector { detect(config?: ResourceDetectionConfig): DetectedResource { const isBrowser = typeof navigator !== 'undefined'; if (!isBrowser) { - return Resource.EMPTY; + return EMPTY_RESOURCE; } const browserResource: Attributes = getBrowserAttributes(); return this._getResourceAttributes(browserResource, config); @@ -53,7 +53,7 @@ class BrowserDetector implements ResourceDetector { diag.debug( 'BrowserDetector failed: Unable to find required browser resources. ' ); - return Resource.EMPTY; + return EMPTY_RESOURCE; } else { return { attributes: browserResource }; } diff --git a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts index c29cb22b639..04e2f5a6174 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts @@ -24,7 +24,7 @@ import { Histogram, } from '@opentelemetry/sdk-metrics'; import { hrTimeToMilliseconds } from '@opentelemetry/core'; -import { IResource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; type PrometheusDataTypeLiteral = | 'counter' @@ -324,7 +324,7 @@ export class PrometheusSerializer { return results; } - protected _serializeResource(resource: IResource): string { + protected _serializeResource(resource: Resource): string { const name = 'target_info'; const help = `# HELP ${name} Target metadata`; const type = `# TYPE ${name} gauge`; diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts index e4303ddc5f8..73ab372274a 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts @@ -34,7 +34,7 @@ import { sdkVersion, serviceName, } from './util'; -import { Resource } from '@opentelemetry/resources'; +import { resourceFromAttributes } from '@opentelemetry/resources'; import { AggregationType } from '@opentelemetry/sdk-metrics'; const attributes = { @@ -703,14 +703,12 @@ describe('PrometheusSerializer', () => { it('should serialize resource', () => { const serializer = new PrometheusSerializer(undefined, true); const result = serializer['_serializeResource']( - new Resource({ - attributes: { - env: 'prod', - hostname: 'myhost', - datacenter: 'sdc', - region: 'europe', - owner: 'frontend', - }, + resourceFromAttributes({ + env: 'prod', + hostname: 'myhost', + datacenter: 'sdc', + region: 'europe', + owner: 'frontend', }) ); diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/util.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/util.ts index 7f3cea9a1bd..fa75016e4ba 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/util.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/util.ts @@ -15,7 +15,7 @@ */ import * as sinon from 'sinon'; -import { Resource } from '@opentelemetry/resources'; +import { DEFAULT_RESOURCE } from '@opentelemetry/resources'; import { SEMRESATTRS_SERVICE_NAME, SEMRESATTRS_TELEMETRY_SDK_LANGUAGE, @@ -29,19 +29,23 @@ export function mockHrTime() { sinon.useFakeTimers(mockedHrTimeMs); } -export const serviceName = Resource.default() - .attributes[SEMRESATTRS_SERVICE_NAME]?.toString() +export const serviceName = DEFAULT_RESOURCE.attributes[ + SEMRESATTRS_SERVICE_NAME +]?.toString() .replace(/\\/g, '\\\\') .replace(/\n/g, '\\n'); -export const sdkLanguage = Resource.default() - .attributes[SEMRESATTRS_TELEMETRY_SDK_LANGUAGE]?.toString() +export const sdkLanguage = DEFAULT_RESOURCE.attributes[ + SEMRESATTRS_TELEMETRY_SDK_LANGUAGE +]?.toString() .replace(/\\/g, '\\\\') .replace(/\n/g, '\\n'); -export const sdkName = Resource.default() - .attributes[SEMRESATTRS_TELEMETRY_SDK_NAME]?.toString() +export const sdkName = DEFAULT_RESOURCE.attributes[ + SEMRESATTRS_TELEMETRY_SDK_NAME +]?.toString() .replace(/\\/g, '\\\\') .replace(/\n/g, '\\n'); -export const sdkVersion = Resource.default() - .attributes[SEMRESATTRS_TELEMETRY_SDK_VERSION]?.toString() +export const sdkVersion = DEFAULT_RESOURCE.attributes[ + SEMRESATTRS_TELEMETRY_SDK_VERSION +]?.toString() .replace(/\\/g, '\\\\') .replace(/\n/g, '\\n'); diff --git a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts index 1629d45e8f5..bfbfa92877a 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts @@ -27,14 +27,15 @@ import { registerInstrumentations, } from '@opentelemetry/instrumentation'; import { + DEFAULT_RESOURCE, detectResources, envDetector, hostDetector, - IResource, - processDetector, Resource, + processDetector, ResourceDetectionConfig, ResourceDetector, + resourceFromAttributes, } from '@opentelemetry/resources'; import { LogRecordProcessor, @@ -208,7 +209,7 @@ export class NodeSDK { private _meterProviderConfig?: MeterProviderConfig; private _instrumentations: Instrumentation[]; - private _resource: IResource; + private _resource: Resource; private _resourceDetectors: Array; private _autoDetectResources: boolean; @@ -244,7 +245,7 @@ export class NodeSDK { this._configuration = configuration; - this._resource = configuration.resource ?? Resource.default(); + this._resource = configuration.resource ?? DEFAULT_RESOURCE; this._autoDetectResources = configuration.autoDetectResources ?? true; if (!this._autoDetectResources) { this._resourceDetectors = []; @@ -352,10 +353,8 @@ export class NodeSDK { this._serviceName === undefined ? this._resource : this._resource.merge( - new Resource({ - attributes: { - [ATTR_SERVICE_NAME]: this._serviceName, - }, + resourceFromAttributes({ + [ATTR_SERVICE_NAME]: this._serviceName, }) ); diff --git a/experimental/packages/opentelemetry-sdk-node/src/types.ts b/experimental/packages/opentelemetry-sdk-node/src/types.ts index 3d62258799c..ff400de8f21 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/types.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/types.ts @@ -17,7 +17,7 @@ import type { ContextManager } from '@opentelemetry/api'; import { TextMapPropagator } from '@opentelemetry/api'; import { Instrumentation } from '@opentelemetry/instrumentation'; -import { IResource, ResourceDetector } from '@opentelemetry/resources'; +import { Resource, ResourceDetector } from '@opentelemetry/resources'; import { LogRecordProcessor } from '@opentelemetry/sdk-logs'; import { IMetricReader, ViewOptions } from '@opentelemetry/sdk-metrics'; import { @@ -38,7 +38,7 @@ export interface NodeSDKConfiguration { metricReader: IMetricReader; views: ViewOptions[]; instrumentations: (Instrumentation | Instrumentation[])[]; - resource: IResource; + resource: Resource; resourceDetectors: Array; sampler: Sampler; serviceName?: string; diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index e7e12d6cc5a..2c16a3ed5c9 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -64,9 +64,9 @@ import { envDetector, processDetector, hostDetector, - Resource, serviceInstanceIdDetector, DetectedResource, + DEFAULT_RESOURCE, } from '@opentelemetry/resources'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { logs, ProxyLoggerProvider } from '@opentelemetry/api-logs'; @@ -956,7 +956,7 @@ describe('Node SDK', () => { const resource = sdk['_resource']; await resource.waitForAsyncAttributes?.(); - assert.deepStrictEqual(resource, Resource.default()); + assert.deepStrictEqual(resource, DEFAULT_RESOURCE); await sdk.shutdown(); }); }); diff --git a/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts b/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts index 2b0221d3c77..fa4a1bfd9f3 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts @@ -16,7 +16,7 @@ import { SDK_INFO } from '@opentelemetry/core'; import * as assert from 'assert'; -import { IResource, Resource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; import { SEMRESATTRS_CLOUD_ACCOUNT_ID, SEMRESATTRS_CLOUD_AVAILABILITY_ZONE, @@ -260,7 +260,7 @@ export const assertTelemetrySDKResource = ( * @param validations validations for the resource attributes */ export const assertServiceResource = ( - resource: IResource, + resource: Resource, validations: { name: string; instanceId?: string; @@ -362,7 +362,7 @@ const assertHasOneLabel = (prefix: string, resource: Resource): void => { ); }; -export const assertServiceInstanceIdIsUUID = (resource: IResource): void => { +export const assertServiceInstanceIdIsUUID = (resource: Resource): void => { const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; assert.equal( diff --git a/experimental/packages/otlp-transformer/src/common/internal-types.ts b/experimental/packages/otlp-transformer/src/common/internal-types.ts index b3026f121a1..93e07a50a6f 100644 --- a/experimental/packages/otlp-transformer/src/common/internal-types.ts +++ b/experimental/packages/otlp-transformer/src/common/internal-types.ts @@ -15,7 +15,7 @@ */ /** Properties of a Resource. */ -export interface IResource { +export interface Resource { /** Resource attributes */ attributes: IKeyValue[]; diff --git a/experimental/packages/otlp-transformer/src/common/internal.ts b/experimental/packages/otlp-transformer/src/common/internal.ts index 0deeb1d51f2..80f61e0553d 100644 --- a/experimental/packages/otlp-transformer/src/common/internal.ts +++ b/experimental/packages/otlp-transformer/src/common/internal.ts @@ -17,13 +17,13 @@ import type { IAnyValue, IInstrumentationScope, IKeyValue, - IResource, + Resource, } from './internal-types'; import { Attributes } from '@opentelemetry/api'; import { InstrumentationScope } from '@opentelemetry/core'; -import { IResource as ISdkResource } from '@opentelemetry/resources'; +import { Resource as ISdkResource } from '@opentelemetry/resources'; -export function createResource(resource: ISdkResource): IResource { +export function createResource(resource: ISdkResource): Resource { return { attributes: toAttributes(resource.attributes), droppedAttributesCount: 0, diff --git a/experimental/packages/otlp-transformer/src/logs/internal-types.ts b/experimental/packages/otlp-transformer/src/logs/internal-types.ts index 28917fbd74f..09f744141d2 100644 --- a/experimental/packages/otlp-transformer/src/logs/internal-types.ts +++ b/experimental/packages/otlp-transformer/src/logs/internal-types.ts @@ -19,7 +19,7 @@ import type { IAnyValue, IInstrumentationScope, IKeyValue, - IResource, + Resource, } from '../common/internal-types'; /** Properties of an ExportLogsServiceRequest. */ @@ -31,7 +31,7 @@ export interface IExportLogsServiceRequest { /** Properties of a ResourceLogs. */ export interface IResourceLogs { /** ResourceLogs resource */ - resource?: IResource; + resource?: Resource; /** ResourceLogs scopeLogs */ scopeLogs: IScopeLogs[]; diff --git a/experimental/packages/otlp-transformer/src/logs/internal.ts b/experimental/packages/otlp-transformer/src/logs/internal.ts index 53fe9ea6688..8c54e72a097 100644 --- a/experimental/packages/otlp-transformer/src/logs/internal.ts +++ b/experimental/packages/otlp-transformer/src/logs/internal.ts @@ -21,7 +21,7 @@ import { ILogRecord, IResourceLogs, } from './internal-types'; -import { IResource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; import { Encoder, getOtlpEncoder } from '../common/utils'; import { createInstrumentationScope, @@ -45,9 +45,9 @@ export function createExportLogsServiceRequest( function createResourceMap( logRecords: ReadableLogRecord[] -): Map> { +): Map> { const resourceMap: Map< - IResource, + Resource, Map > = new Map(); diff --git a/experimental/packages/otlp-transformer/src/metrics/internal-types.ts b/experimental/packages/otlp-transformer/src/metrics/internal-types.ts index f210a88fe93..b67d03e2842 100644 --- a/experimental/packages/otlp-transformer/src/metrics/internal-types.ts +++ b/experimental/packages/otlp-transformer/src/metrics/internal-types.ts @@ -17,7 +17,7 @@ import { Fixed64, IInstrumentationScope, IKeyValue, - IResource, + Resource, } from '../common/internal-types'; /** Properties of an ExportMetricsServiceRequest. */ @@ -29,7 +29,7 @@ export interface IExportMetricsServiceRequest { /** Properties of a ResourceMetrics. */ export interface IResourceMetrics { /** ResourceMetrics resource */ - resource?: IResource; + resource?: Resource; /** ResourceMetrics scopeMetrics */ scopeMetrics: IScopeMetrics[]; diff --git a/experimental/packages/otlp-transformer/src/trace/internal-types.ts b/experimental/packages/otlp-transformer/src/trace/internal-types.ts index 94e78072b27..75b9c21e260 100644 --- a/experimental/packages/otlp-transformer/src/trace/internal-types.ts +++ b/experimental/packages/otlp-transformer/src/trace/internal-types.ts @@ -18,7 +18,7 @@ import { Fixed64, IInstrumentationScope, IKeyValue, - IResource, + Resource, } from '../common/internal-types'; /** Properties of an ExportTraceServiceRequest. */ @@ -30,7 +30,7 @@ export interface IExportTraceServiceRequest { /** Properties of a ResourceSpans. */ export interface IResourceSpans { /** ResourceSpans resource */ - resource?: IResource; + resource?: Resource; /** ResourceSpans scopeSpans */ scopeSpans: IScopeSpans[]; diff --git a/experimental/packages/otlp-transformer/src/trace/internal.ts b/experimental/packages/otlp-transformer/src/trace/internal.ts index da94baf7473..b3c07da0e19 100644 --- a/experimental/packages/otlp-transformer/src/trace/internal.ts +++ b/experimental/packages/otlp-transformer/src/trace/internal.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import type { Link } from '@opentelemetry/api'; -import { IResource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; import type { ReadableSpan, TimedEvent } from '@opentelemetry/sdk-trace-base'; import type { Encoder } from '../common/utils'; import { @@ -112,7 +112,7 @@ export function createExportTraceServiceRequest( } function createResourceMap(readableSpans: ReadableSpan[]) { - const resourceMap: Map> = new Map(); + const resourceMap: Map> = new Map(); for (const record of readableSpans) { let ilsMap = resourceMap.get(record.resource); diff --git a/experimental/packages/otlp-transformer/test/logs.test.ts b/experimental/packages/otlp-transformer/test/logs.test.ts index 2d14bcd6cbc..05da91f89ab 100644 --- a/experimental/packages/otlp-transformer/test/logs.test.ts +++ b/experimental/packages/otlp-transformer/test/logs.test.ts @@ -15,7 +15,7 @@ */ import { HrTime, TraceFlags } from '@opentelemetry/api'; import { InstrumentationScope } from '@opentelemetry/core'; -import { Resource } from '@opentelemetry/resources'; +import { Resource, resourceFromAttributes } from '@opentelemetry/resources'; import * as assert from 'assert'; import { ReadableLogRecord } from '@opentelemetry/sdk-logs'; import { SeverityNumber } from '@opentelemetry/api-logs'; @@ -166,15 +166,11 @@ describe('Logs', () => { let log_2_1_1: ReadableLogRecord; beforeEach(() => { - resource_1 = new Resource({ - attributes: { - 'resource-attribute': 'some attribute value', - }, + resource_1 = resourceFromAttributes({ + 'resource-attribute': 'some attribute value', }); - resource_2 = new Resource({ - attributes: { - 'resource-attribute': 'another attribute value', - }, + resource_2 = resourceFromAttributes({ + 'resource-attribute': 'another attribute value', }); scope_1 = { name: 'scope_name_1', diff --git a/experimental/packages/otlp-transformer/test/metrics.test.ts b/experimental/packages/otlp-transformer/test/metrics.test.ts index 254ef82c955..f97d6497b62 100644 --- a/experimental/packages/otlp-transformer/test/metrics.test.ts +++ b/experimental/packages/otlp-transformer/test/metrics.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { ValueType } from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; +import { resourceFromAttributes } from '@opentelemetry/resources'; import { AggregationTemporality, DataPointType, @@ -302,10 +302,8 @@ describe('Metrics', () => { } function createResourceMetrics(metricData: MetricData[]): ResourceMetrics { - const resource = new Resource({ - attributes: { - 'resource-attribute': 'resource attribute value', - }, + const resource = resourceFromAttributes({ + 'resource-attribute': 'resource attribute value', }); return { resource: resource, diff --git a/experimental/packages/otlp-transformer/test/trace.test.ts b/experimental/packages/otlp-transformer/test/trace.test.ts index a4ae8b0ce02..c2711d78339 100644 --- a/experimental/packages/otlp-transformer/test/trace.test.ts +++ b/experimental/packages/otlp-transformer/test/trace.test.ts @@ -16,7 +16,7 @@ import * as root from '../src/generated/root'; import { SpanKind, SpanStatusCode, TraceFlags } from '@opentelemetry/api'; import { TraceState } from '@opentelemetry/core'; -import { Resource } from '@opentelemetry/resources'; +import { Resource, resourceFromAttributes } from '@opentelemetry/resources'; import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import * as assert from 'assert'; import { toBase64 } from './utils'; @@ -232,10 +232,8 @@ describe('Trace', () => { let span: ReadableSpan; beforeEach(() => { - resource = new Resource({ - attributes: { - 'resource-attribute': 'resource attribute value', - }, + resource = resourceFromAttributes({ + 'resource-attribute': 'resource attribute value', }); span = { spanContext: () => ({ diff --git a/experimental/packages/sampler-jaeger-remote/README.md b/experimental/packages/sampler-jaeger-remote/README.md index ef6727a688f..e6d3c7a2841 100644 --- a/experimental/packages/sampler-jaeger-remote/README.md +++ b/experimental/packages/sampler-jaeger-remote/README.md @@ -19,7 +19,7 @@ To integrate the Jaeger Remote Sampler with your application, configure it with ```javascript const { JaegerRemoteSampler } = require('@opentelemetry/sampler-jaeger-remote'); -const { Resource } = require('@opentelemetry/resources'); +const { DEFAULT_RESOURCE, resourceFromAttributes } = require('@opentelemetry/resources'); const { NodeTracerProvider } = require('@opentelemetry/node'); // Jaeger agent endpoint @@ -30,7 +30,7 @@ const sampler = new JaegerRemoteSampler({ poolingInterval: 60000 // 60 seconds }); const provider = new NodeTracerProvider({ - resource: Resource.default().merge(new Resource({ + resource: DEFAULT_RESOURCE.merge(resourceFromAttributes({ 'service.name': 'your-service-name' })), sampler diff --git a/experimental/packages/sdk-logs/src/LogRecord.ts b/experimental/packages/sdk-logs/src/LogRecord.ts index f678648e756..f1f9c99506e 100644 --- a/experimental/packages/sdk-logs/src/LogRecord.ts +++ b/experimental/packages/sdk-logs/src/LogRecord.ts @@ -22,7 +22,7 @@ import { isAttributeValue, InstrumentationScope, } from '@opentelemetry/core'; -import type { IResource } from '@opentelemetry/resources'; +import type { Resource } from '@opentelemetry/resources'; import type { ReadableLogRecord } from './export/ReadableLogRecord'; import type { LogRecordLimits } from './types'; @@ -33,7 +33,7 @@ export class LogRecord implements ReadableLogRecord { readonly hrTime: api.HrTime; readonly hrTimeObserved: api.HrTime; readonly spanContext?: api.SpanContext; - readonly resource: IResource; + readonly resource: Resource; readonly instrumentationScope: InstrumentationScope; readonly attributes: logsAPI.LogAttributes = {}; private _severityText?: string; diff --git a/experimental/packages/sdk-logs/src/LoggerProvider.ts b/experimental/packages/sdk-logs/src/LoggerProvider.ts index 575f178178e..818ecd566c9 100644 --- a/experimental/packages/sdk-logs/src/LoggerProvider.ts +++ b/experimental/packages/sdk-logs/src/LoggerProvider.ts @@ -16,7 +16,7 @@ import { diag } from '@opentelemetry/api'; import type * as logsAPI from '@opentelemetry/api-logs'; import { NOOP_LOGGER } from '@opentelemetry/api-logs'; -import { Resource } from '@opentelemetry/resources'; +import { DEFAULT_RESOURCE } from '@opentelemetry/resources'; import { BindOnceFuture, merge } from '@opentelemetry/core'; import type { LoggerProviderConfig } from './types'; @@ -34,7 +34,7 @@ export class LoggerProvider implements logsAPI.LoggerProvider { constructor(config: LoggerProviderConfig = {}) { const mergedConfig = merge({}, loadDefaultConfig(), config); - const resource = config.resource ?? Resource.default(); + const resource = config.resource ?? DEFAULT_RESOURCE; this._sharedState = new LoggerProviderSharedState( resource, mergedConfig.forceFlushTimeoutMillis, diff --git a/experimental/packages/sdk-logs/src/export/ReadableLogRecord.ts b/experimental/packages/sdk-logs/src/export/ReadableLogRecord.ts index 2af71de76be..ab110104d1f 100644 --- a/experimental/packages/sdk-logs/src/export/ReadableLogRecord.ts +++ b/experimental/packages/sdk-logs/src/export/ReadableLogRecord.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import type { IResource } from '@opentelemetry/resources'; +import type { Resource } from '@opentelemetry/resources'; import type { HrTime, SpanContext } from '@opentelemetry/api'; import type { InstrumentationScope } from '@opentelemetry/core'; import type { @@ -30,7 +30,7 @@ export interface ReadableLogRecord { readonly severityText?: string; readonly severityNumber?: SeverityNumber; readonly body?: LogBody; - readonly resource: IResource; + readonly resource: Resource; readonly instrumentationScope: InstrumentationScope; readonly attributes: LogAttributes; readonly droppedAttributesCount: number; diff --git a/experimental/packages/sdk-logs/src/internal/LoggerProviderSharedState.ts b/experimental/packages/sdk-logs/src/internal/LoggerProviderSharedState.ts index 16b208f72c1..ef573b3612e 100644 --- a/experimental/packages/sdk-logs/src/internal/LoggerProviderSharedState.ts +++ b/experimental/packages/sdk-logs/src/internal/LoggerProviderSharedState.ts @@ -15,7 +15,7 @@ */ import { Logger } from '@opentelemetry/api-logs'; -import { IResource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; import { LogRecordProcessor } from '../LogRecordProcessor'; import { LogRecordLimits } from '../types'; import { NoopLogRecordProcessor } from '../export/NoopLogRecordProcessor'; @@ -26,7 +26,7 @@ export class LoggerProviderSharedState { readonly registeredLogRecordProcessors: LogRecordProcessor[] = []; constructor( - readonly resource: IResource, + readonly resource: Resource, readonly forceFlushTimeoutMillis: number, readonly logRecordLimits: Required ) { diff --git a/experimental/packages/sdk-logs/src/types.ts b/experimental/packages/sdk-logs/src/types.ts index 27aefa540fe..bf40207f4d7 100644 --- a/experimental/packages/sdk-logs/src/types.ts +++ b/experimental/packages/sdk-logs/src/types.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import type { IResource } from '@opentelemetry/resources'; +import type { Resource } from '@opentelemetry/resources'; export interface LoggerProviderConfig { /** Resource associated with trace telemetry */ - resource?: IResource; + resource?: Resource; /** * How long the forceFlush can run before it is cancelled. diff --git a/experimental/packages/sdk-logs/test/common/LogRecord.test.ts b/experimental/packages/sdk-logs/test/common/LogRecord.test.ts index 3518e99fd18..0eb16eaf397 100644 --- a/experimental/packages/sdk-logs/test/common/LogRecord.test.ts +++ b/experimental/packages/sdk-logs/test/common/LogRecord.test.ts @@ -27,7 +27,7 @@ import { import * as logsAPI from '@opentelemetry/api-logs'; import type { HrTime } from '@opentelemetry/api'; import { hrTimeToMilliseconds, timeInputToHrTime } from '@opentelemetry/core'; -import { Resource } from '@opentelemetry/resources'; +import { DEFAULT_RESOURCE } from '@opentelemetry/resources'; import { LogRecordLimits, @@ -47,7 +47,7 @@ const setup = (logRecordLimits?: LogRecordLimits, data?: logsAPI.LogRecord) => { version: 'test version', schemaUrl: 'test schema url', }; - const resource = Resource.default(); + const resource = DEFAULT_RESOURCE; const sharedState = new LoggerProviderSharedState( resource, Infinity, diff --git a/experimental/packages/sdk-logs/test/common/LoggerProvider.test.ts b/experimental/packages/sdk-logs/test/common/LoggerProvider.test.ts index 44c82800f51..9dcdc18dd44 100644 --- a/experimental/packages/sdk-logs/test/common/LoggerProvider.test.ts +++ b/experimental/packages/sdk-logs/test/common/LoggerProvider.test.ts @@ -15,7 +15,10 @@ */ import { logs, NoopLogger } from '@opentelemetry/api-logs'; import { diag } from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; +import { + DEFAULT_RESOURCE, + resourceFromAttributes, +} from '@opentelemetry/resources'; import * as assert from 'assert'; import * as sinon from 'sinon'; @@ -60,11 +63,11 @@ describe('LoggerProvider', () => { it('should have default resource if not pass', () => { const provider = new LoggerProvider(); const { resource } = provider['_sharedState']; - assert.deepStrictEqual(resource, Resource.default()); + assert.deepStrictEqual(resource, DEFAULT_RESOURCE); }); it('should not have default resource if passed', function () { - const passedInResource = new Resource({ attributes: { foo: 'bar' } }); + const passedInResource = resourceFromAttributes({ foo: 'bar' }); const provider = new LoggerProvider({ resource: passedInResource, }); diff --git a/experimental/packages/sdk-logs/test/common/export/BatchLogRecordProcessor.test.ts b/experimental/packages/sdk-logs/test/common/export/BatchLogRecordProcessor.test.ts index 9c4b5eee295..6348ab5e72a 100644 --- a/experimental/packages/sdk-logs/test/common/export/BatchLogRecordProcessor.test.ts +++ b/experimental/packages/sdk-logs/test/common/export/BatchLogRecordProcessor.test.ts @@ -32,7 +32,11 @@ import { import { BatchLogRecordProcessorBase } from '../../../src/export/BatchLogRecordProcessorBase'; import { reconfigureLimits } from '../../../src/config'; import { LoggerProviderSharedState } from '../../../src/internal/LoggerProviderSharedState'; -import { Resource } from '@opentelemetry/resources'; +import { + DEFAULT_RESOURCE, + Resource, + resourceFromAttributes, +} from '@opentelemetry/resources'; class BatchLogRecordProcessor extends BatchLogRecordProcessorBase { onInit() {} @@ -44,7 +48,7 @@ const createLogRecord = ( resource?: Resource ): LogRecord => { const sharedState = new LoggerProviderSharedState( - resource || Resource.default(), + resource || DEFAULT_RESOURCE, Infinity, reconfigureLimits(limits ?? {}) ); @@ -314,12 +318,10 @@ describe('BatchLogRecordProcessorBase', () => { it('should wait for pending resource on flush', async () => { const processor = new BatchLogRecordProcessor(exporter); - const asyncResource = new Resource({ - attributes: { - async: new Promise(resolve => - setTimeout(() => resolve('fromasync'), 1) - ), - }, + const asyncResource = resourceFromAttributes({ + async: new Promise(resolve => + setTimeout(() => resolve('fromasync'), 1) + ), }); const logRecord = createLogRecord(undefined, asyncResource); processor.onEmit(logRecord); diff --git a/experimental/packages/sdk-logs/test/common/export/SimpleLogRecordProcessor.test.ts b/experimental/packages/sdk-logs/test/common/export/SimpleLogRecordProcessor.test.ts index 547e8e86c32..0862d33b1f6 100644 --- a/experimental/packages/sdk-logs/test/common/export/SimpleLogRecordProcessor.test.ts +++ b/experimental/packages/sdk-logs/test/common/export/SimpleLogRecordProcessor.test.ts @@ -21,7 +21,11 @@ import { loggingErrorHandler, setGlobalErrorHandler, } from '@opentelemetry/core'; -import { Resource } from '@opentelemetry/resources'; +import { + DEFAULT_RESOURCE, + Resource, + resourceFromAttributes, +} from '@opentelemetry/resources'; import { InMemoryLogRecordExporter, @@ -35,7 +39,7 @@ import { TestExporterWithDelay } from './TestExporterWithDelay'; const setup = (exporter: LogRecordExporter, resource?: Resource) => { const sharedState = new LoggerProviderSharedState( - resource || Resource.default(), + resource || DEFAULT_RESOURCE, Infinity, reconfigureLimits({}) ); @@ -118,12 +122,10 @@ describe('SimpleLogRecordProcessor', () => { describe('force flush', () => { it('should await unresolved resources', async () => { const exporter = new InMemoryLogRecordExporter(); - const asyncResource = new Resource({ - attributes: { - async: new Promise(resolve => - setTimeout(() => resolve('fromasync'), 1) - ), - }, + const asyncResource = resourceFromAttributes({ + async: new Promise(resolve => + setTimeout(() => resolve('fromasync'), 1) + ), }); const { processor, logRecord } = setup(exporter, asyncResource); assert.strictEqual(exporter.getFinishedLogRecords().length, 0); @@ -141,12 +143,10 @@ describe('SimpleLogRecordProcessor', () => { it('should await doExport() and delete from _unresolvedExports', async () => { const testExporterWithDelay = new TestExporterWithDelay(); - const asyncResource = new Resource({ - attributes: { - async: new Promise(resolve => - setTimeout(() => resolve('fromasync'), 1) - ), - }, + const asyncResource = resourceFromAttributes({ + async: new Promise(resolve => + setTimeout(() => resolve('fromasync'), 1) + ), }); const processor = new SimpleLogRecordProcessor(testExporterWithDelay); const { logRecord } = setup(testExporterWithDelay, asyncResource); diff --git a/experimental/packages/shim-opencensus/src/OpenCensusMetricProducer.ts b/experimental/packages/shim-opencensus/src/OpenCensusMetricProducer.ts index 92234e96bc3..a582648a758 100644 --- a/experimental/packages/shim-opencensus/src/OpenCensusMetricProducer.ts +++ b/experimental/packages/shim-opencensus/src/OpenCensusMetricProducer.ts @@ -16,7 +16,7 @@ */ import * as oc from '@opencensus/core'; -import { Resource } from '@opentelemetry/resources'; +import { EMPTY_RESOURCE } from '@opentelemetry/resources'; import { CollectionResult, MetricData, @@ -80,7 +80,7 @@ export class OpenCensusMetricProducer implements MetricProducer { errors: [], resourceMetrics: { // Resource is ignored by the SDK, it just uses the SDK's resource - resource: Resource.EMPTY, + resource: EMPTY_RESOURCE, scopeMetrics, }, }; diff --git a/experimental/packages/shim-opencensus/test/OpenCensusMetricProducer.test.ts b/experimental/packages/shim-opencensus/test/OpenCensusMetricProducer.test.ts index db9d018ac6e..d7667282d02 100644 --- a/experimental/packages/shim-opencensus/test/OpenCensusMetricProducer.test.ts +++ b/experimental/packages/shim-opencensus/test/OpenCensusMetricProducer.test.ts @@ -16,7 +16,7 @@ import * as oc from '@opencensus/core'; import { ValueType } from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; +import { EMPTY_RESOURCE } from '@opentelemetry/resources'; import { AggregationTemporality, DataPointType, @@ -43,7 +43,7 @@ describe('OpenCensusMetricProducer', () => { assert.deepStrictEqual( resourceMetrics.resourceMetrics.resource, - Resource.EMPTY + EMPTY_RESOURCE ); }); diff --git a/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts b/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts index 55275441ddf..1fe726769c8 100644 --- a/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts +++ b/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts @@ -21,7 +21,7 @@ import * as api from '@opentelemetry/api'; import { ThriftProcess } from '../src/types'; import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import { TraceFlags } from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; +import { resourceFromAttributes } from '@opentelemetry/resources'; import * as nock from 'nock'; import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; @@ -46,10 +46,8 @@ describe('JaegerExporter', () => { links: [], events: [], duration: [32, 800000000], - resource: new Resource({ - attributes: { - [SEMRESATTRS_SERVICE_NAME]: 'opentelemetry', - }, + resource: resourceFromAttributes({ + [SEMRESATTRS_SERVICE_NAME]: 'opentelemetry', }), instrumentationScope: { name: 'default', diff --git a/packages/opentelemetry-exporter-jaeger/test/transform.test.ts b/packages/opentelemetry-exporter-jaeger/test/transform.test.ts index 2baaace92a1..872c7ca4ae8 100644 --- a/packages/opentelemetry-exporter-jaeger/test/transform.test.ts +++ b/packages/opentelemetry-exporter-jaeger/test/transform.test.ts @@ -17,7 +17,10 @@ import * as assert from 'assert'; import { spanToThrift } from '../src/transform'; import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import { Resource } from '@opentelemetry/resources'; +import { + EMPTY_RESOURCE, + resourceFromAttributes, +} from '@opentelemetry/resources'; import * as api from '@opentelemetry/api'; import { ThriftUtils, Utils, ThriftReferenceType } from '../src/types'; import { hrTimeToMicroseconds } from '@opentelemetry/core'; @@ -73,12 +76,10 @@ describe('transform', () => { }, ], duration: [32, 800000000], - resource: new Resource({ - attributes: { - service: 'ui', - version: 1, - cost: 112.12, - }, + resource: resourceFromAttributes({ + service: 'ui', + version: 1, + cost: 112.12, }), instrumentationScope: { name: 'default', @@ -179,7 +180,7 @@ describe('transform', () => { links: [], events: [], duration: [32, 800000000], - resource: Resource.EMPTY, + resource: EMPTY_RESOURCE, instrumentationScope: { name: 'default', version: '0.0.1', @@ -249,7 +250,7 @@ describe('transform', () => { ], events: [], duration: [32, 800000000], - resource: Resource.EMPTY, + resource: EMPTY_RESOURCE, instrumentationScope: { name: 'default', version: '0.0.1', @@ -297,7 +298,7 @@ describe('transform', () => { links: [], events: [], duration: [32, 800000000], - resource: Resource.EMPTY, + resource: EMPTY_RESOURCE, instrumentationScope: { name: 'default', version: '0.0.1', @@ -358,12 +359,10 @@ describe('transform', () => { }, ], duration: [32, 800000000], - resource: new Resource({ - attributes: { - service: 'ui', - version: 1, - cost: 112.12, - }, + resource: resourceFromAttributes({ + service: 'ui', + version: 1, + cost: 112.12, }), instrumentationScope: { name: 'default', diff --git a/packages/opentelemetry-exporter-zipkin/test/common/transform.test.ts b/packages/opentelemetry-exporter-zipkin/test/common/transform.test.ts index c580a07ca24..8cd6f385d1b 100644 --- a/packages/opentelemetry-exporter-zipkin/test/common/transform.test.ts +++ b/packages/opentelemetry-exporter-zipkin/test/common/transform.test.ts @@ -21,7 +21,7 @@ import { hrTimeToMicroseconds, millisToHrTime, } from '@opentelemetry/core'; -import { IResource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import * as assert from 'assert'; import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; @@ -45,7 +45,7 @@ const resource = { 'telemetry.sdk.name': 'opentelemetry', 'telemetry.sdk.version': VERSION, }, -} as unknown as IResource; +} as unknown as Resource; const parentId = '5c1c63257de34c67'; const spanContext: api.SpanContext = { traceId: 'd4cda95b652f4a1592b449d5929fda1b', diff --git a/packages/opentelemetry-exporter-zipkin/test/helper.ts b/packages/opentelemetry-exporter-zipkin/test/helper.ts index 22fb84c8778..abc3777d37b 100644 --- a/packages/opentelemetry-exporter-zipkin/test/helper.ts +++ b/packages/opentelemetry-exporter-zipkin/test/helper.ts @@ -16,9 +16,9 @@ import { TraceFlags, SpanStatusCode } from '@opentelemetry/api'; import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import { Resource } from '@opentelemetry/resources'; import * as assert from 'assert'; import { Span } from '../src/types'; +import { resourceFromAttributes } from '@opentelemetry/resources'; export const mockedReadableSpan: ReadableSpan = { name: 'documentFetch', @@ -39,12 +39,10 @@ export const mockedReadableSpan: ReadableSpan = { links: [], events: [], duration: [0, 8885000], - resource: new Resource({ - attributes: { - service: 'ui', - version: 1, - cost: 112.12, - }, + resource: resourceFromAttributes({ + service: 'ui', + version: 1, + cost: 112.12, }), instrumentationScope: { name: 'default', version: '0.0.1' }, droppedAttributesCount: 0, diff --git a/packages/opentelemetry-exporter-zipkin/test/node/zipkin.test.ts b/packages/opentelemetry-exporter-zipkin/test/node/zipkin.test.ts index 357d9e01763..787bb5b261f 100644 --- a/packages/opentelemetry-exporter-zipkin/test/node/zipkin.test.ts +++ b/packages/opentelemetry-exporter-zipkin/test/node/zipkin.test.ts @@ -23,7 +23,10 @@ import { ExportResultCode, } from '@opentelemetry/core'; import * as api from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; +import { + EMPTY_RESOURCE, + resourceFromAttributes, +} from '@opentelemetry/resources'; import { ZipkinExporter } from '../../src'; import * as zipkinTypes from '../../src/types'; import { TraceFlags } from '@opentelemetry/api'; @@ -54,7 +57,7 @@ function getReadableSpan() { attributes: {}, links: [], events: [], - resource: Resource.EMPTY, + resource: EMPTY_RESOURCE, instrumentationScope: { name: 'default', version: '0.0.1' }, droppedAttributesCount: 0, droppedEventsCount: 0, @@ -165,7 +168,7 @@ describe('Zipkin Exporter - node', () => { attributes: { key3: 'value3' }, }, ], - resource: Resource.EMPTY, + resource: EMPTY_RESOURCE, instrumentationScope: { name: 'default', version: '0.0.1' }, droppedAttributesCount: 0, droppedEventsCount: 0, @@ -191,7 +194,7 @@ describe('Zipkin Exporter - node', () => { attributes: {}, links: [], events: [], - resource: Resource.EMPTY, + resource: EMPTY_RESOURCE, instrumentationScope: { name: 'default', version: '0.0.1' }, droppedAttributesCount: 0, droppedEventsCount: 0, @@ -384,8 +387,8 @@ describe('Zipkin Exporter - node', () => { attributes: { key3: 'value3' }, }, ], - resource: new Resource({ - attributes: { [SEMRESATTRS_SERVICE_NAME]: resource_service_name }, + resource: resourceFromAttributes({ + [SEMRESATTRS_SERVICE_NAME]: resource_service_name, }), instrumentationScope: { name: 'default', version: '0.0.1' }, droppedAttributesCount: 0, @@ -410,8 +413,8 @@ describe('Zipkin Exporter - node', () => { attributes: {}, links: [], events: [], - resource: new Resource({ - attributes: { [SEMRESATTRS_SERVICE_NAME]: resource_service_name_prime }, + resource: resourceFromAttributes({ + [SEMRESATTRS_SERVICE_NAME]: resource_service_name_prime, }), instrumentationScope: { name: 'default', version: '0.0.1' }, droppedAttributesCount: 0, @@ -480,7 +483,7 @@ describe('Zipkin Exporter - node', () => { attributes: { key3: 'value3' }, }, ], - resource: Resource.EMPTY, + resource: EMPTY_RESOURCE, instrumentationScope: { name: 'default', version: '0.0.1' }, droppedAttributesCount: 0, droppedEventsCount: 0, @@ -506,7 +509,7 @@ describe('Zipkin Exporter - node', () => { }, links: [], events: [], - resource: Resource.EMPTY, + resource: EMPTY_RESOURCE, instrumentationScope: { name: 'default', version: '0.0.1' }, droppedAttributesCount: 0, droppedEventsCount: 0, diff --git a/packages/opentelemetry-resources/README.md b/packages/opentelemetry-resources/README.md index 3b19855adff..58e3aaac2f2 100644 --- a/packages/opentelemetry-resources/README.md +++ b/packages/opentelemetry-resources/README.md @@ -17,13 +17,13 @@ npm install --save @opentelemetry/resources ```typescript import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; -import { Resource } from '@opentelemetry/resources'; +import { resourceFromAttributes } from '@opentelemetry/resources'; -const resource = new Resource({ +const resource = resourceFromAttributes({ [SEMRESATTRS_SERVICE_NAME]: 'api-service', }); -const anotherResource = new Resource({ +const anotherResource = resourceFromAttributes({ 'service.version': '2.0.0', 'service.group': 'instrumentation-group' }); diff --git a/packages/opentelemetry-resources/src/IResource.ts b/packages/opentelemetry-resources/src/IResource.ts deleted file mode 100644 index 7db9866515f..00000000000 --- a/packages/opentelemetry-resources/src/IResource.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright The 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 { Attributes } from '@opentelemetry/api'; -import { RawResourceAttribute } from './types'; - -/** - * An interface that represents a resource. A Resource describes the entity for which signals (metrics or trace) are - * collected. - * - */ -export interface IResource { - /** - * Check if async attributes have resolved. This is useful to avoid awaiting - * waitForAsyncAttributes (which will introduce asynchronous behavior) when not necessary. - * - * @returns true if the resource "attributes" property is not yet settled to its final value - */ - readonly asyncAttributesPending?: boolean; - - /** - * @returns the Resource's attributes. - */ - readonly attributes: Attributes; - - /** - * Returns a promise that will never be rejected. Resolves when all async attributes have finished being added to - * this Resource's attributes. This is useful in exporters to block until resource detection - * has finished. - */ - waitForAsyncAttributes?(): Promise; - - /** - * Returns a new, merged {@link Resource} by merging the current Resource - * with the other Resource. In case of a collision, other Resource takes - * precedence. - * - * @param other the Resource that will be merged with this. - * @returns the newly merged Resource. - */ - merge(other: IResource | null): IResource; - - getRawAttributes(): RawResourceAttribute[]; -} diff --git a/packages/opentelemetry-resources/src/Resource.ts b/packages/opentelemetry-resources/src/Resource.ts index 5172b18b882..7b909d70f79 100644 --- a/packages/opentelemetry-resources/src/Resource.ts +++ b/packages/opentelemetry-resources/src/Resource.ts @@ -14,133 +14,44 @@ * limitations under the License. */ -import { Attributes, AttributeValue, diag } from '@opentelemetry/api'; -import { SDK_INFO } from '@opentelemetry/core'; -import { - ATTR_SERVICE_NAME, - ATTR_TELEMETRY_SDK_LANGUAGE, - ATTR_TELEMETRY_SDK_NAME, - ATTR_TELEMETRY_SDK_VERSION, -} from '@opentelemetry/semantic-conventions'; -import { IResource } from './IResource'; -import { defaultServiceName } from './platform'; -import { DetectedResource, MaybePromise, RawResourceAttribute } from './types'; -import { isPromiseLike } from './utils'; +import { Attributes } from '@opentelemetry/api'; +import { RawResourceAttribute } from './types'; -export class Resource implements IResource { - private _rawAttributes: RawResourceAttribute[]; - private _asyncAttributesPending = false; - - private _memoizedAttributes?: Attributes; - - public static EMPTY: IResource = new Resource({ attributes: {} }); +/** + * An interface that represents a resource. A Resource describes the entity for which signals (metrics or trace) are + * collected. + * + */ +export interface Resource { /** - * Returns a Resource that identifies the SDK in use. + * Check if async attributes have resolved. This is useful to avoid awaiting + * waitForAsyncAttributes (which will introduce asynchronous behavior) when not necessary. + * + * @returns true if the resource "attributes" property is not yet settled to its final value */ - static default(): IResource { - return new Resource({ - attributes: { - [ATTR_SERVICE_NAME]: defaultServiceName(), - [ATTR_TELEMETRY_SDK_LANGUAGE]: SDK_INFO[ATTR_TELEMETRY_SDK_LANGUAGE], - [ATTR_TELEMETRY_SDK_NAME]: SDK_INFO[ATTR_TELEMETRY_SDK_NAME], - [ATTR_TELEMETRY_SDK_VERSION]: SDK_INFO[ATTR_TELEMETRY_SDK_VERSION], - }, - }); - } - - static FromAttributeList( - attributes: [string, MaybePromise][] - ): Resource { - const res = new Resource({}); - res._rawAttributes = attributes; - res._asyncAttributesPending = - attributes.filter(([_, val]) => isPromiseLike(val)).length > 0; - return res; - } - - constructor( - /** - * A dictionary of attributes with string keys and values that provide - * information about the entity as numbers, strings or booleans - * TODO: Consider to add check/validation on attributes. - */ - resource: DetectedResource - ) { - const attributes = resource.attributes ?? {}; - this._rawAttributes = Object.entries(attributes).map(([k, v]) => { - if (isPromiseLike(v)) { - // side-effect - this._asyncAttributesPending = true; - } - - return [k, v]; - }); - } - - public get asyncAttributesPending(): boolean { - return this._asyncAttributesPending; - } - - public async waitForAsyncAttributes(): Promise { - if (!this.asyncAttributesPending) { - return; - } - - for (let i = 0; i < this._rawAttributes.length; i++) { - const [k, v] = this._rawAttributes[i]; - try { - this._rawAttributes[i] = [k, isPromiseLike(v) ? await v : v]; - } catch (err) { - diag.debug("a resource's async attributes promise rejected: %s", err); - this._rawAttributes[i] = [k, undefined]; - } - } - - this._asyncAttributesPending = false; - } + readonly asyncAttributesPending?: boolean; - public get attributes(): Attributes { - if (this.asyncAttributesPending) { - diag.error( - 'Accessing resource attributes before async attributes settled' - ); - } - - if (this._memoizedAttributes) { - return this._memoizedAttributes; - } - - const attrs: Attributes = {}; - for (const [k, v] of this._rawAttributes) { - if (isPromiseLike(v)) { - diag.debug(`Unsettled resource attribute ${k} skipped`); - continue; - } - if (v != null) { - attrs[k] ??= v; - } - } - - // only memoize output if all attributes are settled - if (!this._asyncAttributesPending) { - this._memoizedAttributes = attrs; - } - - return attrs; - } + /** + * @returns the Resource's attributes. + */ + readonly attributes: Attributes; - public getRawAttributes(): RawResourceAttribute[] { - return this._rawAttributes; - } + /** + * Returns a promise that will never be rejected. Resolves when all async attributes have finished being added to + * this Resource's attributes. This is useful in exporters to block until resource detection + * has finished. + */ + waitForAsyncAttributes?(): Promise; - public merge(resource: IResource | null): IResource { - if (resource == null) return this; + /** + * Returns a new, merged {@link Resource} by merging the current Resource + * with the other Resource. In case of a collision, other Resource takes + * precedence. + * + * @param other the Resource that will be merged with this. + * @returns the newly merged Resource. + */ + merge(other: Resource | null): Resource; - // Order is important - // Spec states incoming attributes override existing attributes - return Resource.FromAttributeList([ - ...resource.getRawAttributes(), - ...this.getRawAttributes(), - ]); - } + getRawAttributes(): RawResourceAttribute[]; } diff --git a/packages/opentelemetry-resources/src/ResourceImpl.ts b/packages/opentelemetry-resources/src/ResourceImpl.ts new file mode 100644 index 00000000000..e90b98b90dc --- /dev/null +++ b/packages/opentelemetry-resources/src/ResourceImpl.ts @@ -0,0 +1,156 @@ +/* + * Copyright The 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 { Attributes, AttributeValue, diag } from '@opentelemetry/api'; +import { SDK_INFO } from '@opentelemetry/core'; +import { + ATTR_SERVICE_NAME, + ATTR_TELEMETRY_SDK_LANGUAGE, + ATTR_TELEMETRY_SDK_NAME, + ATTR_TELEMETRY_SDK_VERSION, +} from '@opentelemetry/semantic-conventions'; +import { Resource } from './Resource'; +import { defaultServiceName } from './platform'; +import { + DetectedResource, + DetectedResourceAttributes, + MaybePromise, + RawResourceAttribute, +} from './types'; +import { isPromiseLike } from './utils'; + +class ResourceImpl implements Resource { + private _rawAttributes: RawResourceAttribute[]; + private _asyncAttributesPending = false; + + private _memoizedAttributes?: Attributes; + + static FromAttributeList( + attributes: [string, MaybePromise][] + ): Resource { + const res = new ResourceImpl({}); + res._rawAttributes = attributes; + res._asyncAttributesPending = + attributes.filter(([_, val]) => isPromiseLike(val)).length > 0; + return res; + } + + constructor( + /** + * A dictionary of attributes with string keys and values that provide + * information about the entity as numbers, strings or booleans + * TODO: Consider to add check/validation on attributes. + */ + resource: DetectedResource + ) { + const attributes = resource.attributes ?? {}; + this._rawAttributes = Object.entries(attributes).map(([k, v]) => { + if (isPromiseLike(v)) { + // side-effect + this._asyncAttributesPending = true; + } + + return [k, v]; + }); + } + + public get asyncAttributesPending(): boolean { + return this._asyncAttributesPending; + } + + public async waitForAsyncAttributes(): Promise { + if (!this.asyncAttributesPending) { + return; + } + + for (let i = 0; i < this._rawAttributes.length; i++) { + const [k, v] = this._rawAttributes[i]; + try { + this._rawAttributes[i] = [k, isPromiseLike(v) ? await v : v]; + } catch (err) { + diag.debug("a resource's async attributes promise rejected: %s", err); + this._rawAttributes[i] = [k, undefined]; + } + } + + this._asyncAttributesPending = false; + } + + public get attributes(): Attributes { + if (this.asyncAttributesPending) { + diag.error( + 'Accessing resource attributes before async attributes settled' + ); + } + + if (this._memoizedAttributes) { + return this._memoizedAttributes; + } + + const attrs: Attributes = {}; + for (const [k, v] of this._rawAttributes) { + if (isPromiseLike(v)) { + diag.debug(`Unsettled resource attribute ${k} skipped`); + continue; + } + if (v != null) { + attrs[k] ??= v; + } + } + + // only memoize output if all attributes are settled + if (!this._asyncAttributesPending) { + this._memoizedAttributes = attrs; + } + + return attrs; + } + + public getRawAttributes(): RawResourceAttribute[] { + return this._rawAttributes; + } + + public merge(resource: Resource | null): Resource { + if (resource == null) return this; + + // Order is important + // Spec states incoming attributes override existing attributes + return ResourceImpl.FromAttributeList([ + ...resource.getRawAttributes(), + ...this.getRawAttributes(), + ]); + } +} + +export function resourceFromAttributes( + attributes: DetectedResourceAttributes +): Resource { + return ResourceImpl.FromAttributeList(Object.entries(attributes)); +} + +export function resourceFromDetectedResource( + detectedResource: DetectedResource +): Resource { + return new ResourceImpl(detectedResource); +} + +export const EMPTY_RESOURCE = resourceFromAttributes({}); +export const DEFAULT_RESOURCE = resourceFromAttributes({ + [ATTR_SERVICE_NAME]: defaultServiceName(), + [ATTR_TELEMETRY_SDK_LANGUAGE]: SDK_INFO[ATTR_TELEMETRY_SDK_LANGUAGE], + [ATTR_TELEMETRY_SDK_NAME]: SDK_INFO[ATTR_TELEMETRY_SDK_NAME], + [ATTR_TELEMETRY_SDK_VERSION]: SDK_INFO[ATTR_TELEMETRY_SDK_VERSION], +}); diff --git a/packages/opentelemetry-resources/src/detect-resources.ts b/packages/opentelemetry-resources/src/detect-resources.ts index 015e415832c..f4c8305ae58 100644 --- a/packages/opentelemetry-resources/src/detect-resources.ts +++ b/packages/opentelemetry-resources/src/detect-resources.ts @@ -15,8 +15,8 @@ */ import { diag } from '@opentelemetry/api'; -import { IResource } from './IResource'; import { Resource } from './Resource'; +import { EMPTY_RESOURCE, resourceFromDetectedResource } from './ResourceImpl'; import { ResourceDetectionConfig } from './config'; /** @@ -26,15 +26,15 @@ import { ResourceDetectionConfig } from './config'; */ export const detectResources = ( config: ResourceDetectionConfig = {} -): IResource => { - const resources: IResource[] = (config.detectors || []).map(d => { +): Resource => { + const resources: Resource[] = (config.detectors || []).map(d => { try { - const resource = new Resource(d.detect(config)); + const resource = resourceFromDetectedResource(d.detect(config)); diag.debug(`${d.constructor.name} found resource.`, resource); return resource; } catch (e) { diag.debug(`${d.constructor.name} failed: ${e.message}`); - return Resource.EMPTY; + return EMPTY_RESOURCE; } }); @@ -43,7 +43,7 @@ export const detectResources = ( return resources.reduce( (acc, resource) => acc.merge(resource), - Resource.EMPTY + EMPTY_RESOURCE ); }; @@ -52,7 +52,7 @@ export const detectResources = ( * * @param resources The array of {@link Resource} that should be logged. Empty entries will be ignored. */ -const logResources = (resources: Array) => { +const logResources = (resources: Array) => { resources.forEach(resource => { // Print only populated resources if (Object.keys(resource.attributes).length > 0) { diff --git a/packages/opentelemetry-resources/src/index.ts b/packages/opentelemetry-resources/src/index.ts index 812bda333ee..0330c4251b7 100644 --- a/packages/opentelemetry-resources/src/index.ts +++ b/packages/opentelemetry-resources/src/index.ts @@ -23,9 +23,13 @@ export { processDetector, serviceInstanceIdDetector, } from './detectors'; -export { IResource } from './IResource'; -export { defaultServiceName } from './platform'; export { Resource } from './Resource'; +export { + resourceFromAttributes, + DEFAULT_RESOURCE, + EMPTY_RESOURCE, +} from './ResourceImpl'; +export { defaultServiceName } from './platform'; export { ResourceDetector, DetectedResource, diff --git a/packages/opentelemetry-resources/test/Resource.test.ts b/packages/opentelemetry-resources/test/Resource.test.ts index c17e39f19bf..157991519bb 100644 --- a/packages/opentelemetry-resources/test/Resource.test.ts +++ b/packages/opentelemetry-resources/test/Resource.test.ts @@ -24,40 +24,36 @@ import { } from '@opentelemetry/semantic-conventions'; import * as assert from 'assert'; import * as sinon from 'sinon'; -import { Resource } from '../src'; import { describeBrowser, describeNode } from './util'; +import { + DEFAULT_RESOURCE, + EMPTY_RESOURCE, + resourceFromAttributes, +} from '../src'; describe('Resource', () => { - const resource1 = new Resource({ - attributes: { - 'k8s.io/container/name': 'c1', - 'k8s.io/namespace/name': 'default', - 'k8s.io/pod/name': 'pod-xyz-123', - }, + const resource1 = resourceFromAttributes({ + 'k8s.io/container/name': 'c1', + 'k8s.io/namespace/name': 'default', + 'k8s.io/pod/name': 'pod-xyz-123', }); - const resource2 = new Resource({ - attributes: { - 'k8s.io/zone': 'zone1', - 'k8s.io/location': 'location', - }, + const resource2 = resourceFromAttributes({ + 'k8s.io/zone': 'zone1', + 'k8s.io/location': 'location', }); - const resource3 = new Resource({ - attributes: { - 'k8s.io/container/name': 'c2', - 'k8s.io/location': 'location1', - }, + const resource3 = resourceFromAttributes({ + 'k8s.io/container/name': 'c2', + 'k8s.io/location': 'location1', }); - const emptyResource = new Resource({ attributes: {} }); + const emptyResource = resourceFromAttributes({}); it('should return merged resource', () => { - const expectedResource = new Resource({ - attributes: { - 'k8s.io/container/name': 'c1', - 'k8s.io/namespace/name': 'default', - 'k8s.io/pod/name': 'pod-xyz-123', - 'k8s.io/zone': 'zone1', - 'k8s.io/location': 'location', - }, + const expectedResource = resourceFromAttributes({ + 'k8s.io/container/name': 'c1', + 'k8s.io/namespace/name': 'default', + 'k8s.io/pod/name': 'pod-xyz-123', + 'k8s.io/zone': 'zone1', + 'k8s.io/location': 'location', }); const actualResource = resource1.merge(resource2); assert.strictEqual(Object.keys(actualResource.attributes).length, 5); @@ -68,13 +64,11 @@ describe('Resource', () => { }); it('should return merged resource when collision in attributes', () => { - const expectedResource = new Resource({ - attributes: { - 'k8s.io/container/name': 'c2', - 'k8s.io/namespace/name': 'default', - 'k8s.io/pod/name': 'pod-xyz-123', - 'k8s.io/location': 'location1', - }, + const expectedResource = resourceFromAttributes({ + 'k8s.io/container/name': 'c2', + 'k8s.io/namespace/name': 'default', + 'k8s.io/pod/name': 'pod-xyz-123', + 'k8s.io/location': 'location1', }); const actualResource = resource1.merge(resource3); assert.strictEqual(Object.keys(actualResource.attributes).length, 4); @@ -103,12 +97,10 @@ describe('Resource', () => { }); it('should accept string, number, and boolean values', () => { - const resource = new Resource({ - attributes: { - 'custom.string': 'strvalue', - 'custom.number': 42, - 'custom.boolean': true, - }, + const resource = resourceFromAttributes({ + 'custom.string': 'strvalue', + 'custom.number': 42, + 'custom.boolean': true, }); assert.strictEqual(resource.attributes['custom.string'], 'strvalue'); assert.strictEqual(resource.attributes['custom.number'], 42); @@ -117,12 +109,10 @@ describe('Resource', () => { it('should log when accessing attributes before async attributes promise has settled', () => { const debugStub = sinon.spy(diag, 'error'); - const resource = new Resource({ - attributes: { - async: new Promise(resolve => { - setTimeout(resolve, 1); - }), - }, + const resource = resourceFromAttributes({ + async: new Promise(resolve => { + setTimeout(resolve, 1); + }), }); resource.attributes; @@ -140,29 +130,23 @@ describe('Resource', () => { }); it('should return false for asyncAttributesPending if no promise provided', () => { - assert.ok( - !new Resource({ attributes: { foo: 'bar' } }).asyncAttributesPending - ); - assert.ok(!Resource.EMPTY.asyncAttributesPending); - assert.ok(!Resource.default().asyncAttributesPending); + assert.ok(!resourceFromAttributes({ foo: 'bar' }).asyncAttributesPending); + assert.ok(!EMPTY_RESOURCE.asyncAttributesPending); + assert.ok(!DEFAULT_RESOURCE.asyncAttributesPending); }); it('should return false for asyncAttributesPending once promise settles', async () => { - const resourceResolve = new Resource({ - attributes: { - async: new Promise(resolve => { - setTimeout(resolve, 1); - }), - }, + const resourceResolve = resourceFromAttributes({ + async: new Promise(resolve => { + setTimeout(resolve, 1); + }), }); - const resourceReject = new Resource({ - attributes: { - async: new Promise((_, reject) => { - setTimeout(() => { - reject(new Error('reject')); - }, 1); - }), - }, + const resourceReject = resourceFromAttributes({ + async: new Promise((_, reject) => { + setTimeout(() => { + reject(new Error('reject')); + }, 1); + }), }); for (const resource of [resourceResolve, resourceReject]) { @@ -173,14 +157,12 @@ describe('Resource', () => { }); it('should merge async attributes into sync attributes once resolved', async () => { - const resource = new Resource({ - attributes: { - sync: 'fromsync', - // async attribute resolves after 1ms - async: new Promise(resolve => - setTimeout(() => resolve('fromasync'), 1) - ), - }, + const resource = resourceFromAttributes({ + sync: 'fromsync', + // async attribute resolves after 1ms + async: new Promise(resolve => + setTimeout(() => resolve('fromasync'), 1) + ), }); await resource.waitForAsyncAttributes?.(); @@ -191,29 +173,21 @@ describe('Resource', () => { }); it('should merge async attributes when both resources have promises', async () => { - const resource1 = new Resource({ - attributes: { - promise1: Promise.resolve('promise1val'), - shared: Promise.resolve('promise1val'), - }, + const resource1 = resourceFromAttributes({ + promise1: Promise.resolve('promise1val'), + shared: Promise.resolve('promise1val'), }); - const resource2 = new Resource({ - attributes: { - promise2: Promise.resolve('promise2val'), - shared: Promise.resolve('promise2val'), - }, + const resource2 = resourceFromAttributes({ + promise2: Promise.resolve('promise2val'), + shared: Promise.resolve('promise2val'), }); // this one rejects - const resource3 = new Resource({ - attributes: { - err: Promise.reject(new Error('reject')), - }, + const resource3 = resourceFromAttributes({ + err: Promise.reject(new Error('reject')), }); - const resource4 = new Resource({ - attributes: { - promise4: Promise.resolve('promise4val'), - shared: Promise.resolve('promise4val'), - }, + const resource4 = resourceFromAttributes({ + promise4: Promise.resolve('promise4val'), + shared: Promise.resolve('promise4val'), }); const merged = resource1 @@ -232,18 +206,14 @@ describe('Resource', () => { }); it('should merge async attributes correctly when resource1 fulfils after resource2', async () => { - const resource1 = new Resource({ - attributes: { - promise1: Promise.resolve('promise1val'), - shared: Promise.resolve('promise1val'), - }, + const resource1 = resourceFromAttributes({ + promise1: Promise.resolve('promise1val'), + shared: Promise.resolve('promise1val'), }); - const resource2 = new Resource({ - attributes: { - promise2: 'promise2val', - shared: 'promise2val', - }, + const resource2 = resourceFromAttributes({ + promise2: 'promise2val', + shared: 'promise2val', }); const merged = resource1.merge(resource2); @@ -258,18 +228,14 @@ describe('Resource', () => { }); it('should merge async attributes correctly when resource2 fulfils after resource1', async () => { - const resource1 = new Resource({ - attributes: { - promise1: Promise.resolve('promise1val'), - shared: 'promise1val', - }, + const resource1 = resourceFromAttributes({ + promise1: Promise.resolve('promise1val'), + shared: 'promise1val', }); - const resource2 = new Resource({ - attributes: { - promise2: new Promise(res => setTimeout(() => res('promise2val'), 1)), - shared: new Promise(res => setTimeout(() => res('promise2val'), 1)), - }, + const resource2 = resourceFromAttributes({ + promise2: new Promise(res => setTimeout(() => res('promise2val'), 1)), + shared: new Promise(res => setTimeout(() => res('promise2val'), 1)), }); const merged = resource1.merge(resource2); @@ -286,8 +252,8 @@ describe('Resource', () => { it('should log when promise rejects', async () => { const debugStub = sinon.spy(diag, 'debug'); - const resource = new Resource({ - attributes: { rejected: Promise.reject(new Error('rejected')) }, + const resource = resourceFromAttributes({ + rejected: Promise.reject(new Error('rejected')), }); await resource.waitForAsyncAttributes?.(); @@ -301,7 +267,7 @@ describe('Resource', () => { describeNode('.default()', () => { it('should return a default resource', () => { - const resource = Resource.default(); + const resource = DEFAULT_RESOURCE; assert.strictEqual( resource.attributes[SEMRESATTRS_TELEMETRY_SDK_NAME], SDK_INFO[SEMRESATTRS_TELEMETRY_SDK_NAME] @@ -323,7 +289,7 @@ describe('Resource', () => { describeBrowser('.default()', () => { it('should return a default resource', () => { - const resource = Resource.default(); + const resource = DEFAULT_RESOURCE; assert.strictEqual( resource.attributes[SEMRESATTRS_TELEMETRY_SDK_NAME], SDK_INFO[SEMRESATTRS_TELEMETRY_SDK_NAME] diff --git a/packages/opentelemetry-resources/test/detectors/browser/ProcessDetector.test.ts b/packages/opentelemetry-resources/test/detectors/browser/ProcessDetector.test.ts index 8ed0e25c2f0..38e4b3ec3e2 100644 --- a/packages/opentelemetry-resources/test/detectors/browser/ProcessDetector.test.ts +++ b/packages/opentelemetry-resources/test/detectors/browser/ProcessDetector.test.ts @@ -14,9 +14,10 @@ * limitations under the License. */ import * as sinon from 'sinon'; -import { processDetector, Resource } from '../../../src'; +import { processDetector } from '../../../src'; import { describeBrowser } from '../../util'; import { assertEmptyResource } from '../../util/resource-assertions'; +import { resourceFromDetectedResource } from '../../../src/ResourceImpl'; describeBrowser('processDetector() on web browser', () => { afterEach(() => { @@ -24,7 +25,7 @@ describeBrowser('processDetector() on web browser', () => { }); it('should return empty resource', async () => { - const resource = new Resource(processDetector.detect()); + const resource = resourceFromDetectedResource(processDetector.detect()); assertEmptyResource(resource); }); }); diff --git a/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts b/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts index 565af3951f0..229579a6943 100644 --- a/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts +++ b/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts @@ -14,7 +14,8 @@ * limitations under the License. */ -import { envDetector, Resource } from '../../../src'; +import { envDetector } from '../../../src'; +import { resourceFromDetectedResource } from '../../../src/ResourceImpl'; import { describeNode } from '../../util'; import { assertEmptyResource, @@ -33,7 +34,7 @@ describeNode('envDetector() on Node.js', () => { }); it('should return resource information from environment variable', async () => { - const resource = new Resource(envDetector.detect()); + const resource = resourceFromDetectedResource(envDetector.detect()); assertK8sResource(resource, { podName: 'pod-xyz-123', clusterName: 'c1', @@ -57,7 +58,7 @@ describeNode('envDetector() on Node.js', () => { }); it('should return empty resource', async () => { - const resource = new Resource(envDetector.detect()); + const resource = resourceFromDetectedResource(envDetector.detect()); assertEmptyResource(resource); }); }); @@ -66,7 +67,7 @@ describeNode('envDetector() on Node.js', () => { describe('with empty env', () => { it('should return empty resource', async () => { - const resource = new Resource(envDetector.detect()); + const resource = resourceFromDetectedResource(envDetector.detect()); assertEmptyResource(resource); }); }); diff --git a/packages/opentelemetry-resources/test/detectors/node/HostDetector.test.ts b/packages/opentelemetry-resources/test/detectors/node/HostDetector.test.ts index 0cbf54fb40a..8f71c8c3e8b 100644 --- a/packages/opentelemetry-resources/test/detectors/node/HostDetector.test.ts +++ b/packages/opentelemetry-resources/test/detectors/node/HostDetector.test.ts @@ -21,7 +21,8 @@ import { } from '@opentelemetry/semantic-conventions'; import * as assert from 'assert'; import * as sinon from 'sinon'; -import { hostDetector, Resource } from '../../../src'; +import { hostDetector } from '../../../src'; +import { resourceFromDetectedResource } from '../../../src/ResourceImpl'; import { describeNode } from '../../util'; describeNode('hostDetector() on Node.js', () => { @@ -39,7 +40,7 @@ describeNode('hostDetector() on Node.js', () => { sinon.stub(os, 'hostname').returns('opentelemetry-test'); sinon.stub(mid, 'getMachineId').returns(Promise.resolve(expectedHostId)); - const resource = new Resource(hostDetector.detect()); + const resource = resourceFromDetectedResource(hostDetector.detect()); await resource.waitForAsyncAttributes?.(); assert.strictEqual( @@ -58,7 +59,7 @@ describeNode('hostDetector() on Node.js', () => { sinon.stub(os, 'arch').returns('some-unknown-arch'); - const resource = new Resource(hostDetector.detect()); + const resource = resourceFromDetectedResource(hostDetector.detect()); assert.strictEqual( resource.attributes[SEMRESATTRS_HOST_ARCH], @@ -74,7 +75,7 @@ describeNode('hostDetector() on Node.js', () => { sinon.stub(os, 'hostname').returns('opentelemetry-test'); sinon.stub(mid, 'getMachineId').returns(Promise.resolve(undefined)); - const resource = new Resource(hostDetector.detect()); + const resource = resourceFromDetectedResource(hostDetector.detect()); await resource.waitForAsyncAttributes?.(); assert.strictEqual( diff --git a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts index aff253ff38a..c298a395feb 100644 --- a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts +++ b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts @@ -28,7 +28,7 @@ import { W3CTraceContextPropagator, merge, } from '@opentelemetry/core'; -import { IResource, Resource } from '@opentelemetry/resources'; +import { DEFAULT_RESOURCE, Resource } from '@opentelemetry/resources'; import { SpanProcessor } from './SpanProcessor'; import { Tracer } from './Tracer'; import { loadDefaultConfig } from './config'; @@ -53,7 +53,7 @@ function getDefaultPropagators(): TextMapPropagator[] { export class BasicTracerProvider implements TracerProvider { private readonly _config: TracerConfig; private readonly _tracers: Map = new Map(); - private readonly _resource: IResource; + private readonly _resource: Resource; private readonly _activeSpanProcessor: MultiSpanProcessor; constructor(config: TracerConfig = {}) { @@ -62,7 +62,7 @@ export class BasicTracerProvider implements TracerProvider { loadDefaultConfig(), reconfigureLimits(config) ); - this._resource = mergedConfig.resource ?? Resource.default(); + this._resource = mergedConfig.resource ?? DEFAULT_RESOURCE; this._config = Object.assign({}, mergedConfig, { resource: this._resource, diff --git a/packages/opentelemetry-sdk-trace-base/src/Span.ts b/packages/opentelemetry-sdk-trace-base/src/Span.ts index 6098b47f179..e2a365e0be9 100644 --- a/packages/opentelemetry-sdk-trace-base/src/Span.ts +++ b/packages/opentelemetry-sdk-trace-base/src/Span.ts @@ -42,7 +42,7 @@ import { otperformance, sanitizeAttributes, } from '@opentelemetry/core'; -import { IResource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; import { SEMATTRS_EXCEPTION_MESSAGE, SEMATTRS_EXCEPTION_STACKTRACE, @@ -61,7 +61,7 @@ import { SpanLimits } from './types'; export type Span = APISpan & ReadableSpan; interface SpanOptions { - resource: IResource; + resource: Resource; scope: InstrumentationScope; context: Context; spanContext: SpanContext; @@ -88,7 +88,7 @@ export class SpanImpl implements Span { readonly links: Link[] = []; readonly events: TimedEvent[] = []; readonly startTime: HrTime; - readonly resource: IResource; + readonly resource: Resource; readonly instrumentationScope: InstrumentationScope; private _droppedAttributesCount = 0; diff --git a/packages/opentelemetry-sdk-trace-base/src/Tracer.ts b/packages/opentelemetry-sdk-trace-base/src/Tracer.ts index 28f0e91adfa..502f22e1245 100644 --- a/packages/opentelemetry-sdk-trace-base/src/Tracer.ts +++ b/packages/opentelemetry-sdk-trace-base/src/Tracer.ts @@ -27,7 +27,7 @@ import { SpanProcessor } from './SpanProcessor'; import { Sampler } from './Sampler'; import { IdGenerator } from './IdGenerator'; import { RandomIdGenerator } from './platform'; -import { IResource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; /** * This class represents a basic tracer. @@ -39,7 +39,7 @@ export class Tracer implements api.Tracer { private readonly _idGenerator: IdGenerator; readonly instrumentationScope: InstrumentationScope; - private readonly _resource: IResource; + private readonly _resource: Resource; private readonly _spanProcessor: SpanProcessor; /** @@ -48,7 +48,7 @@ export class Tracer implements api.Tracer { constructor( instrumentationScope: InstrumentationScope, config: TracerConfig, - resource: IResource, + resource: Resource, spanProcessor: SpanProcessor ) { const localConfig = mergeConfig(config); diff --git a/packages/opentelemetry-sdk-trace-base/src/export/ReadableSpan.ts b/packages/opentelemetry-sdk-trace-base/src/export/ReadableSpan.ts index 15b4ceff9c0..ec6b33d2eb2 100644 --- a/packages/opentelemetry-sdk-trace-base/src/export/ReadableSpan.ts +++ b/packages/opentelemetry-sdk-trace-base/src/export/ReadableSpan.ts @@ -22,7 +22,7 @@ import { Link, SpanContext, } from '@opentelemetry/api'; -import { IResource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; import { InstrumentationScope } from '@opentelemetry/core'; import { TimedEvent } from '../TimedEvent'; @@ -39,7 +39,7 @@ export interface ReadableSpan { readonly events: TimedEvent[]; readonly duration: HrTime; readonly ended: boolean; - readonly resource: IResource; + readonly resource: Resource; readonly instrumentationScope: InstrumentationScope; readonly droppedAttributesCount: number; readonly droppedEventsCount: number; diff --git a/packages/opentelemetry-sdk-trace-base/src/export/SimpleSpanProcessor.ts b/packages/opentelemetry-sdk-trace-base/src/export/SimpleSpanProcessor.ts index d146c4364c8..b853c01b945 100644 --- a/packages/opentelemetry-sdk-trace-base/src/export/SimpleSpanProcessor.ts +++ b/packages/opentelemetry-sdk-trace-base/src/export/SimpleSpanProcessor.ts @@ -25,7 +25,6 @@ import { Span } from '../Span'; import { SpanProcessor } from '../SpanProcessor'; import { ReadableSpan } from './ReadableSpan'; import { SpanExporter } from './SpanExporter'; -import { Resource } from '@opentelemetry/resources'; /** * An implementation of the {@link SpanProcessor} that converts the {@link Span} @@ -73,7 +72,7 @@ export class SimpleSpanProcessor implements SpanProcessor { private async _doExport(span: ReadableSpan): Promise { if (span.resource.asyncAttributesPending) { // Ensure resource is fully resolved before exporting. - await (span.resource as Resource).waitForAsyncAttributes?.(); + await span.resource.waitForAsyncAttributes?.(); } const result = await internal._export(this._exporter, [span]); diff --git a/packages/opentelemetry-sdk-trace-base/src/types.ts b/packages/opentelemetry-sdk-trace-base/src/types.ts index 9c3bc222a8c..413a5caa1cc 100644 --- a/packages/opentelemetry-sdk-trace-base/src/types.ts +++ b/packages/opentelemetry-sdk-trace-base/src/types.ts @@ -15,7 +15,7 @@ */ import { ContextManager, TextMapPropagator } from '@opentelemetry/api'; -import { IResource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; import { IdGenerator } from './IdGenerator'; import { Sampler } from './Sampler'; import { SpanProcessor } from './SpanProcessor'; @@ -36,7 +36,7 @@ export interface TracerConfig { spanLimits?: SpanLimits; /** Resource associated with trace telemetry */ - resource?: IResource; + resource?: Resource; /** * Generator of trace and span IDs diff --git a/packages/opentelemetry-sdk-trace-base/test/common/BasicTracerProvider.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/BasicTracerProvider.test.ts index d041060c4f6..dfd3802948b 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/BasicTracerProvider.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/BasicTracerProvider.test.ts @@ -30,7 +30,10 @@ import { } from '@opentelemetry/api'; import { CompositePropagator } from '@opentelemetry/core'; import { TraceState } from '@opentelemetry/core'; -import { Resource } from '@opentelemetry/resources'; +import { + DEFAULT_RESOURCE, + resourceFromAttributes, +} from '@opentelemetry/resources'; import * as assert from 'assert'; import * as sinon from 'sinon'; import { @@ -638,7 +641,7 @@ describe('BasicTracerProvider', () => { const tracer = new BasicTracerProvider().getTracer('default'); const span = tracer.startSpan('my-span') as Span; assert.ok(span); - assert.ok(span.resource instanceof Resource); + assert.ok(span.resource); }); }); @@ -726,11 +729,11 @@ describe('BasicTracerProvider', () => { describe('.resource', () => { it('should use the default resource when no resource is provided', function () { const tracerProvider = new BasicTracerProvider(); - assert.deepStrictEqual(tracerProvider['_resource'], Resource.default()); + assert.deepStrictEqual(tracerProvider['_resource'], DEFAULT_RESOURCE); }); it('should use not use the default if resource passed', function () { - const providedResource = new Resource({ attributes: { foo: 'bar' } }); + const providedResource = resourceFromAttributes({ foo: 'bar' }); const tracerProvider = new BasicTracerProvider({ resource: providedResource, }); diff --git a/packages/opentelemetry-sdk-trace-base/test/common/export/BatchSpanProcessorBase.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/export/BatchSpanProcessorBase.test.ts index 2a5b58948e2..657bbd724e2 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/export/BatchSpanProcessorBase.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/export/BatchSpanProcessorBase.test.ts @@ -37,7 +37,7 @@ import { TestRecordOnlySampler } from './TestRecordOnlySampler'; import { TestTracingSpanExporter } from './TestTracingSpanExporter'; import { TestStackContextManager } from './TestStackContextManager'; import { BatchSpanProcessorBase } from '../../../src/export/BatchSpanProcessorBase'; -import { Resource } from '@opentelemetry/resources'; +import { resourceFromAttributes } from '@opentelemetry/resources'; function createSampledSpan(spanName: string): Span { const tracer = new BasicTracerProvider({ @@ -440,12 +440,10 @@ describe('BatchSpanProcessorBase', () => { it('should wait for pending resource on flush', async () => { const tracer = new BasicTracerProvider({ - resource: new Resource({ - attributes: { - async: new Promise(resolve => - setTimeout(() => resolve('fromasync'), 1) - ), - }, + resource: resourceFromAttributes({ + async: new Promise(resolve => + setTimeout(() => resolve('fromasync'), 1) + ), }), }).getTracer('default'); diff --git a/packages/opentelemetry-sdk-trace-base/test/common/export/SimpleSpanProcessor.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/export/SimpleSpanProcessor.test.ts index 257a856a681..7acfb566291 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/export/SimpleSpanProcessor.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/export/SimpleSpanProcessor.test.ts @@ -36,9 +36,9 @@ import { import { SpanImpl } from '../../../src/Span'; import { TestStackContextManager } from './TestStackContextManager'; import { TestTracingSpanExporter } from './TestTracingSpanExporter'; -import { Resource } from '@opentelemetry/resources'; import { TestExporterWithDelay } from './TestExporterWithDelay'; import { Tracer } from '../../../src/Tracer'; +import { resourceFromAttributes } from '@opentelemetry/resources'; describe('SimpleSpanProcessor', () => { let provider: BasicTracerProvider; @@ -175,12 +175,10 @@ describe('SimpleSpanProcessor', () => { it('should await unresolved resources', async () => { const processor = new SimpleSpanProcessor(exporter); const providerWithAsyncResource = new BasicTracerProvider({ - resource: new Resource({ - attributes: { - async: new Promise(resolve => - setTimeout(() => resolve('fromasync'), 1) - ), - }, + resource: resourceFromAttributes({ + async: new Promise(resolve => + setTimeout(() => resolve('fromasync'), 1) + ), }), }); const spanContext: SpanContext = { @@ -255,12 +253,10 @@ describe('SimpleSpanProcessor', () => { const processor = new SimpleSpanProcessor(testExporterWithDelay); const providerWithAsyncResource = new BasicTracerProvider({ - resource: new Resource({ - attributes: { - async: new Promise(resolve => - setTimeout(() => resolve('fromasync'), 1) - ), - }, + resource: resourceFromAttributes({ + async: new Promise(resolve => + setTimeout(() => resolve('fromasync'), 1) + ), }), }); const spanContext: SpanContext = { diff --git a/packages/opentelemetry-sdk-trace-node/test/NodeTracerProvider.test.ts b/packages/opentelemetry-sdk-trace-node/test/NodeTracerProvider.test.ts index 6acf1b16b45..209fe02036e 100644 --- a/packages/opentelemetry-sdk-trace-node/test/NodeTracerProvider.test.ts +++ b/packages/opentelemetry-sdk-trace-node/test/NodeTracerProvider.test.ts @@ -29,7 +29,6 @@ import { AlwaysOnSampler, Span, } from '@opentelemetry/sdk-trace-base'; -import { Resource } from '@opentelemetry/resources'; import { SEMRESATTRS_TELEMETRY_SDK_LANGUAGE } from '@opentelemetry/semantic-conventions'; import { NodeTracerProvider } from '../src/NodeTracerProvider'; @@ -138,7 +137,7 @@ describe('NodeTracerProvider', () => { provider = new NodeTracerProvider(); const span = provider.getTracer('default').startSpan('my-span') as Span; assert.ok(span); - assert.ok(span.resource instanceof Resource); + assert.ok(span.resource); assert.equal( span.resource.attributes[SEMRESATTRS_TELEMETRY_SDK_LANGUAGE], 'nodejs' diff --git a/packages/opentelemetry-sdk-trace-web/test/NodeGlobalsFoolProofing.test.ts b/packages/opentelemetry-sdk-trace-web/test/NodeGlobalsFoolProofing.test.ts index 9b8901a50ef..02afac5f208 100644 --- a/packages/opentelemetry-sdk-trace-web/test/NodeGlobalsFoolProofing.test.ts +++ b/packages/opentelemetry-sdk-trace-web/test/NodeGlobalsFoolProofing.test.ts @@ -20,9 +20,9 @@ import { trace, ProxyTracerProvider, } from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; import * as assert from 'assert'; import { StackContextManager, WebTracerProvider } from '../src'; +import { resourceFromAttributes } from '@opentelemetry/resources'; describe('Node Globals Foolproofing', () => { const originalProcess = globalThis?.process; @@ -69,10 +69,8 @@ describe('Node Globals Foolproofing', () => { }; const tracer = new WebTracerProvider({ - resource: new Resource({ - attributes: { - 'service.name': 'web-core', - }, + resource: resourceFromAttributes({ + 'service.name': 'web-core', }), idGenerator: { generateTraceId: () => getRandomString(32), diff --git a/packages/opentelemetry-sdk-trace-web/test/WebTracerProvider.test.ts b/packages/opentelemetry-sdk-trace-web/test/WebTracerProvider.test.ts index fc598d98e07..4220fcb4e47 100644 --- a/packages/opentelemetry-sdk-trace-web/test/WebTracerProvider.test.ts +++ b/packages/opentelemetry-sdk-trace-web/test/WebTracerProvider.test.ts @@ -16,7 +16,6 @@ import { context, ContextManager, trace } from '@opentelemetry/api'; import { ZoneContextManager } from '@opentelemetry/context-zone'; -import { Resource } from '@opentelemetry/resources'; import { SEMRESATTRS_TELEMETRY_SDK_LANGUAGE } from '@opentelemetry/semantic-conventions'; import { Span } from '@opentelemetry/sdk-trace-base'; import * as assert from 'assert'; @@ -95,7 +94,7 @@ describe('WebTracerProvider', () => { const provider = new WebTracerProvider(); const span = provider.getTracer('default').startSpan('my-span') as Span; assert.ok(span); - assert.ok(span.resource instanceof Resource); + assert.ok(span.resource); assert.equal( span.resource.attributes[SEMRESATTRS_TELEMETRY_SDK_LANGUAGE], 'webjs' diff --git a/packages/sdk-metrics/src/MeterProvider.ts b/packages/sdk-metrics/src/MeterProvider.ts index f201356c05c..d228f7d435f 100644 --- a/packages/sdk-metrics/src/MeterProvider.ts +++ b/packages/sdk-metrics/src/MeterProvider.ts @@ -21,7 +21,7 @@ import { MeterOptions, createNoopMeter, } from '@opentelemetry/api'; -import { IResource, Resource } from '@opentelemetry/resources'; +import { DEFAULT_RESOURCE, Resource } from '@opentelemetry/resources'; import { IMetricReader } from './export/MetricReader'; import { MeterProviderSharedState } from './state/MeterProviderSharedState'; import { MetricCollector } from './state/MetricCollector'; @@ -33,7 +33,7 @@ import { View, ViewOptions } from './view/View'; */ export interface MeterProviderOptions { /** Resource associated with metric telemetry */ - resource?: IResource; + resource?: Resource; views?: ViewOptions[]; readers?: IMetricReader[]; } @@ -47,7 +47,7 @@ export class MeterProvider implements IMeterProvider { constructor(options?: MeterProviderOptions) { this._sharedState = new MeterProviderSharedState( - options?.resource ?? Resource.default() + options?.resource ?? DEFAULT_RESOURCE ); if (options?.views != null && options.views.length > 0) { for (const viewOption of options.views) { diff --git a/packages/sdk-metrics/src/export/MetricData.ts b/packages/sdk-metrics/src/export/MetricData.ts index ecf5a0a62d5..02a94b49899 100644 --- a/packages/sdk-metrics/src/export/MetricData.ts +++ b/packages/sdk-metrics/src/export/MetricData.ts @@ -16,7 +16,7 @@ import { HrTime, Attributes, ValueType } from '@opentelemetry/api'; import { InstrumentationScope } from '@opentelemetry/core'; -import { IResource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; import { AggregationTemporality } from './AggregationTemporality'; import { Histogram, ExponentialHistogram } from '../aggregator/types'; @@ -98,7 +98,7 @@ export interface ScopeMetrics { } export interface ResourceMetrics { - resource: IResource; + resource: Resource; scopeMetrics: ScopeMetrics[]; } diff --git a/packages/sdk-metrics/src/state/MeterProviderSharedState.ts b/packages/sdk-metrics/src/state/MeterProviderSharedState.ts index 116bb121626..058cc62ca08 100644 --- a/packages/sdk-metrics/src/state/MeterProviderSharedState.ts +++ b/packages/sdk-metrics/src/state/MeterProviderSharedState.ts @@ -15,7 +15,7 @@ */ import { InstrumentationScope } from '@opentelemetry/core'; -import { IResource } from '@opentelemetry/resources'; +import { Resource } from '@opentelemetry/resources'; import { instrumentationScopeId } from '../utils'; import { ViewRegistry } from '../view/ViewRegistry'; import { MeterSharedState } from './MeterSharedState'; @@ -34,7 +34,7 @@ export class MeterProviderSharedState { meterSharedStates: Map = new Map(); - constructor(public resource: IResource) {} + constructor(public resource: Resource) {} getMeterSharedState(instrumentationScope: InstrumentationScope) { const id = instrumentationScopeId(instrumentationScope); diff --git a/packages/sdk-metrics/test/Instruments.test.ts b/packages/sdk-metrics/test/Instruments.test.ts index d5703fb0ee7..450a56b1270 100644 --- a/packages/sdk-metrics/test/Instruments.test.ts +++ b/packages/sdk-metrics/test/Instruments.test.ts @@ -17,7 +17,6 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import { InstrumentationScope } from '@opentelemetry/core'; -import { Resource } from '@opentelemetry/resources'; import { DataPoint, DataPointType, @@ -40,6 +39,7 @@ import { } from './util'; import { ObservableResult, ValueType } from '@opentelemetry/api'; import { IMetricReader } from '../src/export/MetricReader'; +import { Resource } from '@opentelemetry/resources'; describe('Instruments', () => { describe('Counter', () => { diff --git a/packages/sdk-metrics/test/MeterProvider.test.ts b/packages/sdk-metrics/test/MeterProvider.test.ts index 18f1efa0b78..c5e64fbb682 100644 --- a/packages/sdk-metrics/test/MeterProvider.test.ts +++ b/packages/sdk-metrics/test/MeterProvider.test.ts @@ -33,7 +33,10 @@ import * as sinon from 'sinon'; import { Meter } from '../src/Meter'; import { createAllowListAttributesProcessor } from '../src/view/AttributesProcessor'; import { AggregationType } from '../src/view/AggregationOption'; -import { Resource } from '@opentelemetry/resources'; +import { + DEFAULT_RESOURCE, + resourceFromAttributes, +} from '@opentelemetry/resources'; describe('MeterProvider', () => { afterEach(() => { @@ -65,12 +68,12 @@ describe('MeterProvider', () => { // Perform collection. const { resourceMetrics } = await reader.collect(); - assert.deepStrictEqual(resourceMetrics.resource, Resource.default()); + assert.deepStrictEqual(resourceMetrics.resource, DEFAULT_RESOURCE); }); it('should use the resource passed in constructor', async function () { const reader = new TestMetricReader(); - const expectedResource = new Resource({ attributes: { foo: 'bar' } }); + const expectedResource = resourceFromAttributes({ foo: 'bar' }); const meterProvider = new MeterProvider({ readers: [reader], @@ -100,7 +103,7 @@ describe('MeterProvider', () => { // Perform collection. const { resourceMetrics } = await reader.collect(); - assert.deepStrictEqual(resourceMetrics.resource, Resource.default()); + assert.deepStrictEqual(resourceMetrics.resource, DEFAULT_RESOURCE); }); }); diff --git a/packages/sdk-metrics/test/export/InMemoryMetricExporter.test.ts b/packages/sdk-metrics/test/export/InMemoryMetricExporter.test.ts index 1b1c114eb90..8a05612f061 100644 --- a/packages/sdk-metrics/test/export/InMemoryMetricExporter.test.ts +++ b/packages/sdk-metrics/test/export/InMemoryMetricExporter.test.ts @@ -14,7 +14,6 @@ * limitations under the License. */ import { ExportResultCode } from '@opentelemetry/core'; -import { Resource } from '@opentelemetry/resources'; import * as metrics from '@opentelemetry/api'; import * as assert from 'assert'; import { AggregationTemporality } from '../../src/export/AggregationTemporality'; @@ -23,6 +22,7 @@ import { ResourceMetrics } from '../../src/export/MetricData'; import { PeriodicExportingMetricReader } from '../../src/export/PeriodicExportingMetricReader'; import { MeterProvider } from '../../src/MeterProvider'; import { defaultResource } from '../util'; +import { resourceFromAttributes } from '@opentelemetry/resources'; async function waitForNumberOfExports( exporter: InMemoryMetricExporter, @@ -69,10 +69,8 @@ describe('InMemoryMetricExporter', () => { it('should return failed result code', done => { exporter.shutdown().then(() => { - const resource = new Resource({ - attributes: { - 'resource-attribute': 'resource attribute value', - }, + const resource = resourceFromAttributes({ + 'resource-attribute': 'resource attribute value', }); const resourceMetrics: ResourceMetrics = { resource: resource, diff --git a/packages/sdk-metrics/test/export/MetricReader.test.ts b/packages/sdk-metrics/test/export/MetricReader.test.ts index f306fdf92e0..b90c48c0e0c 100644 --- a/packages/sdk-metrics/test/export/MetricReader.test.ts +++ b/packages/sdk-metrics/test/export/MetricReader.test.ts @@ -36,7 +36,7 @@ import { } from './utils'; import { defaultResource } from '../util'; import { ValueType } from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; +import { resourceFromAttributes } from '@opentelemetry/resources'; const testScopeMetrics: ScopeMetrics[] = [ { @@ -140,10 +140,8 @@ describe('MetricReader', () => { it('should collect metrics from the SDK and the additional metricProducers', async () => { const additionalProducer = new TestMetricProducer({ resourceMetrics: { - resource: new Resource({ - attributes: { - shouldBeDiscarded: 'should-be-discarded', - }, + resource: resourceFromAttributes({ + shouldBeDiscarded: 'should-be-discarded', }), scopeMetrics: testScopeMetrics, }, diff --git a/packages/sdk-metrics/test/util.ts b/packages/sdk-metrics/test/util.ts index 46049e1aba0..e7a20ed4537 100644 --- a/packages/sdk-metrics/test/util.ts +++ b/packages/sdk-metrics/test/util.ts @@ -22,7 +22,10 @@ import { ValueType, } from '@opentelemetry/api'; import { InstrumentationScope } from '@opentelemetry/core'; -import { Resource } from '@opentelemetry/resources'; +import { + DEFAULT_RESOURCE, + resourceFromAttributes, +} from '@opentelemetry/resources'; import * as assert from 'assert'; import { InstrumentDescriptor } from '../src/InstrumentDescriptor'; import { @@ -43,10 +46,8 @@ export type Measurement = { context?: Context; }; -export const defaultResource = Resource.default().merge( - new Resource({ - attributes: { resourceKey: 'my-resource' }, - }) +export const defaultResource = DEFAULT_RESOURCE.merge( + resourceFromAttributes({ resourceKey: 'my-resource' }) ); export const defaultInstrumentDescriptor: InstrumentDescriptor = {