@ogcio/o11y-sdk-node 0.1.0-beta.6 → 0.1.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +59 -0
  3. package/dist/index.d.ts +2 -2
  4. package/dist/index.js +1 -0
  5. package/dist/lib/exporter/console.d.ts +3 -0
  6. package/dist/lib/exporter/console.js +16 -0
  7. package/dist/lib/exporter/grpc.d.ts +3 -0
  8. package/dist/lib/{grpc.js → exporter/grpc.js} +9 -5
  9. package/dist/lib/exporter/http.d.ts +3 -0
  10. package/dist/lib/{http.js → exporter/http.js} +9 -5
  11. package/dist/lib/index.d.ts +17 -5
  12. package/dist/lib/instrumentation.node.js +26 -7
  13. package/dist/lib/options.d.ts +5 -3
  14. package/dist/lib/processor/enrich-span-processor.d.ts +11 -0
  15. package/dist/lib/processor/enrich-span-processor.js +22 -0
  16. package/dist/lib/traces.d.ts +1 -0
  17. package/dist/lib/traces.js +4 -0
  18. package/dist/lib/url-sampler.d.ts +3 -2
  19. package/dist/lib/url-sampler.js +5 -8
  20. package/dist/lib/utils.d.ts +4 -2
  21. package/dist/lib/utils.js +8 -3
  22. package/dist/package.json +18 -14
  23. package/dist/vitest.config.js +15 -1
  24. package/index.ts +2 -2
  25. package/lib/exporter/console.ts +27 -0
  26. package/lib/{grpc.ts → exporter/grpc.ts} +13 -7
  27. package/lib/{http.ts → exporter/http.ts} +13 -7
  28. package/lib/index.ts +24 -4
  29. package/lib/instrumentation.node.ts +48 -9
  30. package/lib/options.ts +5 -3
  31. package/lib/processor/enrich-span-processor.ts +39 -0
  32. package/lib/traces.ts +5 -0
  33. package/lib/url-sampler.ts +13 -14
  34. package/lib/utils.ts +16 -4
  35. package/package.json +18 -14
  36. package/test/enrich-span-processor.test.ts +105 -0
  37. package/test/index.test.ts +9 -0
  38. package/test/integration/integration.test.ts +21 -0
  39. package/test/integration/run.sh +2 -2
  40. package/test/node-config.test.ts +49 -36
  41. package/test/url-sampler.test.ts +215 -0
  42. package/vitest.config.ts +15 -1
  43. package/dist/lib/console.d.ts +0 -3
  44. package/dist/lib/console.js +0 -12
  45. package/dist/lib/grpc.d.ts +0 -3
  46. package/dist/lib/http.d.ts +0 -3
  47. package/lib/console.ts +0 -15
package/lib/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- interface SDKConfig {
1
+ export interface NodeSDKConfig {
2
2
  /**
3
3
  * The opentelemetry collector entrypoint GRPC url.
4
4
  * If the collectoUrl is null or undefined, the instrumentation will not be activated.
@@ -32,9 +32,27 @@ interface SDKConfig {
32
32
  * @default []
33
33
  */
34
34
  ignoreUrls?: SamplerCondition[];
35
- }
36
35
 
37
- export interface NodeSDKConfig extends SDKConfig {
36
+ /**
37
+ * Object containing static properties or functions used to evaluate custom attributes for every logs and traces.
38
+ */
39
+ spanAttributes?: Record<
40
+ string,
41
+ SignalAttributeValue | (() => SignalAttributeValue)
42
+ >;
43
+
44
+ /**
45
+ * Object containing static properties used as resources attributes for the Node SDK initialization.
46
+ */
47
+ resourceAttributes?: Record<string, SignalAttributeValue>;
48
+
49
+ /**
50
+ * Faction value from 0 to 1, used by TraceIdRatioBasedSampler which it deterministically samples a percentage of traces that you pass in as a parameter.
51
+ *
52
+ * @default 1
53
+ */
54
+ traceRatio?: number;
55
+
38
56
  /**
39
57
  * Flag to enable or disable the tracing for node:fs module
40
58
  *
@@ -43,7 +61,7 @@ export interface NodeSDKConfig extends SDKConfig {
43
61
  enableFS?: boolean;
44
62
 
45
63
  /**
46
- * protocol used to send signals.
64
+ * Protocol used to send signals.
47
65
  *
48
66
  * @default grpc
49
67
  */
@@ -55,6 +73,8 @@ export interface SamplerCondition {
55
73
  url: string;
56
74
  }
57
75
 
76
+ export type SignalAttributeValue = string | number | boolean;
77
+
58
78
  export type SDKCollectorMode = "single" | "batch";
59
79
 
60
80
  export type SDKProtocol = "grpc" | "http" | "console";
@@ -1,13 +1,23 @@
1
- import { NodeSDK, resources } from "@opentelemetry/sdk-node";
2
- import type { NodeSDKConfig } from "./index.js";
3
- import type { Exporters } from "./options.js";
4
- import buildHttpExporters from "./http.js";
5
- import buildGrpcExporters from "./grpc.js";
6
- import buildConsoleExporters from "./console.js";
7
- import { diag, DiagConsoleLogger, DiagLogLevel } from "@opentelemetry/api";
1
+ import {
2
+ diag,
3
+ DiagConsoleLogger,
4
+ DiagLogLevel,
5
+ Span,
6
+ } from "@opentelemetry/api";
8
7
  import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
9
8
  import { W3CTraceContextPropagator } from "@opentelemetry/core";
9
+ import { NodeSDK, resources } from "@opentelemetry/sdk-node";
10
+ import {
11
+ AlwaysOffSampler,
12
+ ParentBasedSampler,
13
+ TraceIdRatioBasedSampler,
14
+ } from "@opentelemetry/sdk-trace-base";
10
15
  import packageJson from "../package.json" with { type: "json" };
16
+ import buildConsoleExporters from "./exporter/console.js";
17
+ import buildGrpcExporters from "./exporter/grpc.js";
18
+ import buildHttpExporters from "./exporter/http.js";
19
+ import type { NodeSDKConfig } from "./index.js";
20
+ import type { Exporters } from "./options.js";
11
21
  import { UrlSampler } from "./url-sampler.js";
12
22
 
13
23
  export default function buildNodeInstrumentation(
@@ -44,6 +54,19 @@ export default function buildNodeInstrumentation(
44
54
  exporter = buildGrpcExporters(config);
45
55
  }
46
56
 
57
+ const urlSampler = new UrlSampler(
58
+ config.ignoreUrls,
59
+ new TraceIdRatioBasedSampler(config.traceRatio ?? 1),
60
+ );
61
+
62
+ const mainSampler = new ParentBasedSampler({
63
+ root: urlSampler,
64
+ remoteParentSampled: urlSampler,
65
+ remoteParentNotSampled: new AlwaysOffSampler(),
66
+ localParentSampled: urlSampler,
67
+ localParentNotSampled: new AlwaysOffSampler(),
68
+ });
69
+
47
70
  try {
48
71
  diag.setLogger(
49
72
  new DiagConsoleLogger(),
@@ -56,18 +79,34 @@ export default function buildNodeInstrumentation(
56
79
  resource: new resources.Resource({
57
80
  "o11y.sdk.name": packageJson.name,
58
81
  "o11y.sdk.version": packageJson.version,
82
+ ...config.resourceAttributes,
59
83
  }),
84
+ spanProcessors: exporter.spans,
60
85
  serviceName: config.serviceName,
61
- traceExporter: exporter.traces,
62
86
  metricReader: exporter.metrics,
63
87
  logRecordProcessors: exporter.logs,
64
- sampler: new UrlSampler(config.ignoreUrls),
88
+ sampler: mainSampler,
65
89
  textMapPropagator: new W3CTraceContextPropagator(),
66
90
  instrumentations: [
67
91
  getNodeAutoInstrumentations({
68
92
  "@opentelemetry/instrumentation-fs": {
69
93
  enabled: config.enableFS ?? false,
70
94
  },
95
+ "@opentelemetry/instrumentation-pino": {
96
+ logHook: (
97
+ _span: Span,
98
+ record: Record<string, unknown>,
99
+ _level?: number,
100
+ ) => {
101
+ if (config.spanAttributes != undefined) {
102
+ for (const [key, value] of Object.entries(
103
+ config.spanAttributes,
104
+ )) {
105
+ record[key] = typeof value === "function" ? value() : value;
106
+ }
107
+ }
108
+ },
109
+ },
71
110
  }),
72
111
  ],
73
112
  });
package/lib/options.ts CHANGED
@@ -1,7 +1,9 @@
1
- import type { logs, tracing, metrics } from "@opentelemetry/sdk-node";
1
+ import { LogRecordProcessor } from "@opentelemetry/sdk-logs";
2
+ import type { metrics } from "@opentelemetry/sdk-node";
3
+ import { SpanProcessor } from "@opentelemetry/sdk-trace-base";
2
4
 
3
5
  export type Exporters = {
4
- traces: tracing.SpanExporter;
6
+ spans: SpanProcessor[];
5
7
  metrics: metrics.MetricReader;
6
- logs: logs.LogRecordProcessor[];
8
+ logs: LogRecordProcessor[];
7
9
  };
@@ -0,0 +1,39 @@
1
+ import { Context } from "@opentelemetry/api";
2
+ import {
3
+ ReadableSpan,
4
+ Span,
5
+ SpanProcessor,
6
+ } from "@opentelemetry/sdk-trace-base";
7
+ import { SignalAttributeValue } from "../index.js";
8
+
9
+ export class EnrichSpanProcessor implements SpanProcessor {
10
+ private _spanAttributes:
11
+ | Record<string, SignalAttributeValue | (() => SignalAttributeValue)>
12
+ | undefined;
13
+
14
+ constructor(
15
+ spanAttributes?: Record<
16
+ string,
17
+ SignalAttributeValue | (() => SignalAttributeValue)
18
+ >,
19
+ ) {
20
+ this._spanAttributes = spanAttributes;
21
+ }
22
+
23
+ forceFlush(): Promise<void> {
24
+ return Promise.resolve();
25
+ }
26
+ onStart(span: Span, _context: Context): void {
27
+ if (this._spanAttributes != undefined) {
28
+ for (const [key, value] of Object.entries(this._spanAttributes)) {
29
+ span.setAttribute(key, typeof value === "function" ? value() : value);
30
+ }
31
+ }
32
+ }
33
+ onEnd(_span: ReadableSpan): void {
34
+ return;
35
+ }
36
+ shutdown(): Promise<void> {
37
+ return Promise.resolve();
38
+ }
39
+ }
package/lib/traces.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { trace } from "@opentelemetry/api";
2
+
3
+ export function getActiveSpan() {
4
+ return trace.getActiveSpan();
5
+ }
@@ -1,10 +1,4 @@
1
- import {
2
- Context,
3
- SpanKind,
4
- Link,
5
- Attributes,
6
- isValidTraceId,
7
- } from "@opentelemetry/api";
1
+ import { Attributes, Context, Link, SpanKind } from "@opentelemetry/api";
8
2
  import {
9
3
  Sampler,
10
4
  SamplingDecision,
@@ -14,9 +8,11 @@ import { SamplerCondition } from "./index.js";
14
8
 
15
9
  export class UrlSampler implements Sampler {
16
10
  private _samplerCondition: SamplerCondition[];
11
+ private _nextSampler: Sampler;
17
12
 
18
- constructor(samplerCondition: SamplerCondition[] = []) {
13
+ constructor(samplerCondition: SamplerCondition[] = [], nextSampler: Sampler) {
19
14
  this._samplerCondition = samplerCondition;
15
+ this._nextSampler = nextSampler;
20
16
  }
21
17
 
22
18
  shouldSample(
@@ -41,13 +37,16 @@ export class UrlSampler implements Sampler {
41
37
  }
42
38
  }
43
39
 
44
- return {
45
- decision: isValidTraceId(traceId)
46
- ? SamplingDecision.RECORD_AND_SAMPLED
47
- : SamplingDecision.NOT_RECORD,
48
- };
40
+ return this._nextSampler.shouldSample(
41
+ _context,
42
+ traceId,
43
+ _spanName,
44
+ _spanKind,
45
+ attributes,
46
+ _links,
47
+ );
49
48
  }
50
49
  toString(): string {
51
- throw "UrlSampler";
50
+ return "UrlSampler";
52
51
  }
53
52
  }
package/lib/utils.ts CHANGED
@@ -1,10 +1,22 @@
1
+ import {
2
+ BatchLogRecordProcessor,
3
+ SimpleLogRecordProcessor,
4
+ } from "@opentelemetry/sdk-logs";
1
5
  import { SDKCollectorMode } from "./index.js";
2
- import { logs } from "@opentelemetry/sdk-node";
6
+ import { tracing } from "@opentelemetry/sdk-node";
3
7
 
4
8
  export const LogRecordProcessorMap: Record<
5
9
  SDKCollectorMode,
6
- typeof logs.SimpleLogRecordProcessor | typeof logs.BatchLogRecordProcessor
10
+ typeof SimpleLogRecordProcessor | typeof BatchLogRecordProcessor
7
11
  > = {
8
- single: logs.SimpleLogRecordProcessor,
9
- batch: logs.BatchLogRecordProcessor,
12
+ single: SimpleLogRecordProcessor,
13
+ batch: BatchLogRecordProcessor,
14
+ };
15
+
16
+ export const SpanProcessorMap: Record<
17
+ SDKCollectorMode,
18
+ typeof tracing.SimpleSpanProcessor | typeof tracing.BatchSpanProcessor
19
+ > = {
20
+ single: tracing.SimpleSpanProcessor,
21
+ batch: tracing.BatchSpanProcessor,
10
22
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ogcio/o11y-sdk-node",
3
- "version": "0.1.0-beta.6",
3
+ "version": "0.1.0-beta.7",
4
4
  "description": "Opentelemetry standard instrumentation SDK for NodeJS based project",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -22,27 +22,31 @@
22
22
  "@opentelemetry/api": "^1.9.0",
23
23
  "@opentelemetry/auto-instrumentations-node": "^0.56.0",
24
24
  "@opentelemetry/core": "1.30.1",
25
- "@opentelemetry/exporter-logs-otlp-grpc": "^0.57.1",
26
- "@opentelemetry/exporter-logs-otlp-http": "^0.57.1",
27
- "@opentelemetry/exporter-metrics-otlp-grpc": "^0.57.1",
28
- "@opentelemetry/exporter-metrics-otlp-http": "^0.57.1",
29
- "@opentelemetry/exporter-trace-otlp-grpc": "^0.57.1",
30
- "@opentelemetry/exporter-trace-otlp-http": "^0.57.1",
31
- "@opentelemetry/instrumentation": "^0.57.1",
32
- "@opentelemetry/otlp-exporter-base": "^0.57.1",
25
+ "@opentelemetry/exporter-logs-otlp-grpc": "^0.57.2",
26
+ "@opentelemetry/exporter-logs-otlp-http": "^0.57.2",
27
+ "@opentelemetry/exporter-metrics-otlp-grpc": "^0.57.2",
28
+ "@opentelemetry/exporter-metrics-otlp-http": "^0.57.2",
29
+ "@opentelemetry/exporter-trace-otlp-grpc": "^0.57.2",
30
+ "@opentelemetry/exporter-trace-otlp-http": "^0.57.2",
31
+ "@opentelemetry/instrumentation": "^0.57.2",
32
+ "@opentelemetry/otlp-exporter-base": "^0.57.2",
33
+ "@opentelemetry/sdk-logs": "^0.57.2",
33
34
  "@opentelemetry/sdk-metrics": "^1.30.1",
34
- "@opentelemetry/sdk-node": "^0.57.1",
35
+ "@opentelemetry/sdk-node": "^0.57.2",
35
36
  "@opentelemetry/sdk-trace-base": "^1.30.1"
36
37
  },
37
38
  "devDependencies": {
38
- "@types/node": "^22.12.0",
39
- "@vitest/coverage-v8": "^3.0.4",
39
+ "@types/node": "^22.13.4",
40
+ "@vitest/coverage-v8": "^3.0.5",
40
41
  "tsx": "^4.19.2",
41
42
  "typescript": "^5.7.3",
42
- "vitest": "^3.0.4"
43
+ "vitest": "^3.0.5"
43
44
  },
44
45
  "scripts": {
45
46
  "build": "rm -rf dist && tsc -p tsconfig.json",
46
- "test": "vitest"
47
+ "test": "vitest",
48
+ "test:unit": "vitest --project unit",
49
+ "test:integration": "pnpm --filter @ogcio/o11y run prepare:integration && vitest --project integration",
50
+ "test:integration:dryrun": "vitest --project integration"
47
51
  }
48
52
  }
@@ -0,0 +1,105 @@
1
+ import {
2
+ AttributeValue,
3
+ Context,
4
+ Exception,
5
+ Link,
6
+ Span,
7
+ SpanAttributes,
8
+ SpanAttributeValue,
9
+ SpanContext,
10
+ SpanStatus,
11
+ TimeInput,
12
+ } from "@opentelemetry/api";
13
+ import { describe, expect, it } from "vitest";
14
+ import { EnrichSpanProcessor } from "../lib/processor/enrich-span-processor.js";
15
+
16
+ class MockSpan implements Span {
17
+ public attributes: Record<string, AttributeValue> = {};
18
+
19
+ spanContext(): SpanContext {
20
+ throw new Error("Method not implemented.");
21
+ }
22
+ setAttribute(key: string, value: AttributeValue): this {
23
+ this.attributes[key] = value;
24
+ return this;
25
+ }
26
+ setAttributes(attributes: SpanAttributes): this {
27
+ throw new Error("Method not implemented.");
28
+ }
29
+ addEvent(
30
+ name: string,
31
+ attributesOrStartTime?: SpanAttributes | TimeInput,
32
+ startTime?: TimeInput,
33
+ ): this {
34
+ throw new Error("Method not implemented.");
35
+ }
36
+ addLink(link: Link): this {
37
+ throw new Error("Method not implemented.");
38
+ }
39
+ addLinks(links: Link[]): this {
40
+ throw new Error("Method not implemented.");
41
+ }
42
+ setStatus(status: SpanStatus): this {
43
+ throw new Error("Method not implemented.");
44
+ }
45
+ updateName(name: string): this {
46
+ throw new Error("Method not implemented.");
47
+ }
48
+ end(endTime?: TimeInput): void {
49
+ throw new Error("Method not implemented.");
50
+ }
51
+ isRecording(): boolean {
52
+ throw new Error("Method not implemented.");
53
+ }
54
+ recordException(exception: Exception, time?: TimeInput): void {
55
+ throw new Error("Method not implemented.");
56
+ }
57
+ }
58
+
59
+ describe("EnrichSpanProcessor", () => {
60
+ it("should set static attributes on span", () => {
61
+ const spanAttributes = {
62
+ key1: "value1",
63
+ key2: 123,
64
+ };
65
+ const processor = new EnrichSpanProcessor(spanAttributes);
66
+ const mockSpan = new MockSpan();
67
+ const mockContext = {} as Context;
68
+
69
+ processor.onStart(mockSpan, mockContext);
70
+
71
+ expect(mockSpan.attributes["key1"]).toBe("value1");
72
+ expect(mockSpan.attributes["key2"]).toBe(123);
73
+ });
74
+
75
+ it("should set dynamic attributes on span", () => {
76
+ const spanAttributes = {
77
+ dynamicKey: () => "dynamicValue",
78
+ };
79
+ const processor = new EnrichSpanProcessor(spanAttributes);
80
+ const mockSpan = new MockSpan();
81
+ const mockContext = {} as Context;
82
+
83
+ processor.onStart(mockSpan, mockContext);
84
+
85
+ expect(mockSpan.attributes["dynamicKey"]).toBe("dynamicValue");
86
+ });
87
+
88
+ it("should not set attributes if none are provided", () => {
89
+ const processor = new EnrichSpanProcessor();
90
+ const mockSpan = new MockSpan();
91
+ const mockContext = {} as Context;
92
+
93
+ processor.onStart(mockSpan, mockContext);
94
+
95
+ expect(mockSpan.attributes["key1"]).toBeUndefined();
96
+ });
97
+
98
+ it("default method, should maintain default behaviour", async () => {
99
+ const processor = new EnrichSpanProcessor();
100
+
101
+ expect(processor.onEnd(null!)).toBeUndefined();
102
+ expect(await processor.shutdown()).toBeUndefined();
103
+ expect(await processor.forceFlush()).toBeUndefined();
104
+ });
105
+ });
@@ -12,6 +12,15 @@ describe("instrumentNode", () => {
12
12
  serviceName: "custom-service",
13
13
  collectorUrl: "http://custom-collector.com",
14
14
  protocol: "grpc",
15
+ resourceAttributes: {
16
+ "team.infra.cluster": "dev-01",
17
+ "team.infra.pod": "01",
18
+ "team.service.type": "fastify",
19
+ },
20
+ spanAttributes: {
21
+ "signal.namespace": "example",
22
+ "signal.number": () => "callback",
23
+ },
15
24
  };
16
25
 
17
26
  const buildNodeInstrumentation = await import(
@@ -23,6 +23,27 @@ describe("instrumentation integration test", () => {
23
23
  ) {
24
24
  if (parsedLine["attributes"]["http.target"] === "/api/dummy") {
25
25
  dummy_traces_counter++;
26
+
27
+ // verify global sdk span resource
28
+ assert.equal(
29
+ parsedLine["resource_attributes"]["team.infra.pod"],
30
+ "01",
31
+ );
32
+ assert.equal(
33
+ parsedLine["resource_attributes"]["team.service.type"],
34
+ "fastify",
35
+ );
36
+
37
+ // verify global sdk span attributes
38
+ assert.equal(parsedLine["attributes"]["signal.namespace"], "example");
39
+
40
+ // verify runtime custom span inside dev application
41
+ assert.equal(parsedLine["attributes"]["business.info"], "dummy");
42
+ assert.equal(
43
+ parsedLine["attributes"]["business.request_type"],
44
+ "application/json",
45
+ );
46
+
26
47
  continue;
27
48
  }
28
49
  if (parsedLine["attributes"]["http.target"] === "/api/health") {
@@ -60,9 +60,9 @@ fi
60
60
 
61
61
  if [[ $ERROR_CODE -eq 0 ]]; then
62
62
  sleep 2
63
- curl -X GET -f http://localhost:9091/api/dummy
63
+ curl -X GET -f http://localhost:9091/api/dummy -H 'Content-Type: application/json'
64
64
  sleep 2
65
- curl -X GET -f http://localhost:9091/api/dummy
65
+ curl -X GET -f http://localhost:9091/api/dummy -H 'Content-Type: application/json'
66
66
  fi
67
67
 
68
68
  # sleep N seconds to await instrumentation flow send and receiving signals
@@ -9,7 +9,17 @@ import { OTLPTraceExporter as HTTP_OTLPTraceExporter } from "@opentelemetry/expo
9
9
  import { OTLPMetricExporter as HTTP_OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
10
10
  import { OTLPLogExporter as HTTP_OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
11
11
  import { NodeSDKConfig } from "../lib/index.js";
12
- import buildHttpExporters from "../lib/http.js";
12
+ import buildHttpExporters from "../lib/exporter/http.js";
13
+ import {
14
+ BatchSpanProcessor,
15
+ ConsoleSpanExporter,
16
+ SimpleSpanProcessor,
17
+ } from "@opentelemetry/sdk-trace-base";
18
+ import {
19
+ BatchLogRecordProcessor,
20
+ SimpleLogRecordProcessor,
21
+ } from "@opentelemetry/sdk-logs";
22
+ import { EnrichSpanProcessor } from "../lib/processor/enrich-span-processor.js";
13
23
 
14
24
  describe("verify config settings", () => {
15
25
  const commonConfig = {
@@ -21,6 +31,7 @@ describe("verify config settings", () => {
21
31
  const config: NodeSDKConfig = {
22
32
  ...commonConfig,
23
33
  protocol: "grpc",
34
+ collectorMode: "batch",
24
35
  diagLogLevel: "NONE",
25
36
  };
26
37
 
@@ -31,20 +42,21 @@ describe("verify config settings", () => {
31
42
  const _configuration = sdk["_configuration"];
32
43
  assert.equal(_configuration.serviceName, commonConfig.serviceName);
33
44
 
34
- const traceExporter = _configuration.traceExporter;
45
+ const logs = _configuration.logRecordProcessors;
35
46
 
36
- assert.ok(traceExporter instanceof GRPC_OTLPTraceExporter);
47
+ assert.equal(logs.length, 1);
48
+ assert.ok(logs[0] instanceof BatchLogRecordProcessor);
49
+
50
+ const spans = _configuration.spanProcessors;
51
+
52
+ assert.equal(spans.length, 2);
53
+ assert.ok(spans[0] instanceof BatchSpanProcessor);
54
+ assert.ok(spans[1] instanceof EnrichSpanProcessor);
37
55
 
38
- const logRecordProcessors = _configuration.logRecordProcessors;
39
- assert.equal(logRecordProcessors.length, 1);
40
- // assert default signals sending mode
41
- assert.ok(logRecordProcessors[0] instanceof logs.BatchLogRecordProcessor);
42
56
  assert.ok(
43
- logRecordProcessors[0]["_exporter"] instanceof GRPC_OTLPLogExporter,
57
+ _configuration.metricReader instanceof
58
+ metrics.PeriodicExportingMetricReader,
44
59
  );
45
-
46
- const metricReader = _configuration.metricReader;
47
- assert.ok(metricReader._exporter instanceof GRPC_OTLPMetricExporter);
48
60
  });
49
61
 
50
62
  test("http config", () => {
@@ -60,19 +72,21 @@ describe("verify config settings", () => {
60
72
  const _configuration = sdk["_configuration"];
61
73
  assert.equal(_configuration.serviceName, commonConfig.serviceName);
62
74
 
63
- const traceExporter = _configuration.traceExporter;
64
- assert.ok(traceExporter instanceof HTTP_OTLPTraceExporter);
75
+ const logs = _configuration.logRecordProcessors;
76
+
77
+ assert.equal(logs.length, 1);
78
+ assert.ok(logs[0] instanceof BatchLogRecordProcessor);
79
+
80
+ const spans = _configuration.spanProcessors;
81
+
82
+ assert.equal(spans.length, 2);
83
+ assert.ok(spans[0] instanceof BatchSpanProcessor);
84
+ assert.ok(spans[1] instanceof EnrichSpanProcessor);
65
85
 
66
- const logRecordProcessors = _configuration.logRecordProcessors;
67
- assert.equal(logRecordProcessors.length, 1);
68
- // assert default signals sending mode
69
- assert.ok(logRecordProcessors[0] instanceof logs.BatchLogRecordProcessor);
70
86
  assert.ok(
71
- logRecordProcessors[0]["_exporter"] instanceof HTTP_OTLPLogExporter,
87
+ _configuration.metricReader instanceof
88
+ metrics.PeriodicExportingMetricReader,
72
89
  );
73
-
74
- const metricReader = _configuration.metricReader;
75
- assert.ok(metricReader._exporter instanceof HTTP_OTLPMetricExporter);
76
90
  });
77
91
 
78
92
  test("console - console config", () => {
@@ -82,30 +96,29 @@ describe("verify config settings", () => {
82
96
  diagLogLevel: "NONE",
83
97
  };
84
98
 
85
- const sdk: NodeSDK | undefined = buildNodeInstrumentation(config);
99
+ const sdk: NodeSDK = buildNodeInstrumentation(config)!;
86
100
  assert.ok(sdk);
87
101
 
88
102
  const _configuration = sdk["_configuration"];
89
103
  assert.equal(_configuration.serviceName, commonConfig.serviceName);
90
104
 
91
- const traceExporter = _configuration.traceExporter;
105
+ const logs = _configuration.logRecordProcessors;
92
106
 
93
- assert.ok(traceExporter instanceof tracing.ConsoleSpanExporter);
94
- assert.isUndefined(traceExporter._transport);
107
+ // verify simple log processor for instant console logging
108
+ assert.equal(logs.length, 1);
109
+ assert.ok(logs[0] instanceof SimpleLogRecordProcessor);
95
110
 
96
- const logRecordProcessors = _configuration.logRecordProcessors;
97
- assert.equal(logRecordProcessors.length, 1);
111
+ const spans = _configuration.spanProcessors;
112
+
113
+ assert.equal(spans.length, 2);
114
+ // verify simple span for instant console logging
115
+ assert.ok(spans[0] instanceof SimpleSpanProcessor);
116
+ assert.ok(spans[1] instanceof EnrichSpanProcessor);
98
117
 
99
- assert.ok(logRecordProcessors[0] instanceof logs.SimpleLogRecordProcessor);
100
118
  assert.ok(
101
- logRecordProcessors[0]["_exporter"] instanceof
102
- logs.ConsoleLogRecordExporter,
119
+ _configuration.metricReader instanceof
120
+ metrics.PeriodicExportingMetricReader,
103
121
  );
104
- assert.isUndefined(logRecordProcessors[0]["_exporter"]._transport);
105
-
106
- const metricReader = _configuration.metricReader;
107
- assert.ok(metricReader._exporter instanceof metrics.ConsoleMetricExporter);
108
- assert.isUndefined(metricReader._exporter._transport);
109
122
  });
110
123
 
111
124
  test("single log sending config", () => {
@@ -124,7 +137,7 @@ describe("verify config settings", () => {
124
137
 
125
138
  const logRecordProcessors = _configuration.logRecordProcessors;
126
139
  assert.equal(logRecordProcessors.length, 1);
127
- assert.ok(logRecordProcessors[0] instanceof logs.SimpleLogRecordProcessor);
140
+ assert.ok(logRecordProcessors[0] instanceof SimpleLogRecordProcessor);
128
141
  });
129
142
 
130
143
  test("check if clear base endpoint final slash", () => {