Skip to content

Commit

Permalink
Merge branch 'main' into print-message-when-logrecord-attribute-dropped
Browse files Browse the repository at this point in the history
  • Loading branch information
pichlermarc committed Apr 15, 2024
2 parents d8802b6 + fab27d5 commit f39a20f
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 31 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/

### :rocket: (Enhancement)

feat(sdk-trace-base): log resource attributes in ConsoleSpanExporter [#4605](https://github.com/open-telemetry/opentelemetry-js/pull/4605) @pichlermarc
* feat(sdk-trace-base): log resource attributes in ConsoleSpanExporter [#4605](https://github.com/open-telemetry/opentelemetry-js/pull/4605) @pichlermarc
* feat(resources): new experimental detector ServiceInstanceIdDetectorSync that sets the value for `service.instance.id` as random UUID.

### :bug: (Bug Fix)

Expand Down
91 changes: 86 additions & 5 deletions experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
processDetector,
hostDetector,
Resource,
serviceInstanceIdDetectorSync,
} from '@opentelemetry/resources';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { logs } from '@opentelemetry/api-logs';
Expand All @@ -70,6 +71,7 @@ import {
import {
SEMRESATTRS_HOST_NAME,
SEMRESATTRS_PROCESS_PID,
SEMRESATTRS_SERVICE_INSTANCE_ID,
} from '@opentelemetry/semantic-conventions';

const DefaultContextManager = semver.gte(process.version, '14.8.0')
Expand Down Expand Up @@ -126,6 +128,7 @@ describe('Node SDK', () => {
assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider));
assert.ok(!(logs.getLoggerProvider() instanceof LoggerProvider));
delete env.OTEL_TRACES_EXPORTER;
await sdk.shutdown();
});

it('should register a diag logger with OTEL_LOG_LEVEL', () => {
Expand All @@ -145,6 +148,7 @@ describe('Node SDK', () => {
});

delete env.OTEL_LOG_LEVEL;
sdk.shutdown();
});

it('should not register a diag logger with OTEL_LOG_LEVEL unset', () => {
Expand All @@ -158,6 +162,7 @@ describe('Node SDK', () => {
sdk.start();

assert.strictEqual(spy.callCount, 0);
sdk.shutdown();
});

it('should register a tracer provider if an exporter is provided', async () => {
Expand All @@ -180,6 +185,7 @@ describe('Node SDK', () => {
const apiTracerProvider =
trace.getTracerProvider() as ProxyTracerProvider;
assert.ok(apiTracerProvider.getDelegate() instanceof NodeTracerProvider);
await sdk.shutdown();
});

it('should register a tracer provider if an exporter is provided via env', async () => {
Expand All @@ -203,6 +209,7 @@ describe('Node SDK', () => {
trace.getTracerProvider() as ProxyTracerProvider;
assert.ok(apiTracerProvider.getDelegate() instanceof NodeTracerProvider);
delete env.OTEL_TRACES_EXPORTER;
await sdk.shutdown();
});

it('should register a tracer provider if span processors are provided', async () => {
Expand Down Expand Up @@ -240,6 +247,7 @@ describe('Node SDK', () => {
assert(listOfProcessors[0] instanceof NoopSpanProcessor);
assert(listOfProcessors[1] instanceof SimpleSpanProcessor);
assert(listOfProcessors[2] instanceof BatchSpanProcessor);
await sdk.shutdown();
});

it('should register a meter provider if a reader is provided', async () => {
Expand Down Expand Up @@ -446,6 +454,7 @@ describe('Node SDK', () => {
namespace: 'default',
version: '0.0.1',
});
await sdk.shutdown();
});
});

Expand Down Expand Up @@ -497,6 +506,7 @@ describe('Node SDK', () => {
namespace: 'default',
version: '0.0.1',
});
await sdk.shutdown();
});
});

Expand Down Expand Up @@ -551,6 +561,7 @@ describe('Node SDK', () => {
/{\s+"service\.instance\.id":\s+"627cc493",\s+"service\.name":\s+"my-service",\s+"service\.namespace":\s+"default",\s+"service\.version":\s+"0.0.1"\s+}\s*/gm
)
);
await sdk.shutdown();
});

describe('with a faulty environment variable', () => {
Expand Down Expand Up @@ -578,6 +589,7 @@ describe('Node SDK', () => {
'EnvDetector failed: Attribute value should be a ASCII string with a length not exceed 255 characters.'
)
);
await sdk.shutdown();
});
});
});
Expand All @@ -595,6 +607,7 @@ describe('Node SDK', () => {
assertServiceResource(resource, {
name: 'config-set-name',
});
await sdk.shutdown();
});

it('should configure service name via OTEL_SERVICE_NAME env var', async () => {
Expand All @@ -609,6 +622,7 @@ describe('Node SDK', () => {
name: 'env-set-name',
});
delete process.env.OTEL_SERVICE_NAME;
await sdk.shutdown();
});

it('should favor config set service name over OTEL_SERVICE_NAME env set service name', async () => {
Expand All @@ -625,11 +639,12 @@ describe('Node SDK', () => {
name: 'config-set-name',
});
delete process.env.OTEL_SERVICE_NAME;
await sdk.shutdown();
});

it('should configure service name via OTEL_RESOURCE_ATTRIBUTES env var', async () => {
process.env.OTEL_RESOURCE_ATTRIBUTES =
'service.name=resource-env-set-name';
'service.name=resource-env-set-name,service.instance.id=my-instance-id';
const sdk = new NodeSDK();

sdk.start();
Expand All @@ -638,13 +653,15 @@ describe('Node SDK', () => {

assertServiceResource(resource, {
name: 'resource-env-set-name',
instanceId: 'my-instance-id',
});
delete process.env.OTEL_RESOURCE_ATTRIBUTES;
await sdk.shutdown();
});

it('should favor config set service name over OTEL_RESOURCE_ATTRIBUTES env set service name', async () => {
process.env.OTEL_RESOURCE_ATTRIBUTES =
'service.name=resource-env-set-name';
'service.name=resource-env-set-name,service.instance.id=my-instance-id';
const sdk = new NodeSDK({
serviceName: 'config-set-name',
});
Expand All @@ -655,8 +672,55 @@ describe('Node SDK', () => {

assertServiceResource(resource, {
name: 'config-set-name',
instanceId: 'my-instance-id',
});
delete process.env.OTEL_RESOURCE_ATTRIBUTES;
await sdk.shutdown();
});
});

describe('configureServiceInstanceId', async () => {
it('should configure service instance id via OTEL_RESOURCE_ATTRIBUTES env var', async () => {
process.env.OTEL_RESOURCE_ATTRIBUTES =
'service.instance.id=627cc493,service.name=my-service';
const sdk = new NodeSDK();

sdk.start();
const resource = sdk['_resource'];
await resource.waitForAsyncAttributes?.();

assertServiceResource(resource, {
name: 'my-service',
instanceId: '627cc493',
});
delete process.env.OTEL_RESOURCE_ATTRIBUTES;
sdk.shutdown();
});

it('should configure service instance id with random UUID', async () => {
const sdk = new NodeSDK({
autoDetectResources: true,
resourceDetectors: [
processDetector,
envDetector,
hostDetector,
serviceInstanceIdDetectorSync,
],
});

sdk.start();
const resource = sdk['_resource'];
await resource.waitForAsyncAttributes?.();

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(
UUID_REGEX.test(
resource.attributes[SEMRESATTRS_SERVICE_INSTANCE_ID]?.toString() || ''
),
true
);
await sdk.shutdown();
});
});

Expand All @@ -671,7 +735,7 @@ describe('Node SDK', () => {

it('should not register a trace provider', async () => {
const sdk = new NodeSDK({});
await sdk.start();
sdk.start();

assert.strictEqual(
(trace.getTracerProvider() as ProxyTracerProvider).getDelegate(),
Expand All @@ -694,7 +758,7 @@ describe('Node SDK', () => {
metricReader: metricReader,
autoDetectResources: false,
});
await sdk.start();
sdk.start();

assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider));

Expand Down Expand Up @@ -730,6 +794,7 @@ describe('Node SDK', () => {
await resource.waitForAsyncAttributes?.();

assert.deepStrictEqual(resource, Resource.empty());
await sdk.shutdown();
});
});
});
Expand Down Expand Up @@ -758,6 +823,7 @@ describe('Node SDK', () => {

assert.strictEqual(span.spanContext().spanId, 'constant-test-span-id');
assert.strictEqual(span.spanContext().traceId, 'constant-test-trace-id');
await sdk.shutdown();
});
});
});
Expand Down Expand Up @@ -786,6 +852,7 @@ describe('setup exporter from env', () => {
assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters);
assert(listOfProcessors.length === 1);
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
await sdk.shutdown();
});
it('ignore env exporter when user provides exporter to sdk config', async () => {
const traceExporter = new ConsoleSpanExporter();
Expand All @@ -802,6 +869,7 @@ describe('setup exporter from env', () => {
assert(listOfProcessors.length === 1);
assert(listOfProcessors[0] instanceof SimpleSpanProcessor === false);
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
await sdk.shutdown();
});
it('ignores default env exporter when user provides span processor to sdk config', async () => {
const traceExporter = new ConsoleSpanExporter();
Expand All @@ -819,6 +887,7 @@ describe('setup exporter from env', () => {
assert(listOfProcessors.length === 1);
assert(listOfProcessors[0] instanceof SimpleSpanProcessor);
assert(listOfProcessors[0] instanceof BatchSpanProcessor === false);
await sdk.shutdown();
});
it('ignores env exporter when user provides tracer exporter to sdk config and sets exporter via env', async () => {
env.OTEL_TRACES_EXPORTER = 'console';
Expand All @@ -837,6 +906,7 @@ describe('setup exporter from env', () => {
assert(listOfProcessors[0] instanceof SimpleSpanProcessor === false);
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
delete env.OTEL_TRACES_EXPORTER;
await sdk.shutdown();
});
it('should only create one span processor when configured using env vars and config', async () => {
env.OTEL_TRACES_EXPORTER = 'console';
Expand All @@ -852,6 +922,7 @@ describe('setup exporter from env', () => {
);
assert.strictEqual(listOfProcessors.length, 1);
delete env.OTEL_TRACES_EXPORTER;
await sdk.shutdown();
});
it('use otlp exporter and defined exporter protocol env value', async () => {
env.OTEL_TRACES_EXPORTER = 'otlp';
Expand All @@ -866,6 +937,7 @@ describe('setup exporter from env', () => {
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
delete env.OTEL_TRACES_EXPORTER;
delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL;
await sdk.shutdown();
});
it('use noop span processor when user sets env exporter to none', async () => {
env.OTEL_TRACES_EXPORTER = 'none';
Expand All @@ -879,6 +951,7 @@ describe('setup exporter from env', () => {
assert(listOfProcessors.length === 0);
assert(activeProcessor instanceof NoopSpanProcessor);
delete env.OTEL_TRACES_EXPORTER;
await sdk.shutdown();
});
it('log warning that sdk will not be initialized when exporter is set to none', async () => {
env.OTEL_TRACES_EXPORTER = 'none';
Expand All @@ -890,16 +963,18 @@ describe('setup exporter from env', () => {
'OTEL_TRACES_EXPORTER contains "none". SDK will not be initialized.'
);
delete env.OTEL_TRACES_EXPORTER;
await sdk.shutdown();
});
it('use default otlp exporter when user does not set exporter via env or config', async () => {
const sdk = new NodeSDK();
await sdk.start();
sdk.start();

const listOfProcessors =
sdk['_tracerProvider']!['_registeredSpanProcessors']!;
assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters);
assert(listOfProcessors.length === 1);
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
await sdk.shutdown();
});
it('use default otlp exporter when empty value is provided for exporter via env', async () => {
env.OTEL_TRACES_EXPORTER = '';
Expand All @@ -912,6 +987,7 @@ describe('setup exporter from env', () => {
assert(listOfProcessors.length === 1);
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
env.OTEL_TRACES_EXPORTER = '';
await sdk.shutdown();
});

it('use only default exporter when none value is provided with other exporters', async () => {
Expand All @@ -926,6 +1002,7 @@ describe('setup exporter from env', () => {
assert(listOfProcessors[0] instanceof BatchSpanProcessor);

delete env.OTEL_TRACES_EXPORTER;
await sdk.shutdown();
});
it('log warning that only default exporter will be used since exporter list contains none with other exports ', async () => {
env.OTEL_TRACES_EXPORTER = 'otlp,zipkin,none';
Expand All @@ -937,6 +1014,7 @@ describe('setup exporter from env', () => {
'OTEL_TRACES_EXPORTER contains "none" along with other exporters. Using default otlp exporter.'
);
delete env.OTEL_TRACES_EXPORTER;
await sdk.shutdown();
});
it('should warn that provided exporter value is unrecognized and not able to be set up', async () => {
env.OTEL_TRACES_EXPORTER = 'invalid';
Expand All @@ -954,6 +1032,7 @@ describe('setup exporter from env', () => {
);

delete env.OTEL_TRACES_EXPORTER;
await sdk.shutdown();
});
it('setup zipkin, jaeger and otlp exporters', async () => {
env.OTEL_TRACES_EXPORTER = 'zipkin, otlp, jaeger';
Expand All @@ -971,6 +1050,7 @@ describe('setup exporter from env', () => {

delete env.OTEL_TRACES_EXPORTER;
delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL;
await sdk.shutdown();
});
it('use the console exporter', async () => {
env.OTEL_TRACES_EXPORTER = 'console, otlp';
Expand All @@ -983,5 +1063,6 @@ describe('setup exporter from env', () => {
assert(listOfProcessors[0] instanceof SimpleSpanProcessor);
assert(listOfProcessors[1] instanceof BatchSpanProcessor);
delete env.OTEL_TRACES_EXPORTER;
await sdk.shutdown();
});
});
15 changes: 0 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f39a20f

Please sign in to comment.