Skip to content

Commit

Permalink
add resourceFactory option for traces (#938)
Browse files Browse the repository at this point in the history
* add resource factory for traces

* update resource factory docs
  • Loading branch information
seemk authored Aug 28, 2024
1 parent edeea0b commit 1650ee5
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 13 deletions.
2 changes: 2 additions & 0 deletions docs/advanced-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ The following config options can be set by passing them as tracing arguments to

- `tracing.tracerConfig`: A JS object that is merged into the default tracer config replacing any existing keys. It's passed to the tracer provider during initialization. This can be used to customize the tracer provider or tracer. Must satisfy [`TracerConfig` interface](https://github.com/open-telemetry/opentelemetry-js/blob/71ba83a0dc51118e08e3148c788b81fe711003e7/packages/opentelemetry-tracing/src/types.ts#L26)

- `tracing.resourceFactory`: A function that is invoked with the default resource detected from the environment. Can be used to change the detected attributes or return a completely new resource.

- `tracing.spanExporterFactory`: A function that accepts the tracing options. Returns a new instance of SpanExporter. When set, this function is used to create a new exporter and the returned exporter will be used in the pipeline.

- `tracing.spanProcessorFactory`: Returns a SpanProcessor instance or an array of SpanProcessor instances. When set, this function is be used to create one or more span processors. The returned processors are added to the global tracer provider and configured to process all spans generated by any tracer provider by the global provider. The function creates a new span exporter and uses it with each processor it creates. It may call `options.spanExporterFactory(options)` to create a new exporter as configured by the user.
Expand Down
2 changes: 1 addition & 1 deletion src/metrics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ import * as util from 'util';
import { detect as detectResource } from '../resource';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { ConsoleMetricExporter } from './ConsoleMetricExporter';
import type { ResourceFactory } from '../types';

export type MetricReaderFactory = (options: MetricsOptions) => MetricReader[];
export type ResourceFactory = (resource: Resource) => Resource;

interface MetricsOptions {
accessToken: string;
Expand Down
20 changes: 12 additions & 8 deletions src/tracing/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
getNonEmptyEnvVar,
} from '../utils';
import { NodeTracerConfig } from '@opentelemetry/sdk-trace-node';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
import { diag, Span, TextMapPropagator } from '@opentelemetry/api';
import {
CompositePropagator,
Expand All @@ -44,6 +44,7 @@ import {
} from '@opentelemetry/core';
import { SplunkBatchSpanProcessor } from './SplunkBatchSpanProcessor';
import { Resource } from '@opentelemetry/resources';
import type { ResourceFactory } from '../types';

type SpanExporterFactory = (options: Options) => SpanExporter | SpanExporter[];

Expand All @@ -67,6 +68,7 @@ export interface Options {
captureHttpRequestUriParams: string[] | CaptureHttpUriParameters;
instrumentations: (Instrumentation | Instrumentation[])[];
propagatorFactory: PropagatorFactory;
resourceFactory: ResourceFactory;
serverTimingEnabled: boolean;
spanExporterFactory: SpanExporterFactory;
spanProcessorFactory: SpanProcessorFactory;
Expand All @@ -80,6 +82,7 @@ export const allowedTracingOptions = [
'endpoint',
'instrumentations',
'propagatorFactory',
'resourceFactory',
'serverTimingEnabled',
'serviceName',
'spanExporterFactory',
Expand Down Expand Up @@ -115,12 +118,15 @@ export function _setDefaultOptions(options: Partial<Options> = {}): Options {

const extraTracerConfig = options.tracerConfig || {};

let resource = detectResource();
const envResource = detectResource();

const resourceFactory = options.resourceFactory || ((r: Resource) => r);
let resource = resourceFactory(envResource);

const serviceName =
options.serviceName ||
getNonEmptyEnvVar('OTEL_SERVICE_NAME') ||
resource.attributes[SemanticResourceAttributes.SERVICE_NAME];
resource.attributes[SEMRESATTRS_SERVICE_NAME];

if (!serviceName) {
diag.warn(
Expand All @@ -132,8 +138,7 @@ export function _setDefaultOptions(options: Partial<Options> = {}): Options {

resource = resource.merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]:
serviceName || defaultServiceName(),
[SEMRESATTRS_SERVICE_NAME]: serviceName || defaultServiceName(),
})
);

Expand Down Expand Up @@ -172,16 +177,15 @@ export function _setDefaultOptions(options: Partial<Options> = {}): Options {
return {
realm: options.realm,
endpoint: options.endpoint,
serviceName: String(
resource.attributes[SemanticResourceAttributes.SERVICE_NAME]
),
serviceName: String(resource.attributes[SEMRESATTRS_SERVICE_NAME]),
accessToken: options.accessToken,
serverTimingEnabled: options.serverTimingEnabled,
instrumentations: options.instrumentations,
tracerConfig: tracerConfig,
spanExporterFactory: options.spanExporterFactory,
spanProcessorFactory: options.spanProcessorFactory,
propagatorFactory: options.propagatorFactory,
resourceFactory,
captureHttpRequestUriParams: options.captureHttpRequestUriParams,
};
}
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@
* limitations under the License.
*/

import type { Resource } from '@opentelemetry/resources';

export type LogLevel = 'none' | 'verbose' | 'debug' | 'info' | 'warn' | 'error';

export type ResourceFactory = (resource: Resource) => Resource;

export type EnvVarKey =
| 'OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT'
| 'OTEL_BSP_SCHEDULE_DELAY'
Expand Down
28 changes: 24 additions & 4 deletions test/options.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,18 +217,21 @@ describe('options', () => {
const testInstrumentation = new TestInstrumentation('inst', '1.0', {});
const idGenerator = new TestIdGenerator();

const resourceFactory = (resource: Resource) => {
return resource;
};

const options = _setDefaultOptions({
realm: 'rlm',
endpoint: 'custom-endpoint',
serviceName: 'custom-service-name',
accessToken: 'custom-access-token',
instrumentations: [testInstrumentation],
tracerConfig: {
resource: new Resource({
attr1: 'value',
}),
resource: new Resource({ attr1: 'value1' }),
idGenerator: idGenerator,
},
resourceFactory,
spanExporterFactory: testSpanExporterFactory,
spanProcessorFactory: testSpanProcessorFactory,
propagatorFactory: testPropagatorFactory,
Expand All @@ -242,8 +245,9 @@ describe('options', () => {
accessToken: 'custom-access-token',
serverTimingEnabled: true,
instrumentations: [testInstrumentation],
resourceFactory,
tracerConfig: {
resource: new Resource({ attr1: 'value' }),
resource: new Resource({ attr1: 'value1' }),
idGenerator: idGenerator,
},
spanExporterFactory: testSpanExporterFactory,
Expand All @@ -259,6 +263,22 @@ describe('options', () => {
);
});

it('is possible to provide additional resource attributes', () => {
const options = _setDefaultOptions({
resourceFactory: (resource) => {
return resource.merge(
new Resource({ 'splunk.distro.version': 'v9001', abc: 42 })
);
},
});

assert.strictEqual(
options.tracerConfig.resource?.attributes['splunk.distro.version'],
'v9001'
);
assert.strictEqual(options.tracerConfig.resource?.attributes['abc'], 42);
});

describe('OTEL_TRACES_EXPORTER', () => {
it('accepts a single key', () => {
process.env.OTEL_TRACES_EXPORTER = 'console';
Expand Down

0 comments on commit 1650ee5

Please sign in to comment.