@ogcio/o11y-sdk-node 0.1.0-beta.9 → 0.3.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/CHANGELOG.md +128 -0
- package/README.md +158 -13
- package/dist/lib/config-manager.d.ts +3 -0
- package/dist/lib/config-manager.js +11 -0
- package/dist/lib/exporter/console.js +3 -4
- package/dist/lib/exporter/grpc.d.ts +1 -1
- package/dist/lib/exporter/grpc.js +24 -14
- package/dist/lib/exporter/http.d.ts +1 -1
- package/dist/lib/exporter/http.js +14 -13
- package/dist/lib/exporter/pii-exporter-decorator.d.ts +20 -0
- package/dist/lib/exporter/pii-exporter-decorator.js +103 -0
- package/dist/lib/exporter/processor-config.d.ts +5 -0
- package/dist/lib/exporter/processor-config.js +16 -0
- package/dist/lib/index.d.ts +25 -4
- package/dist/lib/instrumentation.node.d.ts +1 -1
- package/dist/lib/instrumentation.node.js +29 -19
- package/dist/lib/internals/hooks.d.ts +3 -0
- package/dist/lib/internals/hooks.js +12 -0
- package/dist/lib/internals/pii-detection.d.ts +17 -0
- package/dist/lib/internals/pii-detection.js +116 -0
- package/dist/lib/internals/shared-metrics.d.ts +7 -0
- package/dist/lib/internals/shared-metrics.js +18 -0
- package/dist/lib/resource.js +2 -2
- package/dist/lib/traces.d.ts +20 -1
- package/dist/lib/traces.js +47 -1
- package/dist/package.json +23 -21
- package/dist/vitest.config.js +8 -2
- package/lib/config-manager.ts +16 -0
- package/lib/exporter/console.ts +6 -4
- package/lib/exporter/grpc.ts +46 -20
- package/lib/exporter/http.ts +33 -20
- package/lib/exporter/pii-exporter-decorator.ts +152 -0
- package/lib/exporter/processor-config.ts +23 -0
- package/lib/index.ts +28 -4
- package/lib/instrumentation.node.ts +37 -22
- package/lib/internals/hooks.ts +14 -0
- package/lib/internals/pii-detection.ts +145 -0
- package/lib/internals/shared-metrics.ts +34 -0
- package/lib/resource.ts +3 -2
- package/lib/traces.ts +74 -1
- package/package.json +23 -21
- package/test/config-manager.test.ts +34 -0
- package/test/exporter/pii-exporter-decorator.test.ts +139 -0
- package/test/index.test.ts +44 -12
- package/test/integration/README.md +1 -1
- package/test/integration/{integration.test.ts → http-tracing.integration.test.ts} +0 -2
- package/test/integration/pii.integration.test.ts +68 -0
- package/test/integration/run.sh +2 -2
- package/test/internals/hooks.test.ts +45 -0
- package/test/internals/pii-detection.test.ts +141 -0
- package/test/internals/shared-metrics.test.ts +34 -0
- package/test/node-config.test.ts +68 -30
- package/test/processor/enrich-span-processor.test.ts +2 -54
- package/test/resource.test.ts +12 -1
- package/test/traces/active-span.test.ts +28 -0
- package/test/traces/with-span.test.ts +340 -0
- package/test/utils/alloy-log-parser.ts +7 -0
- package/test/utils/mock-signals.ts +144 -0
- package/test/validation.test.ts +22 -16
- package/vitest.config.ts +8 -2
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Span,
|
|
3
|
+
SpanContext,
|
|
4
|
+
AttributeValue,
|
|
5
|
+
SpanStatus,
|
|
6
|
+
TimeInput,
|
|
7
|
+
Link,
|
|
8
|
+
Exception,
|
|
9
|
+
Attributes,
|
|
10
|
+
TraceState,
|
|
11
|
+
} from "@opentelemetry/api";
|
|
12
|
+
|
|
13
|
+
export class MockSpan implements Span {
|
|
14
|
+
public attributes: Record<string, AttributeValue> = {};
|
|
15
|
+
public events: {
|
|
16
|
+
name: string;
|
|
17
|
+
attributes?: Attributes | TimeInput;
|
|
18
|
+
startTime?: TimeInput;
|
|
19
|
+
}[] = [];
|
|
20
|
+
public links: Link[] = [];
|
|
21
|
+
public status?: SpanStatus;
|
|
22
|
+
public updatedName?: string;
|
|
23
|
+
public ended: boolean = false;
|
|
24
|
+
public endTime?: TimeInput;
|
|
25
|
+
public exceptions: { exception: Exception; time?: TimeInput }[] = [];
|
|
26
|
+
|
|
27
|
+
public resource: { attributes: Attributes } = { attributes: {} };
|
|
28
|
+
|
|
29
|
+
spanContext(): SpanContext {
|
|
30
|
+
return {
|
|
31
|
+
traceId: "test-trace-id",
|
|
32
|
+
spanId: "test-span-id",
|
|
33
|
+
traceFlags: 1,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
setAttribute(key: string, value: AttributeValue): this {
|
|
38
|
+
this.attributes[key] = value;
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
setAttributes(attributes: Attributes): this {
|
|
43
|
+
Object.assign(this.attributes, attributes);
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
addEvent(
|
|
48
|
+
name: string,
|
|
49
|
+
attributesOrStartTime?: Attributes | TimeInput,
|
|
50
|
+
startTime?: TimeInput,
|
|
51
|
+
): this {
|
|
52
|
+
this.events.push({ name, attributes: attributesOrStartTime, startTime });
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
addLink(link: Link): this {
|
|
57
|
+
this.links.push(link);
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
addLinks(links: Link[]): this {
|
|
62
|
+
this.links.push(...links);
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
setStatus(status: SpanStatus): this {
|
|
67
|
+
this.status = status;
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
updateName(name: string): this {
|
|
72
|
+
this.updatedName = name;
|
|
73
|
+
return this;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
end(endTime?: TimeInput): void {
|
|
77
|
+
this.ended = true;
|
|
78
|
+
this.endTime = endTime;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
isRecording(): boolean {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
recordException(exception: Exception, time?: TimeInput): void {
|
|
86
|
+
this.exceptions.push({ exception, time });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
reset(): void {
|
|
90
|
+
this.attributes = {};
|
|
91
|
+
this.events = [];
|
|
92
|
+
this.links = [];
|
|
93
|
+
this.status = undefined;
|
|
94
|
+
this.updatedName = undefined;
|
|
95
|
+
this.ended = false;
|
|
96
|
+
this.endTime = undefined;
|
|
97
|
+
this.exceptions = [];
|
|
98
|
+
this.resource = { attributes: {} };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export class TestTraceState implements TraceState {
|
|
103
|
+
private entries: Map<string, string>;
|
|
104
|
+
|
|
105
|
+
constructor(initEntries?: [string, string][]) {
|
|
106
|
+
this.entries = new Map(initEntries ?? []);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
set(key: string, value: string): TraceState {
|
|
110
|
+
const newEntries: [string, string][] = [[key, value]];
|
|
111
|
+
for (const [k, v] of this.entries.entries()) {
|
|
112
|
+
if (k !== key) {
|
|
113
|
+
newEntries.push([k, v]);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return new TestTraceState(newEntries);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
unset(key: string): TraceState {
|
|
120
|
+
const newEntries: [string, string][] = [];
|
|
121
|
+
for (const [k, v] of this.entries.entries()) {
|
|
122
|
+
if (k !== key) {
|
|
123
|
+
newEntries.push([k, v]);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return new TestTraceState(newEntries);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
get(key: string): string | undefined {
|
|
130
|
+
return this.entries.get(key);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
serialize(): string {
|
|
134
|
+
return Array.from(this.entries)
|
|
135
|
+
.slice(0, 32) // Enforce 32-member max
|
|
136
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
137
|
+
.join(",");
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Optional: for testing/debugging
|
|
141
|
+
toJSON(): Record<string, string> {
|
|
142
|
+
return Object.fromEntries(this.entries);
|
|
143
|
+
}
|
|
144
|
+
}
|
package/test/validation.test.ts
CHANGED
|
@@ -10,7 +10,7 @@ describe("validation config: should return without breaking the execution", () =
|
|
|
10
10
|
.spyOn(console, "warn")
|
|
11
11
|
.mockImplementation(vi.fn());
|
|
12
12
|
|
|
13
|
-
instrumentNode();
|
|
13
|
+
await instrumentNode();
|
|
14
14
|
|
|
15
15
|
expect(consoleWarnSpy).toHaveBeenCalled();
|
|
16
16
|
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
@@ -26,11 +26,13 @@ describe("validation config: should return without breaking the execution", () =
|
|
|
26
26
|
.mockImplementation(vi.fn());
|
|
27
27
|
const consoleLogSpy = vi.spyOn(console, "log").mockImplementation(vi.fn());
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
collectorUrl: undefined
|
|
32
|
-
})
|
|
33
|
-
|
|
29
|
+
await expect(
|
|
30
|
+
buildNodeInstrumentation({
|
|
31
|
+
collectorUrl: undefined,
|
|
32
|
+
}).then((result) => {
|
|
33
|
+
sdk = result;
|
|
34
|
+
}),
|
|
35
|
+
).resolves.not.toThrowError();
|
|
34
36
|
|
|
35
37
|
assert.equal(sdk, undefined);
|
|
36
38
|
|
|
@@ -41,7 +43,7 @@ describe("validation config: should return without breaking the execution", () =
|
|
|
41
43
|
expect(consoleLogSpy).not.toHaveBeenCalled();
|
|
42
44
|
});
|
|
43
45
|
|
|
44
|
-
test("node instrumentation: invalid url", () => {
|
|
46
|
+
test("node instrumentation: invalid url", async () => {
|
|
45
47
|
let sdk: NodeSDK | undefined = undefined;
|
|
46
48
|
|
|
47
49
|
const consoleErrorSpy = vi
|
|
@@ -49,11 +51,13 @@ describe("validation config: should return without breaking the execution", () =
|
|
|
49
51
|
.mockImplementation(vi.fn());
|
|
50
52
|
const consoleLogSpy = vi.spyOn(console, "log").mockImplementation(vi.fn());
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
await expect(
|
|
55
|
+
buildNodeInstrumentation({
|
|
54
56
|
collectorUrl: "notavalidURL",
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
+
}).then((result) => {
|
|
58
|
+
sdk = result;
|
|
59
|
+
}),
|
|
60
|
+
).resolves.not.toThrowError();
|
|
57
61
|
|
|
58
62
|
assert.equal(sdk, undefined);
|
|
59
63
|
|
|
@@ -64,7 +68,7 @@ describe("validation config: should return without breaking the execution", () =
|
|
|
64
68
|
expect(consoleLogSpy).not.toHaveBeenCalled();
|
|
65
69
|
});
|
|
66
70
|
|
|
67
|
-
test("node instrumentation: verify no instrumentation if exception occurs", () => {
|
|
71
|
+
test("node instrumentation: verify no instrumentation if exception occurs", async () => {
|
|
68
72
|
let sdk: NodeSDK | undefined = undefined;
|
|
69
73
|
|
|
70
74
|
const consoleErrorSpy = vi
|
|
@@ -78,12 +82,14 @@ describe("validation config: should return without breaking the execution", () =
|
|
|
78
82
|
}),
|
|
79
83
|
}));
|
|
80
84
|
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
await expect(
|
|
86
|
+
buildNodeInstrumentation({
|
|
83
87
|
collectorUrl: "https://testurl.com",
|
|
84
88
|
serviceName: "test",
|
|
85
|
-
})
|
|
86
|
-
|
|
89
|
+
}).then((result) => {
|
|
90
|
+
sdk = result;
|
|
91
|
+
}),
|
|
92
|
+
).resolves.not.toThrowError();
|
|
87
93
|
|
|
88
94
|
assert.equal(sdk, undefined);
|
|
89
95
|
|
package/vitest.config.ts
CHANGED
|
@@ -22,10 +22,16 @@ export default defineConfig({
|
|
|
22
22
|
reporters: ["default", ["junit", { outputFile: "test-report.xml" }]],
|
|
23
23
|
environment: "node",
|
|
24
24
|
pool: "threads",
|
|
25
|
-
|
|
25
|
+
projects: [
|
|
26
26
|
{
|
|
27
27
|
test: {
|
|
28
|
-
include: [
|
|
28
|
+
include: [
|
|
29
|
+
"**/test/*.test.ts",
|
|
30
|
+
"**/test/processor/*.test.ts",
|
|
31
|
+
"**/test/traces/*.test.ts",
|
|
32
|
+
"**/test/internals/*.test.ts",
|
|
33
|
+
"**/test/exporter/*.test.ts",
|
|
34
|
+
],
|
|
29
35
|
name: "unit",
|
|
30
36
|
},
|
|
31
37
|
},
|