@ogcio/o11y-sdk-node 0.4.1 → 0.6.0
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.
- package/dist/sdk-core/index.d.ts +1 -0
- package/dist/sdk-core/index.js +1 -0
- package/dist/sdk-core/lib/index.d.ts +2 -0
- package/dist/sdk-core/lib/index.js +2 -0
- package/dist/sdk-core/lib/redaction/basic-redactor.d.ts +7 -0
- package/dist/sdk-core/lib/redaction/basic-redactor.js +18 -0
- package/dist/sdk-core/lib/redaction/email-redactor.d.ts +8 -0
- package/dist/sdk-core/lib/redaction/email-redactor.js +17 -0
- package/dist/sdk-core/lib/redaction/index.d.ts +9 -0
- package/dist/sdk-core/lib/redaction/index.js +4 -0
- package/dist/sdk-core/lib/redaction/ip-redactor.d.ts +9 -0
- package/dist/sdk-core/lib/redaction/ip-redactor.js +23 -0
- package/dist/sdk-core/lib/redaction/ppsn-redactor.d.ts +8 -0
- package/dist/sdk-core/lib/redaction/ppsn-redactor.js +17 -0
- package/dist/sdk-core/lib/utils/data-structures.d.ts +15 -0
- package/dist/{lib/internals/redaction/pii-detection.js → sdk-core/lib/utils/data-structures.js} +4 -27
- package/dist/sdk-core/lib/utils/index.d.ts +2 -0
- package/dist/sdk-core/lib/utils/index.js +2 -0
- package/dist/sdk-core/lib/utils/string-decoding.d.ts +7 -0
- package/dist/sdk-core/lib/utils/string-decoding.js +22 -0
- package/dist/{index.d.ts → sdk-node/index.d.ts} +1 -0
- package/dist/{index.js → sdk-node/index.js} +1 -0
- package/dist/sdk-node/lib/config-manager.d.ts +3 -0
- package/dist/{lib → sdk-node/lib}/config-manager.js +1 -4
- package/dist/sdk-node/lib/exporter/console.d.ts +3 -0
- package/dist/sdk-node/lib/exporter/grpc.d.ts +3 -0
- package/dist/sdk-node/lib/exporter/http.d.ts +3 -0
- package/dist/{lib → sdk-node/lib}/exporter/index.d.ts +2 -2
- package/dist/{lib → sdk-node/lib}/exporter/pii-exporter-decorator.d.ts +6 -6
- package/dist/{lib → sdk-node/lib}/exporter/pii-exporter-decorator.js +7 -3
- package/dist/sdk-node/lib/exporter/processor-config.d.ts +7 -0
- package/dist/{lib → sdk-node/lib}/exporter/processor-config.js +4 -0
- package/dist/{lib → sdk-node/lib}/index.d.ts +11 -0
- package/dist/{lib → sdk-node/lib}/instrumentation.node.js +1 -1
- package/dist/sdk-node/lib/internals/redaction/redactors/email.d.ts +8 -0
- package/dist/sdk-node/lib/internals/redaction/redactors/email.js +19 -0
- package/dist/sdk-node/lib/internals/redaction/redactors/index.d.ts +16 -0
- package/dist/sdk-node/lib/internals/redaction/redactors/index.js +13 -0
- package/dist/sdk-node/lib/internals/redaction/redactors/ip.d.ts +8 -0
- package/dist/sdk-node/lib/internals/redaction/redactors/ip.js +20 -0
- package/dist/sdk-node/lib/internals/redaction/redactors/ppsn.d.ts +8 -0
- package/dist/sdk-node/lib/internals/redaction/redactors/ppsn.js +18 -0
- package/dist/{lib → sdk-node/lib}/metrics.d.ts +1 -1
- package/dist/{lib → sdk-node/lib}/processor/enrich-logger-processor.d.ts +3 -3
- package/dist/{lib → sdk-node/lib}/processor/enrich-span-processor.d.ts +3 -3
- package/dist/sdk-node/lib/processor/nextjs-logger-processor.d.ts +7 -0
- package/dist/sdk-node/lib/processor/nextjs-logger-processor.js +30 -0
- package/dist/sdk-node/lib/processor/nextjs-span-processor.d.ts +8 -0
- package/dist/sdk-node/lib/processor/nextjs-span-processor.js +25 -0
- package/dist/{lib → sdk-node/lib}/resource.d.ts +2 -2
- package/dist/{lib → sdk-node/lib}/traces.d.ts +1 -1
- package/dist/{lib → sdk-node/lib}/traces.js +2 -2
- package/dist/{lib → sdk-node/lib}/url-sampler.d.ts +3 -3
- package/dist/{lib → sdk-node/lib}/utils.d.ts +1 -1
- package/dist/sdk-node/package.json +62 -0
- package/package.json +25 -22
- package/CHANGELOG.md +0 -226
- package/dist/lib/config-manager.d.ts +0 -3
- package/dist/lib/exporter/console.d.ts +0 -3
- package/dist/lib/exporter/grpc.d.ts +0 -3
- package/dist/lib/exporter/http.d.ts +0 -3
- package/dist/lib/exporter/processor-config.d.ts +0 -5
- package/dist/lib/internals/redaction/pii-detection.d.ts +0 -25
- package/dist/lib/internals/redaction/redactors/email.d.ts +0 -8
- package/dist/lib/internals/redaction/redactors/email.js +0 -48
- package/dist/lib/internals/redaction/redactors/index.d.ts +0 -4
- package/dist/lib/internals/redaction/redactors/index.js +0 -6
- package/dist/lib/internals/redaction/redactors/ip.d.ts +0 -10
- package/dist/lib/internals/redaction/redactors/ip.js +0 -54
- package/dist/lib/internals/shared-metrics.d.ts +0 -7
- package/dist/lib/internals/shared-metrics.js +0 -18
- package/dist/package.json +0 -59
- package/dist/vitest.config.d.ts +0 -2
- package/dist/vitest.config.js +0 -45
- package/index.ts +0 -9
- package/lib/config-manager.ts +0 -16
- package/lib/exporter/console.ts +0 -33
- package/lib/exporter/grpc.ts +0 -65
- package/lib/exporter/http.ts +0 -56
- package/lib/exporter/index.ts +0 -9
- package/lib/exporter/pii-exporter-decorator.ts +0 -187
- package/lib/exporter/processor-config.ts +0 -23
- package/lib/index.ts +0 -118
- package/lib/instrumentation.node.ts +0 -115
- package/lib/internals/hooks.ts +0 -14
- package/lib/internals/redaction/pii-detection.ts +0 -113
- package/lib/internals/redaction/redactors/email.ts +0 -58
- package/lib/internals/redaction/redactors/index.ts +0 -12
- package/lib/internals/redaction/redactors/ip.ts +0 -68
- package/lib/internals/shared-metrics.ts +0 -34
- package/lib/metrics.ts +0 -75
- package/lib/processor/enrich-logger-processor.ts +0 -34
- package/lib/processor/enrich-span-processor.ts +0 -39
- package/lib/resource.ts +0 -30
- package/lib/traces.ts +0 -78
- package/lib/url-sampler.ts +0 -52
- package/lib/utils.ts +0 -22
- package/test/config-manager.test.ts +0 -34
- package/test/exporter/pii-exporter-decorator.test.ts +0 -88
- package/test/index.test.ts +0 -70
- package/test/integration/README.md +0 -26
- package/test/integration/http-tracing.integration.test.ts +0 -56
- package/test/integration/pii.integration.test.ts +0 -68
- package/test/integration/run.sh +0 -88
- package/test/internals/hooks.test.ts +0 -45
- package/test/internals/pii-detection.test.ts +0 -265
- package/test/internals/redactors/email.test.ts +0 -81
- package/test/internals/redactors/ip.test.ts +0 -93
- package/test/internals/shared-metrics.test.ts +0 -34
- package/test/metrics.test.ts +0 -142
- package/test/node-config.test.ts +0 -190
- package/test/processor/enrich-logger-processor.test.ts +0 -58
- package/test/processor/enrich-span-processor.test.ts +0 -52
- package/test/resource.test.ts +0 -33
- package/test/traces/active-span.test.ts +0 -28
- package/test/traces/with-span.test.ts +0 -340
- package/test/url-sampler.test.ts +0 -215
- package/test/utils/alloy-log-parser.ts +0 -53
- package/test/utils/mock-signals.ts +0 -144
- package/test/validation.test.ts +0 -103
- package/tsconfig.json +0 -15
- package/vitest.config.ts +0 -46
- /package/dist/{lib → sdk-node/lib}/exporter/console.js +0 -0
- /package/dist/{lib → sdk-node/lib}/exporter/grpc.js +0 -0
- /package/dist/{lib → sdk-node/lib}/exporter/http.js +0 -0
- /package/dist/{lib → sdk-node/lib}/exporter/index.js +0 -0
- /package/dist/{lib → sdk-node/lib}/index.js +0 -0
- /package/dist/{lib → sdk-node/lib}/instrumentation.node.d.ts +0 -0
- /package/dist/{lib → sdk-node/lib}/internals/hooks.d.ts +0 -0
- /package/dist/{lib → sdk-node/lib}/internals/hooks.js +0 -0
- /package/dist/{lib → sdk-node/lib}/metrics.js +0 -0
- /package/dist/{lib → sdk-node/lib}/processor/enrich-logger-processor.js +0 -0
- /package/dist/{lib → sdk-node/lib}/processor/enrich-span-processor.js +0 -0
- /package/dist/{lib → sdk-node/lib}/resource.js +0 -0
- /package/dist/{lib → sdk-node/lib}/url-sampler.js +0 -0
- /package/dist/{lib → sdk-node/lib}/utils.js +0 -0
package/test/node-config.test.ts
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import { NodeSDK, metrics } from "@opentelemetry/sdk-node";
|
|
2
|
-
import { afterAll, assert, describe, expect, test } from "vitest";
|
|
3
|
-
import buildNodeInstrumentation from "../lib/instrumentation.node.js";
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
BatchLogRecordProcessor,
|
|
7
|
-
SimpleLogRecordProcessor,
|
|
8
|
-
} from "@opentelemetry/sdk-logs";
|
|
9
|
-
import {
|
|
10
|
-
BatchSpanProcessor,
|
|
11
|
-
SimpleSpanProcessor,
|
|
12
|
-
} from "@opentelemetry/sdk-trace-base";
|
|
13
|
-
import buildHttpExporters from "../lib/exporter/http.js";
|
|
14
|
-
import { NodeSDKConfig } from "../lib/index.js";
|
|
15
|
-
import { EnrichLogProcessor } from "../lib/processor/enrich-logger-processor.js";
|
|
16
|
-
import { EnrichSpanProcessor } from "../lib/processor/enrich-span-processor.js";
|
|
17
|
-
import { PIIExporterDecorator } from "../lib/exporter/pii-exporter-decorator.js";
|
|
18
|
-
|
|
19
|
-
describe("verify config settings", () => {
|
|
20
|
-
const commonConfig = {
|
|
21
|
-
collectorUrl: "https://testurl.com",
|
|
22
|
-
serviceName: "test",
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
test("grpc config", async () => {
|
|
26
|
-
const config: NodeSDKConfig = {
|
|
27
|
-
...commonConfig,
|
|
28
|
-
protocol: "grpc",
|
|
29
|
-
collectorMode: "batch",
|
|
30
|
-
diagLogLevel: "NONE",
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const sdk: NodeSDK | undefined = await buildNodeInstrumentation(config);
|
|
34
|
-
|
|
35
|
-
assert.ok(sdk);
|
|
36
|
-
|
|
37
|
-
const _configuration = sdk["_configuration"];
|
|
38
|
-
assert.equal(_configuration.serviceName, commonConfig.serviceName);
|
|
39
|
-
|
|
40
|
-
const logs = _configuration.logRecordProcessors;
|
|
41
|
-
|
|
42
|
-
assert.equal(logs.length, 1);
|
|
43
|
-
assert.ok(logs[logs.length - 1] instanceof BatchLogRecordProcessor);
|
|
44
|
-
|
|
45
|
-
const spans = _configuration.spanProcessors;
|
|
46
|
-
|
|
47
|
-
assert.equal(spans.length, 1);
|
|
48
|
-
assert.ok(spans[0] instanceof BatchSpanProcessor);
|
|
49
|
-
|
|
50
|
-
assert.ok(
|
|
51
|
-
_configuration.metricReader instanceof
|
|
52
|
-
metrics.PeriodicExportingMetricReader,
|
|
53
|
-
);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
test("http config", async () => {
|
|
57
|
-
const config: NodeSDKConfig = {
|
|
58
|
-
...commonConfig,
|
|
59
|
-
protocol: "http",
|
|
60
|
-
diagLogLevel: "NONE",
|
|
61
|
-
spanAttributes: {
|
|
62
|
-
name: "custom-value",
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const sdk: NodeSDK | undefined = await buildNodeInstrumentation(config);
|
|
67
|
-
assert.ok(sdk);
|
|
68
|
-
|
|
69
|
-
const _configuration = sdk["_configuration"];
|
|
70
|
-
assert.equal(_configuration.serviceName, commonConfig.serviceName);
|
|
71
|
-
|
|
72
|
-
const logs = _configuration.logRecordProcessors;
|
|
73
|
-
|
|
74
|
-
assert.equal(logs.length, 2);
|
|
75
|
-
assert.ok(logs[0] instanceof EnrichLogProcessor);
|
|
76
|
-
assert.ok(logs[1] instanceof BatchLogRecordProcessor);
|
|
77
|
-
|
|
78
|
-
const spans = _configuration.spanProcessors;
|
|
79
|
-
|
|
80
|
-
assert.equal(spans.length, 2);
|
|
81
|
-
assert.ok(spans[0] instanceof BatchSpanProcessor);
|
|
82
|
-
assert.ok(spans[1] instanceof EnrichSpanProcessor);
|
|
83
|
-
|
|
84
|
-
assert.ok(
|
|
85
|
-
_configuration.metricReader instanceof
|
|
86
|
-
metrics.PeriodicExportingMetricReader,
|
|
87
|
-
);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
test("console - console config", async () => {
|
|
91
|
-
const config: NodeSDKConfig = {
|
|
92
|
-
...commonConfig,
|
|
93
|
-
protocol: "console",
|
|
94
|
-
diagLogLevel: "NONE",
|
|
95
|
-
spanAttributes: {
|
|
96
|
-
name: "custom-name",
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const sdk: NodeSDK = await buildNodeInstrumentation(config)!;
|
|
101
|
-
assert.ok(sdk);
|
|
102
|
-
|
|
103
|
-
const _configuration = sdk["_configuration"];
|
|
104
|
-
assert.equal(_configuration.serviceName, commonConfig.serviceName);
|
|
105
|
-
|
|
106
|
-
const logs = _configuration.logRecordProcessors;
|
|
107
|
-
|
|
108
|
-
// verify simple log processor for instant console logging
|
|
109
|
-
assert.equal(logs.length, 2);
|
|
110
|
-
assert.ok(logs[0] instanceof EnrichLogProcessor);
|
|
111
|
-
assert.ok(logs[1] instanceof SimpleLogRecordProcessor);
|
|
112
|
-
|
|
113
|
-
const spans = _configuration.spanProcessors;
|
|
114
|
-
|
|
115
|
-
assert.equal(spans.length, 2);
|
|
116
|
-
// verify simple span for instant console logging
|
|
117
|
-
assert.ok(spans[0] instanceof SimpleSpanProcessor);
|
|
118
|
-
assert.ok(spans[1] instanceof EnrichSpanProcessor);
|
|
119
|
-
|
|
120
|
-
assert.ok(
|
|
121
|
-
_configuration.metricReader instanceof
|
|
122
|
-
metrics.PeriodicExportingMetricReader,
|
|
123
|
-
);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
test("single log sending config", async () => {
|
|
127
|
-
const config: NodeSDKConfig = {
|
|
128
|
-
...commonConfig,
|
|
129
|
-
protocol: "grpc",
|
|
130
|
-
diagLogLevel: "NONE",
|
|
131
|
-
collectorMode: "single",
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const sdk: NodeSDK | undefined = await buildNodeInstrumentation(config);
|
|
135
|
-
|
|
136
|
-
assert.ok(sdk);
|
|
137
|
-
|
|
138
|
-
const _configuration = sdk["_configuration"];
|
|
139
|
-
|
|
140
|
-
const logRecordProcessors = _configuration.logRecordProcessors;
|
|
141
|
-
assert.equal(logRecordProcessors.length, 1);
|
|
142
|
-
assert.ok(
|
|
143
|
-
logRecordProcessors[logRecordProcessors.length - 1] instanceof
|
|
144
|
-
SimpleLogRecordProcessor,
|
|
145
|
-
);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test("pii exporter decorator injected by default", async () => {
|
|
149
|
-
const config: NodeSDKConfig = {
|
|
150
|
-
...commonConfig,
|
|
151
|
-
protocol: "grpc",
|
|
152
|
-
diagLogLevel: "NONE",
|
|
153
|
-
collectorMode: "single",
|
|
154
|
-
detection: {},
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
const sdk: NodeSDK | undefined = await buildNodeInstrumentation(config);
|
|
158
|
-
|
|
159
|
-
assert.ok(sdk);
|
|
160
|
-
|
|
161
|
-
const _configuration = sdk["_configuration"];
|
|
162
|
-
|
|
163
|
-
const logRecordProcessors = _configuration.logRecordProcessors;
|
|
164
|
-
assert.equal(logRecordProcessors.length, 1);
|
|
165
|
-
assert.ok(
|
|
166
|
-
logRecordProcessors[logRecordProcessors.length - 1] instanceof
|
|
167
|
-
SimpleLogRecordProcessor,
|
|
168
|
-
);
|
|
169
|
-
assert.ok(
|
|
170
|
-
logRecordProcessors[logRecordProcessors.length - 1][
|
|
171
|
-
"_exporter"
|
|
172
|
-
] instanceof PIIExporterDecorator,
|
|
173
|
-
);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
test("check if clear base endpoint final slash", () => {
|
|
177
|
-
const config: NodeSDKConfig = {
|
|
178
|
-
collectorUrl: "http://example.com/",
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
buildHttpExporters(config);
|
|
182
|
-
|
|
183
|
-
expect(config.collectorUrl).toBe("http://example.com");
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
afterAll(() => {
|
|
187
|
-
// shutdown every instrumentation
|
|
188
|
-
process.emit("SIGTERM");
|
|
189
|
-
});
|
|
190
|
-
});
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
import { LogRecord } from "@opentelemetry/sdk-logs";
|
|
3
|
-
import { EnrichLogProcessor } from "../../lib/processor/enrich-logger-processor.js";
|
|
4
|
-
|
|
5
|
-
const createMockLogRecord = () => {
|
|
6
|
-
return {
|
|
7
|
-
setAttribute: vi.fn(),
|
|
8
|
-
} as unknown as LogRecord;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
describe("EnrichLogProcessor", () => {
|
|
12
|
-
it("should enrich log record with static attributes", () => {
|
|
13
|
-
const attributes = { key1: "value1", key2: 42 };
|
|
14
|
-
const processor = new EnrichLogProcessor(attributes);
|
|
15
|
-
const mockLogRecord = createMockLogRecord();
|
|
16
|
-
|
|
17
|
-
processor.onEmit(mockLogRecord);
|
|
18
|
-
|
|
19
|
-
expect(mockLogRecord.setAttribute).toHaveBeenCalledWith("key1", "value1");
|
|
20
|
-
expect(mockLogRecord.setAttribute).toHaveBeenCalledWith("key2", 42);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it("should enrich log record with dynamic attributes", () => {
|
|
24
|
-
const attributes = {
|
|
25
|
-
key1: () => "dynamicValue",
|
|
26
|
-
key2: () => 100,
|
|
27
|
-
};
|
|
28
|
-
const processor = new EnrichLogProcessor(attributes);
|
|
29
|
-
const mockLogRecord = createMockLogRecord();
|
|
30
|
-
|
|
31
|
-
processor.onEmit(mockLogRecord);
|
|
32
|
-
|
|
33
|
-
expect(mockLogRecord.setAttribute).toHaveBeenCalledWith(
|
|
34
|
-
"key1",
|
|
35
|
-
"dynamicValue",
|
|
36
|
-
);
|
|
37
|
-
expect(mockLogRecord.setAttribute).toHaveBeenCalledWith("key2", 100);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("should not set attributes if no span attributes are provided", () => {
|
|
41
|
-
const processor = new EnrichLogProcessor();
|
|
42
|
-
const mockLogRecord = createMockLogRecord();
|
|
43
|
-
|
|
44
|
-
processor.onEmit(mockLogRecord);
|
|
45
|
-
|
|
46
|
-
expect(mockLogRecord.setAttribute).not.toHaveBeenCalled();
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it("should reject forceFlush", async () => {
|
|
50
|
-
await expect(
|
|
51
|
-
new EnrichLogProcessor().forceFlush(),
|
|
52
|
-
).resolves.toBeUndefined();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should resolve shutdown", async () => {
|
|
56
|
-
await expect(new EnrichLogProcessor().shutdown()).resolves.toBeUndefined();
|
|
57
|
-
});
|
|
58
|
-
});
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { Context } from "@opentelemetry/api";
|
|
2
|
-
import { describe, expect, it } from "vitest";
|
|
3
|
-
import { EnrichSpanProcessor } from "../../lib/processor/enrich-span-processor.js";
|
|
4
|
-
import { MockSpan } from "../utils/mock-signals.js";
|
|
5
|
-
|
|
6
|
-
describe("EnrichSpanProcessor", () => {
|
|
7
|
-
it("should set static attributes on span", () => {
|
|
8
|
-
const spanAttributes = {
|
|
9
|
-
key1: "value1",
|
|
10
|
-
key2: 123,
|
|
11
|
-
};
|
|
12
|
-
const processor = new EnrichSpanProcessor(spanAttributes);
|
|
13
|
-
const mockSpan = new MockSpan();
|
|
14
|
-
const mockContext = {} as Context;
|
|
15
|
-
|
|
16
|
-
processor.onStart(mockSpan, mockContext);
|
|
17
|
-
|
|
18
|
-
expect(mockSpan.attributes["key1"]).toBe("value1");
|
|
19
|
-
expect(mockSpan.attributes["key2"]).toBe(123);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it("should set dynamic attributes on span", () => {
|
|
23
|
-
const spanAttributes = {
|
|
24
|
-
dynamicKey: () => "dynamicValue",
|
|
25
|
-
};
|
|
26
|
-
const processor = new EnrichSpanProcessor(spanAttributes);
|
|
27
|
-
const mockSpan = new MockSpan();
|
|
28
|
-
const mockContext = {} as Context;
|
|
29
|
-
|
|
30
|
-
processor.onStart(mockSpan, mockContext);
|
|
31
|
-
|
|
32
|
-
expect(mockSpan.attributes["dynamicKey"]).toBe("dynamicValue");
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("should not set attributes if none are provided", () => {
|
|
36
|
-
const processor = new EnrichSpanProcessor();
|
|
37
|
-
const mockSpan = new MockSpan();
|
|
38
|
-
const mockContext = {} as Context;
|
|
39
|
-
|
|
40
|
-
processor.onStart(mockSpan, mockContext);
|
|
41
|
-
|
|
42
|
-
expect(mockSpan.attributes["key1"]).toBeUndefined();
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it("default method, should maintain default behaviour", async () => {
|
|
46
|
-
const processor = new EnrichSpanProcessor();
|
|
47
|
-
|
|
48
|
-
expect(processor.onEnd(null!)).toBeUndefined();
|
|
49
|
-
expect(await processor.shutdown()).toBeUndefined();
|
|
50
|
-
expect(await processor.forceFlush()).toBeUndefined();
|
|
51
|
-
});
|
|
52
|
-
});
|
package/test/resource.test.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect } from "vitest";
|
|
2
|
-
import { ObservabilityResourceDetector } from "../lib/resource";
|
|
3
|
-
|
|
4
|
-
describe("ObservabilityResourceDetector", () => {
|
|
5
|
-
test("should return custom resource attribute", () => {
|
|
6
|
-
const detector = new ObservabilityResourceDetector({
|
|
7
|
-
first: "first_value",
|
|
8
|
-
second: "second_value",
|
|
9
|
-
});
|
|
10
|
-
const result = detector.detect();
|
|
11
|
-
|
|
12
|
-
expect(result.attributes).not.toBeNull();
|
|
13
|
-
expect(result.attributes).toHaveProperty("first");
|
|
14
|
-
expect(result.attributes!["first"]).eq("first_value");
|
|
15
|
-
expect(result.attributes).toHaveProperty("second");
|
|
16
|
-
expect(result.attributes!["second"]).eq("second_value");
|
|
17
|
-
// default
|
|
18
|
-
expect(result.attributes).toHaveProperty("o11y.sdk.name");
|
|
19
|
-
expect(result.attributes!["o11y.sdk.name"]).eq("@ogcio/o11y-sdk-node");
|
|
20
|
-
expect(result.attributes).toHaveProperty("o11y.sdk.version");
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
test("should return default resource attribute", () => {
|
|
24
|
-
const detector = new ObservabilityResourceDetector();
|
|
25
|
-
const result = detector.detect();
|
|
26
|
-
|
|
27
|
-
expect(result.attributes).not.toBeNull();
|
|
28
|
-
// default
|
|
29
|
-
expect(result.attributes).toHaveProperty("o11y.sdk.name");
|
|
30
|
-
expect(result.attributes!["o11y.sdk.name"]).eq("@ogcio/o11y-sdk-node");
|
|
31
|
-
expect(result.attributes).toHaveProperty("o11y.sdk.version");
|
|
32
|
-
});
|
|
33
|
-
});
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import * as piiDetection from "../../lib/internals/redaction/pii-detection.js";
|
|
3
|
-
import { getActiveSpan } from "../../lib/traces.js";
|
|
4
|
-
import { MockSpan } from "../utils/mock-signals.js";
|
|
5
|
-
import { setNodeSdkConfig } from "../../lib/config-manager.js";
|
|
6
|
-
|
|
7
|
-
describe("getActiveSpan", () => {
|
|
8
|
-
it("returns undefined if no active span", async () => {
|
|
9
|
-
setNodeSdkConfig({
|
|
10
|
-
serviceName: "unit-test",
|
|
11
|
-
collectorUrl: "http://collector",
|
|
12
|
-
detection: {
|
|
13
|
-
email: false,
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
// Temporarily override
|
|
18
|
-
const opentelemetry = await import("@opentelemetry/api");
|
|
19
|
-
|
|
20
|
-
vi.spyOn(opentelemetry.trace, "getActiveSpan").mockImplementationOnce(
|
|
21
|
-
() => undefined,
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
const span = getActiveSpan();
|
|
25
|
-
|
|
26
|
-
expect(span).toBeUndefined();
|
|
27
|
-
});
|
|
28
|
-
});
|
|
@@ -1,340 +0,0 @@
|
|
|
1
|
-
import { Span, SpanOptions, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
2
|
-
import { TraceState } from "@opentelemetry/core";
|
|
3
|
-
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
4
|
-
import {
|
|
5
|
-
InMemorySpanExporter,
|
|
6
|
-
SimpleSpanProcessor,
|
|
7
|
-
SpanProcessor,
|
|
8
|
-
} from "@opentelemetry/sdk-trace-base";
|
|
9
|
-
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
|
|
10
|
-
import { setNodeSdkConfig } from "../../lib/config-manager.js";
|
|
11
|
-
import { getActiveSpan, withSpan } from "../../lib/traces.js";
|
|
12
|
-
|
|
13
|
-
describe("withSpan", () => {
|
|
14
|
-
let memoryExporter: InMemorySpanExporter;
|
|
15
|
-
let spanProcessor: SpanProcessor;
|
|
16
|
-
let sdk: NodeSDK;
|
|
17
|
-
|
|
18
|
-
beforeAll(() => {
|
|
19
|
-
memoryExporter = new InMemorySpanExporter();
|
|
20
|
-
spanProcessor = new SimpleSpanProcessor(memoryExporter);
|
|
21
|
-
sdk = new NodeSDK({
|
|
22
|
-
spanProcessors: [spanProcessor],
|
|
23
|
-
instrumentations: [],
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
setNodeSdkConfig({
|
|
27
|
-
collectorUrl: "http://localhost:4317",
|
|
28
|
-
});
|
|
29
|
-
sdk.start();
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
afterEach(async () => {
|
|
33
|
-
// Flush any remaining spans
|
|
34
|
-
await spanProcessor.forceFlush();
|
|
35
|
-
// Clean up
|
|
36
|
-
memoryExporter.reset();
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
afterAll(async () => {
|
|
40
|
-
await sdk.shutdown();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("should handle simple synchronous usage", async ({}) => {
|
|
44
|
-
let capturedSpan: Span;
|
|
45
|
-
|
|
46
|
-
await withSpan({
|
|
47
|
-
spanName: "test-sync-span",
|
|
48
|
-
fn: (span: Span) => {
|
|
49
|
-
capturedSpan = span;
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
await spanProcessor.forceFlush();
|
|
54
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
55
|
-
expect(spans).toHaveLength(1);
|
|
56
|
-
expect(spans[0].name).toBe("test-sync-span");
|
|
57
|
-
expect(spans[0].status.code).toBe(SpanStatusCode.OK);
|
|
58
|
-
expect(capturedSpan).toBeTruthy();
|
|
59
|
-
expect(capturedSpan.spanContext().traceId).toBe(
|
|
60
|
-
spans[0].spanContext().traceId,
|
|
61
|
-
);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("should handle synchronous functions that throw errors", async ({}) => {
|
|
65
|
-
const error = new Error("Sync error");
|
|
66
|
-
|
|
67
|
-
await expect(
|
|
68
|
-
withSpan({
|
|
69
|
-
spanName: "test-sync-error-span",
|
|
70
|
-
fn: () => {
|
|
71
|
-
throw error;
|
|
72
|
-
},
|
|
73
|
-
}),
|
|
74
|
-
).rejects.toThrow(error.message);
|
|
75
|
-
|
|
76
|
-
await spanProcessor.forceFlush();
|
|
77
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
78
|
-
expect(spans).toHaveLength(1);
|
|
79
|
-
expect(spans[0].name).toBe("test-sync-error-span");
|
|
80
|
-
expect(spans[0].status.code).toBe(SpanStatusCode.ERROR);
|
|
81
|
-
expect(spans[0].status.message).toBe(error.message);
|
|
82
|
-
expect(spans[0].events).toHaveLength(1);
|
|
83
|
-
expect(spans[0].events[0].name).toBe("exception");
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("should handle asynchronous functions correctly", async ({}) => {
|
|
87
|
-
let capturedSpan: Span;
|
|
88
|
-
|
|
89
|
-
await withSpan({
|
|
90
|
-
spanName: "test-async-span",
|
|
91
|
-
fn: async (span: Span) => {
|
|
92
|
-
capturedSpan = span;
|
|
93
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
94
|
-
return "async-result";
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
await spanProcessor.forceFlush();
|
|
99
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
100
|
-
expect(spans).toHaveLength(1);
|
|
101
|
-
expect(spans[0].name).toBe("test-async-span");
|
|
102
|
-
expect(spans[0].status.code).toBe(SpanStatusCode.OK);
|
|
103
|
-
expect(capturedSpan).toBeTruthy();
|
|
104
|
-
expect(capturedSpan.spanContext().traceId).toBe(
|
|
105
|
-
spans[0].spanContext().traceId,
|
|
106
|
-
);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it("should handle asynchronous functions that reject", async () => {
|
|
110
|
-
const error = new Error("Async error");
|
|
111
|
-
|
|
112
|
-
await expect(
|
|
113
|
-
withSpan({
|
|
114
|
-
spanName: "test-async-error-span",
|
|
115
|
-
fn: async () => {
|
|
116
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
117
|
-
throw error;
|
|
118
|
-
},
|
|
119
|
-
}),
|
|
120
|
-
).rejects.toThrow(error.message);
|
|
121
|
-
|
|
122
|
-
await spanProcessor.forceFlush();
|
|
123
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
124
|
-
expect(spans).toHaveLength(1);
|
|
125
|
-
expect(spans[0].name).toBe("test-async-error-span");
|
|
126
|
-
expect(spans[0].status.code).toBe(SpanStatusCode.ERROR);
|
|
127
|
-
expect(spans[0].status.message).toBe(error.message);
|
|
128
|
-
expect(spans[0].events).toHaveLength(1);
|
|
129
|
-
expect(spans[0].events[0].name).toBe("exception");
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it("should handle non-Error exceptions", async () => {
|
|
133
|
-
const nonErrorException = { message: "Not an error object", code: 500 };
|
|
134
|
-
|
|
135
|
-
await expect(
|
|
136
|
-
withSpan({
|
|
137
|
-
spanName: "test-non-error-span",
|
|
138
|
-
fn: () => {
|
|
139
|
-
throw nonErrorException;
|
|
140
|
-
},
|
|
141
|
-
}),
|
|
142
|
-
).rejects.toEqual(nonErrorException);
|
|
143
|
-
|
|
144
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
145
|
-
expect(spans).toHaveLength(1);
|
|
146
|
-
expect(spans[0].status.code).toBe(SpanStatusCode.ERROR);
|
|
147
|
-
expect(spans[0].status.message).toBe(JSON.stringify(nonErrorException));
|
|
148
|
-
expect(spans[0].events).toHaveLength(1);
|
|
149
|
-
expect(spans[0].events[0].name).toBe("exception");
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it("should ensure span is ended even when errors occur", async () => {
|
|
153
|
-
const error = new Error("Test error");
|
|
154
|
-
|
|
155
|
-
await expect(
|
|
156
|
-
withSpan({
|
|
157
|
-
spanName: "test-finally-span",
|
|
158
|
-
fn: () => {
|
|
159
|
-
throw error;
|
|
160
|
-
},
|
|
161
|
-
}),
|
|
162
|
-
).rejects.toThrow("Test error");
|
|
163
|
-
|
|
164
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
165
|
-
expect(spans).toHaveLength(1);
|
|
166
|
-
expect(spans[0].ended).toBe(true);
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it("should pass span options to tracer", async () => {
|
|
170
|
-
const spanOptions: SpanOptions = {
|
|
171
|
-
attributes: { "custom.attribute": "custom-value" },
|
|
172
|
-
kind: 1,
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
await withSpan({
|
|
176
|
-
spanName: "test-options-span",
|
|
177
|
-
spanOptions,
|
|
178
|
-
fn: () => "result",
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
await spanProcessor.forceFlush();
|
|
182
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
183
|
-
expect(spans).toHaveLength(1);
|
|
184
|
-
expect(spans[0].attributes["custom.attribute"]).toBe("custom-value");
|
|
185
|
-
expect(spans[0].kind).toBe(1);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it("should use custom tracer name", async () => {
|
|
189
|
-
const customTracerName = "custom-tracer";
|
|
190
|
-
|
|
191
|
-
await withSpan({
|
|
192
|
-
traceName: customTracerName,
|
|
193
|
-
spanName: "test-custom-tracer-span",
|
|
194
|
-
fn: () => "result",
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
await spanProcessor.forceFlush();
|
|
198
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
199
|
-
expect(spans).toHaveLength(1);
|
|
200
|
-
expect(spans[0].name).toBe("test-custom-tracer-span");
|
|
201
|
-
expect(spans[0].instrumentationScope.name).toBe(customTracerName);
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it("should use default tracer name when not specified", async () => {
|
|
205
|
-
await withSpan({
|
|
206
|
-
spanName: "test-default-tracer-span",
|
|
207
|
-
fn: () => "result",
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
await spanProcessor.forceFlush();
|
|
211
|
-
const defaultSpans = memoryExporter.getFinishedSpans();
|
|
212
|
-
expect(defaultSpans).toHaveLength(1);
|
|
213
|
-
expect(defaultSpans[0].name).toBe("test-default-tracer-span");
|
|
214
|
-
expect(defaultSpans[0].instrumentationScope.name).toBe("o11y-sdk");
|
|
215
|
-
|
|
216
|
-
memoryExporter.reset();
|
|
217
|
-
|
|
218
|
-
setNodeSdkConfig({
|
|
219
|
-
collectorUrl: "",
|
|
220
|
-
serviceName: "test-service",
|
|
221
|
-
serviceVersion: "v1.0.0",
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
await withSpan({
|
|
225
|
-
spanName: "test-default-tracer-span",
|
|
226
|
-
fn: () => "result",
|
|
227
|
-
});
|
|
228
|
-
await spanProcessor.forceFlush();
|
|
229
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
230
|
-
expect(spans).toHaveLength(1);
|
|
231
|
-
expect(spans[0].name).toBe("test-default-tracer-span");
|
|
232
|
-
expect(spans[0].instrumentationScope.name).toBe("test-service");
|
|
233
|
-
expect(spans[0].instrumentationScope.version).toBe("v1.0.0");
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
it("should allow function to interact with span context", async () => {
|
|
237
|
-
let receivedSpan: Span;
|
|
238
|
-
|
|
239
|
-
await withSpan({
|
|
240
|
-
spanName: "test-span-context",
|
|
241
|
-
fn: (span: Span) => {
|
|
242
|
-
receivedSpan = span;
|
|
243
|
-
span.spanContext().traceState = new TraceState(
|
|
244
|
-
"alpha=aaaaaaaaaaaa,bravo=bbbbbbbbbbbb",
|
|
245
|
-
);
|
|
246
|
-
},
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
await spanProcessor.forceFlush();
|
|
250
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
251
|
-
expect(spans).toHaveLength(1);
|
|
252
|
-
expect(receivedSpan).toBeTruthy();
|
|
253
|
-
expect(receivedSpan.spanContext().traceId).toBe(
|
|
254
|
-
spans[0].spanContext().traceId,
|
|
255
|
-
);
|
|
256
|
-
expect(receivedSpan.spanContext().spanId).toBe(
|
|
257
|
-
spans[0].spanContext().spanId,
|
|
258
|
-
);
|
|
259
|
-
expect(spans[0].spanContext().traceState.serialize()).toStrictEqual(
|
|
260
|
-
"alpha=aaaaaaaaaaaa,bravo=bbbbbbbbbbbb",
|
|
261
|
-
);
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
it("should preserve context across setTimeout", async () => {
|
|
265
|
-
await withSpan({
|
|
266
|
-
spanName: "test-timeout-context",
|
|
267
|
-
fn: async (span: Span) => {
|
|
268
|
-
return new Promise((resolve) => {
|
|
269
|
-
setTimeout(() => {
|
|
270
|
-
getActiveSpan().addEvent("promise-resolved", {
|
|
271
|
-
result: "timeout-result",
|
|
272
|
-
});
|
|
273
|
-
resolve("timeout-result");
|
|
274
|
-
}, 10);
|
|
275
|
-
});
|
|
276
|
-
},
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
let newSpan: Span;
|
|
280
|
-
await trace
|
|
281
|
-
.getTracer("some-tracer")
|
|
282
|
-
.startActiveSpan("other-context", async (span) => {
|
|
283
|
-
newSpan = span;
|
|
284
|
-
span.addEvent("other-context-event", {
|
|
285
|
-
result: "other-context-result",
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
newSpan.addEvent("another-context-event", {
|
|
290
|
-
result: "another-context-result",
|
|
291
|
-
});
|
|
292
|
-
newSpan.setStatus({ code: SpanStatusCode.OK });
|
|
293
|
-
newSpan.end();
|
|
294
|
-
await spanProcessor.forceFlush();
|
|
295
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
296
|
-
expect(spans).toHaveLength(2);
|
|
297
|
-
|
|
298
|
-
const timeoutSpan = spans.find((s) => s.name === "test-timeout-context");
|
|
299
|
-
expect(timeoutSpan.status.code).toBe(SpanStatusCode.OK);
|
|
300
|
-
expect(timeoutSpan.events).toHaveLength(1);
|
|
301
|
-
expect(timeoutSpan.events[0].name).toStrictEqual("promise-resolved");
|
|
302
|
-
|
|
303
|
-
const otherTrackedSpan = spans.find((s) => s.name === "other-context");
|
|
304
|
-
expect(otherTrackedSpan.status.code).toBe(SpanStatusCode.OK);
|
|
305
|
-
expect(otherTrackedSpan.events).toHaveLength(2);
|
|
306
|
-
expect(otherTrackedSpan.events[0].name).toStrictEqual(
|
|
307
|
-
"other-context-event",
|
|
308
|
-
);
|
|
309
|
-
expect(otherTrackedSpan.events[1].name).toStrictEqual(
|
|
310
|
-
"another-context-event",
|
|
311
|
-
);
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
it("should handle nested spans correctly", async () => {
|
|
315
|
-
await withSpan({
|
|
316
|
-
spanName: "outer-span",
|
|
317
|
-
fn: async () => {
|
|
318
|
-
await withSpan({
|
|
319
|
-
spanName: "inner-span",
|
|
320
|
-
fn: async () => {
|
|
321
|
-
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
322
|
-
},
|
|
323
|
-
});
|
|
324
|
-
},
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
await spanProcessor.forceFlush();
|
|
328
|
-
const spans = memoryExporter.getFinishedSpans();
|
|
329
|
-
expect(spans).toHaveLength(2);
|
|
330
|
-
|
|
331
|
-
const innerSpan = spans.find((s) => s.name === "inner-span");
|
|
332
|
-
const outerSpan = spans.find((s) => s.name === "outer-span");
|
|
333
|
-
|
|
334
|
-
expect(innerSpan).toBeTruthy();
|
|
335
|
-
expect(outerSpan).toBeTruthy();
|
|
336
|
-
expect(innerSpan!.parentSpanContext.spanId).toBe(
|
|
337
|
-
outerSpan!.spanContext().spanId,
|
|
338
|
-
);
|
|
339
|
-
});
|
|
340
|
-
});
|