@ogcio/o11y-sdk-node 0.7.0 → 0.8.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/README.md +2 -2
- package/dist/sdk-core/lib/redaction/ip-redactor.js +37 -10
- package/dist/sdk-core/lib/redaction/ppsn-redactor.js +16 -4
- package/dist/sdk-node/index.d.ts +1 -0
- package/dist/sdk-node/lib/exporter/console.js +1 -0
- package/dist/sdk-node/lib/exporter/grpc.js +1 -0
- package/dist/sdk-node/lib/exporter/http.js +1 -0
- package/dist/sdk-node/lib/index.d.ts +8 -0
- package/dist/sdk-node/package.json +11 -8
- package/package.json +11 -8
package/README.md
CHANGED
|
@@ -7,13 +7,13 @@ The NodeJS observability sdk is a npm package used to setup and implement opente
|
|
|
7
7
|
pnpm
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
pnpm i --save @ogcio/o11y-sdk-node
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
npm
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
16
|
+
npm i @ogcio/o11y-sdk-node
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
@@ -1,17 +1,44 @@
|
|
|
1
1
|
import { BasicRedactor } from "./basic-redactor.js";
|
|
2
2
|
export class IpRedactor extends BasicRedactor {
|
|
3
|
-
|
|
4
|
-
static
|
|
3
|
+
// iOS < 16.6 compatible: no lookbehind/lookahead
|
|
4
|
+
static IPV4_REGEX = /(?:%[0-9A-Fa-f]{2})?(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}(?:%[0-9A-Fa-f]{2})?/gi;
|
|
5
|
+
// Comprehensive IPv6 regex without lookbehind - matches all standard formats including :: compression
|
|
6
|
+
static IPV6_REGEX = /(?:%[0-9A-Fa-f]{2})?((?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){1,6}:[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){1,5}(?::[0-9A-Fa-f]{1,4}){1,2}|(?:[0-9A-Fa-f]{1,4}:){1,4}(?::[0-9A-Fa-f]{1,4}){1,3}|(?:[0-9A-Fa-f]{1,4}:){1,3}(?::[0-9A-Fa-f]{1,4}){1,4}|(?:[0-9A-Fa-f]{1,4}:){1,2}(?::[0-9A-Fa-f]{1,4}){1,5}|[0-9A-Fa-f]{1,4}:(?:(?::[0-9A-Fa-f]{1,4}){1,6})|::(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4}|[0-9A-Fa-f]{1,4}::(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){2}::(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){3}::(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){4}::(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){5}::(?:[0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){6}::[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){1,7}:|(?:[0-9A-Fa-f]{1,4}:){1,4}:(?:25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3})(?:%[0-9A-Fa-f]{2})?/gi;
|
|
5
7
|
redact(value) {
|
|
6
8
|
const counters = {};
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
// First pass: redact IPv4 with boundary checking
|
|
10
|
+
const tempValue = value.replace(IpRedactor.IPV4_REGEX, (match, ...args) => {
|
|
11
|
+
const offset = args[args.length - 2];
|
|
12
|
+
const before = offset > 0 ? value[offset - 1] : "";
|
|
13
|
+
const after = offset + match.length < value.length
|
|
14
|
+
? value[offset + match.length]
|
|
15
|
+
: "";
|
|
16
|
+
// Check if surrounded by non-digit characters
|
|
17
|
+
const isValidBefore = !before || !/\d/.test(before);
|
|
18
|
+
const isValidAfter = !after || !/\d/.test(after);
|
|
19
|
+
if (isValidBefore && isValidAfter) {
|
|
20
|
+
counters["IPv4"] = (counters["IPv4"] || 0) + 1;
|
|
21
|
+
return "[REDACTED IPV4]";
|
|
22
|
+
}
|
|
23
|
+
return match;
|
|
24
|
+
});
|
|
25
|
+
// Second pass: redact IPv6 with boundary checking
|
|
26
|
+
const redactedValue = tempValue.replace(IpRedactor.IPV6_REGEX, (match, ...args) => {
|
|
27
|
+
const offset = args[args.length - 2];
|
|
28
|
+
const before = offset > 0 ? tempValue[offset - 1] : "";
|
|
29
|
+
const after = offset + match.length < tempValue.length
|
|
30
|
+
? tempValue[offset + match.length]
|
|
31
|
+
: "";
|
|
32
|
+
// For IPv6:
|
|
33
|
+
// Reject if there's a colon before (indicating :::)
|
|
34
|
+
// Reject if there's a hex digit or colon after
|
|
35
|
+
const isValidBefore = !before || !/[0-9a-f:]/i.test(before);
|
|
36
|
+
const isValidAfter = !after || !/[0-9a-f:]/i.test(after);
|
|
37
|
+
if (isValidBefore && isValidAfter) {
|
|
38
|
+
counters["IPv6"] = (counters["IPv6"] || 0) + 1;
|
|
39
|
+
return "[REDACTED IPV6]";
|
|
40
|
+
}
|
|
41
|
+
return match;
|
|
15
42
|
});
|
|
16
43
|
return {
|
|
17
44
|
redactedValue: redactedValue,
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import { BasicRedactor } from "./basic-redactor.js";
|
|
2
2
|
export class PpsnRedactor extends BasicRedactor {
|
|
3
|
-
|
|
3
|
+
// iOS < 16.6 compatible: no lookbehind/lookahead
|
|
4
|
+
static PPSN_REGEX = /[0-9]{7}[a-z]{1,2}/gi;
|
|
4
5
|
redact(value) {
|
|
5
6
|
let redactedCounter = 0;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// Boundary checking to replace lookbehind/lookahead
|
|
8
|
+
const redactedValue = value.replace(PpsnRedactor.PPSN_REGEX, (match, offset) => {
|
|
9
|
+
const before = offset > 0 ? value[offset - 1] : "";
|
|
10
|
+
const after = offset + match.length < value.length
|
|
11
|
+
? value[offset + match.length]
|
|
12
|
+
: "";
|
|
13
|
+
// Check if surrounded by non-alphanumeric characters
|
|
14
|
+
const isValidBefore = !before || !/[0-9a-z]/i.test(before);
|
|
15
|
+
const isValidAfter = !after || !/[0-9a-z]/i.test(after);
|
|
16
|
+
if (isValidBefore && isValidAfter) {
|
|
17
|
+
redactedCounter++;
|
|
18
|
+
return "[REDACTED PPSN]";
|
|
19
|
+
}
|
|
20
|
+
return match;
|
|
9
21
|
});
|
|
10
22
|
return {
|
|
11
23
|
redactedValue: redactedValue,
|
package/dist/sdk-node/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { NodeSDK } from "@opentelemetry/sdk-node";
|
|
2
2
|
import buildNodeInstrumentation from "./lib/instrumentation.node.js";
|
|
3
|
+
export type { SpanKind, SpanStatus, SpanStatusCode, TraceFlags, } from "@opentelemetry/api";
|
|
3
4
|
export type * from "./lib/index.js";
|
|
4
5
|
export type { NodeSDK };
|
|
5
6
|
export { buildNodeInstrumentation as instrumentNode };
|
|
@@ -9,6 +9,7 @@ export default function buildConsoleExporters(config) {
|
|
|
9
9
|
..._spansProcessorConfig(config),
|
|
10
10
|
],
|
|
11
11
|
metrics: new metrics.PeriodicExportingMetricReader({
|
|
12
|
+
exportIntervalMillis: config.metrics?.exportIntervalMs,
|
|
12
13
|
exporter: new metrics.ConsoleMetricExporter(),
|
|
13
14
|
}),
|
|
14
15
|
logs: [
|
|
@@ -24,6 +24,7 @@ export default async function buildGrpcExporters(config) {
|
|
|
24
24
|
..._spansProcessorConfig(config),
|
|
25
25
|
],
|
|
26
26
|
metrics: new metrics.PeriodicExportingMetricReader({
|
|
27
|
+
exportIntervalMillis: config.metrics?.exportIntervalMs,
|
|
27
28
|
exporter: new PIIExporterDecorator(new OTLPMetricExporter({
|
|
28
29
|
url: `${config.collectorUrl}`,
|
|
29
30
|
compression: CompressionAlgorithm.GZIP,
|
|
@@ -20,6 +20,7 @@ export default function buildHttpExporters(config) {
|
|
|
20
20
|
..._spansProcessorConfig(config),
|
|
21
21
|
],
|
|
22
22
|
metrics: new metrics.PeriodicExportingMetricReader({
|
|
23
|
+
exportIntervalMillis: config.metrics?.exportIntervalMs,
|
|
23
24
|
exporter: new PIIExporterDecorator(new OTLPMetricExporter({
|
|
24
25
|
url: `${config.collectorUrl}/v1/metrics`,
|
|
25
26
|
compression: CompressionAlgorithm.GZIP,
|
|
@@ -54,6 +54,14 @@ export interface NodeSDKConfig {
|
|
|
54
54
|
* @default 1
|
|
55
55
|
*/
|
|
56
56
|
traceRatio?: number;
|
|
57
|
+
metrics?: {
|
|
58
|
+
/**
|
|
59
|
+
* Delay in milliseconds for the metric reader to initiate metric collection.
|
|
60
|
+
*
|
|
61
|
+
* @default 60_000
|
|
62
|
+
*/
|
|
63
|
+
exportIntervalMs?: number;
|
|
64
|
+
};
|
|
57
65
|
/**
|
|
58
66
|
* Flag to enable or disable the tracing for node:fs module
|
|
59
67
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ogcio/o11y-sdk-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Opentelemetry standard instrumentation SDK for NodeJS based project",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -9,8 +9,11 @@
|
|
|
9
9
|
"test": "vitest",
|
|
10
10
|
"prepublishOnly": "pnpm i && rm -rf dist && tsc -p tsconfig.json",
|
|
11
11
|
"test:unit": "vitest --project unit",
|
|
12
|
-
"test:integration": "pnpm
|
|
13
|
-
"test:integration:
|
|
12
|
+
"test:integration": "pnpm test:integration:setup && pnpm test:integration:run && pnpm test:integration:assert && pnpm test:integration:teardown",
|
|
13
|
+
"test:integration:setup": "sh ./test/integration/setup.sh integration",
|
|
14
|
+
"test:integration:run": "pnpm --filter @ogcio/o11y run prepare:integration",
|
|
15
|
+
"test:integration:assert": "vitest --project integration",
|
|
16
|
+
"test:integration:teardown": "sh ./test/integration/teardown.sh integration"
|
|
14
17
|
},
|
|
15
18
|
"exports": {
|
|
16
19
|
".": "./dist/sdk-node/index.js",
|
|
@@ -30,10 +33,10 @@
|
|
|
30
33
|
"author": "team:ogcio/observability",
|
|
31
34
|
"license": "ISC",
|
|
32
35
|
"dependencies": {
|
|
33
|
-
"@grpc/grpc-js": "1.14.
|
|
36
|
+
"@grpc/grpc-js": "1.14.3",
|
|
34
37
|
"@opentelemetry/api": "1.9.0",
|
|
35
38
|
"@opentelemetry/api-logs": "0.208.0",
|
|
36
|
-
"@opentelemetry/auto-instrumentations-node": "0.67.
|
|
39
|
+
"@opentelemetry/auto-instrumentations-node": "0.67.3",
|
|
37
40
|
"@opentelemetry/core": "2.2.0",
|
|
38
41
|
"@opentelemetry/exporter-logs-otlp-grpc": "0.208.0",
|
|
39
42
|
"@opentelemetry/exporter-logs-otlp-http": "0.208.0",
|
|
@@ -50,11 +53,11 @@
|
|
|
50
53
|
"@opentelemetry/sdk-trace-base": "2.2.0"
|
|
51
54
|
},
|
|
52
55
|
"devDependencies": {
|
|
53
|
-
"@types/node": "
|
|
54
|
-
"@vitest/coverage-v8": "4.0.
|
|
56
|
+
"@types/node": "25.0.3",
|
|
57
|
+
"@vitest/coverage-v8": "4.0.16",
|
|
55
58
|
"tsx": "4.21.0",
|
|
56
59
|
"typescript": "5.9.3",
|
|
57
|
-
"vitest": "4.0.
|
|
60
|
+
"vitest": "4.0.16"
|
|
58
61
|
},
|
|
59
62
|
"engines": {
|
|
60
63
|
"node": ">=20.6.0"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ogcio/o11y-sdk-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Opentelemetry standard instrumentation SDK for NodeJS based project",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"author": "team:ogcio/observability",
|
|
23
23
|
"license": "ISC",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@grpc/grpc-js": "1.14.
|
|
25
|
+
"@grpc/grpc-js": "1.14.3",
|
|
26
26
|
"@opentelemetry/api": "1.9.0",
|
|
27
27
|
"@opentelemetry/api-logs": "0.208.0",
|
|
28
|
-
"@opentelemetry/auto-instrumentations-node": "0.67.
|
|
28
|
+
"@opentelemetry/auto-instrumentations-node": "0.67.3",
|
|
29
29
|
"@opentelemetry/core": "2.2.0",
|
|
30
30
|
"@opentelemetry/exporter-logs-otlp-grpc": "0.208.0",
|
|
31
31
|
"@opentelemetry/exporter-logs-otlp-http": "0.208.0",
|
|
@@ -42,11 +42,11 @@
|
|
|
42
42
|
"@opentelemetry/sdk-trace-base": "2.2.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@types/node": "
|
|
46
|
-
"@vitest/coverage-v8": "4.0.
|
|
45
|
+
"@types/node": "25.0.3",
|
|
46
|
+
"@vitest/coverage-v8": "4.0.16",
|
|
47
47
|
"tsx": "4.21.0",
|
|
48
48
|
"typescript": "5.9.3",
|
|
49
|
-
"vitest": "4.0.
|
|
49
|
+
"vitest": "4.0.16"
|
|
50
50
|
},
|
|
51
51
|
"engines": {
|
|
52
52
|
"node": ">=20.6.0"
|
|
@@ -55,7 +55,10 @@
|
|
|
55
55
|
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
56
56
|
"test": "vitest",
|
|
57
57
|
"test:unit": "vitest --project unit",
|
|
58
|
-
"test:integration": "pnpm
|
|
59
|
-
"test:integration:
|
|
58
|
+
"test:integration": "pnpm test:integration:setup && pnpm test:integration:run && pnpm test:integration:assert && pnpm test:integration:teardown",
|
|
59
|
+
"test:integration:setup": "sh ./test/integration/setup.sh integration",
|
|
60
|
+
"test:integration:run": "pnpm --filter @ogcio/o11y run prepare:integration",
|
|
61
|
+
"test:integration:assert": "vitest --project integration",
|
|
62
|
+
"test:integration:teardown": "sh ./test/integration/teardown.sh integration"
|
|
60
63
|
}
|
|
61
64
|
}
|