@ogcio/o11y-sdk-node 0.9.1 → 0.10.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/lib/redaction/basic-redactor.d.ts +0 -1
- package/dist/sdk-core/lib/redaction/basic-redactor.js +0 -1
- package/dist/sdk-core/lib/redaction/email-redactor.d.ts +1 -0
- package/dist/sdk-core/lib/redaction/email-redactor.js +16 -5
- package/dist/sdk-core/lib/redaction/ip-redactor.js +31 -8
- package/dist/sdk-core/lib/redaction/ppsn-redactor.js +3 -3
- package/dist/sdk-core/lib/utils/index.d.ts +1 -0
- package/dist/sdk-core/lib/utils/index.js +1 -0
- package/dist/sdk-core/lib/utils/traces.d.ts +11 -0
- package/dist/sdk-core/lib/utils/traces.js +35 -0
- package/dist/sdk-node/index.d.ts +3 -3
- package/dist/sdk-node/index.js +1 -0
- package/dist/sdk-node/lib/config-manager.js +1 -1
- package/dist/sdk-node/lib/exporter/pii-exporter-decorator.js +1 -1
- package/dist/sdk-node/lib/instrumentation.node.js +8 -2
- package/dist/sdk-node/lib/presets/sentry-next.js +1 -1
- package/dist/sdk-node/lib/presets/sentry-node.js +1 -1
- package/dist/sdk-node/lib/processor/enrich-logger-processor.d.ts +1 -1
- package/dist/sdk-node/lib/processor/enrich-span-processor.d.ts +1 -1
- package/dist/sdk-node/lib/processor/nextjs-span-processor.js +1 -2
- package/dist/sdk-node/lib/processor/pseudo-profiling-span-processor.d.ts +1 -1
- package/dist/sdk-node/lib/resource.d.ts +1 -1
- package/dist/sdk-node/lib/traces.d.ts +1 -0
- package/dist/sdk-node/lib/traces.js +2 -35
- package/dist/sdk-node/lib/url-sampler.d.ts +2 -2
- package/dist/sdk-node/lib/url-sampler.js +2 -2
- package/dist/sdk-node/package.json +25 -25
- package/package.json +37 -36
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { StringKind, RedactionResult } from "./index.js";
|
|
2
2
|
export declare abstract class BasicRedactor {
|
|
3
|
-
constructor();
|
|
4
3
|
process(value: string, source: string, kind: StringKind): string;
|
|
5
4
|
protected redact(_value: string, _source: string, _kind: StringKind): RedactionResult<Record<string, unknown>>;
|
|
6
5
|
protected exportMetrics(_context: RedactionResult<Record<string, unknown>>["context"], _source: string, _kind: StringKind): void;
|
|
@@ -2,6 +2,7 @@ import { BasicRedactor } from "./basic-redactor.js";
|
|
|
2
2
|
import type { RedactionResult } from "./index.js";
|
|
3
3
|
export declare class EmailRedactor extends BasicRedactor {
|
|
4
4
|
private static readonly EMAIL_REGEX;
|
|
5
|
+
private static readonly CHUNK_SPLIT;
|
|
5
6
|
protected redact(value: string): RedactionResult<{
|
|
6
7
|
domains: Record<string, number>;
|
|
7
8
|
}>;
|
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
import { BasicRedactor } from "./basic-redactor.js";
|
|
2
2
|
export class EmailRedactor extends BasicRedactor {
|
|
3
|
-
|
|
3
|
+
// Security Hotspot accepted: regex is carefully designed and tested to avoid ReDoS
|
|
4
|
+
// vulnerabilities while effectively matching email addresses, including internationalized ones.
|
|
5
|
+
static EMAIL_REGEX = /[\p{L}\p{N}._%+-]+@([\p{L}\p{N}-]+(?:\.[\p{L}\p{N}-]+)*\.\p{L}{2,})/giu; // NOSONAR
|
|
6
|
+
static CHUNK_SPLIT = /(\s+)/;
|
|
4
7
|
redact(value) {
|
|
5
8
|
const domains = {};
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
// Split on whitespace to process each token independently,
|
|
10
|
+
// bounding regex execution per chunk to prevent ReDoS.
|
|
11
|
+
const parts = value.split(EmailRedactor.CHUNK_SPLIT);
|
|
12
|
+
const redacted = parts.map((part) => {
|
|
13
|
+
// Whitespace separators are returned by the split — pass them through
|
|
14
|
+
if (EmailRedactor.CHUNK_SPLIT.test(part))
|
|
15
|
+
return part;
|
|
16
|
+
return part.replace(EmailRedactor.EMAIL_REGEX, (_, domain) => {
|
|
17
|
+
domains[domain] = (domains[domain] || 0) + 1;
|
|
18
|
+
return "[REDACTED EMAIL]";
|
|
19
|
+
});
|
|
9
20
|
});
|
|
10
21
|
return {
|
|
11
|
-
redactedValue:
|
|
22
|
+
redactedValue: redacted.join(""),
|
|
12
23
|
context: {
|
|
13
24
|
domains,
|
|
14
25
|
},
|
|
@@ -1,14 +1,37 @@
|
|
|
1
1
|
import { BasicRedactor } from "./basic-redactor.js";
|
|
2
|
+
// iOS < 16.6 compatible: no lookbehind/lookahead
|
|
3
|
+
// Building blocks — composed programmatically to avoid regex complexity & duplication
|
|
4
|
+
const H = String.raw `[\da-f]{1,4}`; // single hex group
|
|
5
|
+
const PCT = String.raw `(?:%[\da-f]{2})`; // percent-encoded byte
|
|
6
|
+
const OCTET = String.raw `(?:25[0-5]|2[0-4]\d|[01]?\d\d?)`; // IPv4 octet 0-255
|
|
7
|
+
const IPV4_PATTERN = String.raw `${PCT}?${OCTET}(?:\.${OCTET}){3}${PCT}?`;
|
|
8
|
+
const IPV6_ALTERNATIVES = [
|
|
9
|
+
`(?:${H}:){7}${H}`, // full 8-group
|
|
10
|
+
`(?:${H}:){1,6}:${H}`, // :: after 1-6 groups + 1 trailing
|
|
11
|
+
`(?:${H}:){1,5}(?::${H}){1,2}`, // :: after 1-5 + 1-2 trailing
|
|
12
|
+
`(?:${H}:){1,4}(?::${H}){1,3}`, // :: after 1-4 + 1-3 trailing
|
|
13
|
+
`(?:${H}:){1,3}(?::${H}){1,4}`, // :: after 1-3 + 1-4 trailing
|
|
14
|
+
`(?:${H}:){1,2}(?::${H}){1,5}`, // :: after 1-2 + 1-5 trailing
|
|
15
|
+
`${H}:(?::${H}){1,6}`, // :: after 1 + 1-6 trailing
|
|
16
|
+
`::(?:${H}:){0,5}${H}`, // leading ::
|
|
17
|
+
`${H}::(?:${H}:){0,5}${H}`, // 1 group + ::
|
|
18
|
+
`(?:${H}:){2}::(?:${H}:){0,4}${H}`, // 2 groups + ::
|
|
19
|
+
`(?:${H}:){3}::(?:${H}:){0,3}${H}`, // 3 groups + ::
|
|
20
|
+
`(?:${H}:){4}::(?:${H}:){0,2}${H}`, // 4 groups + ::
|
|
21
|
+
`(?:${H}:){5}::(?:${H}:)?${H}`, // 5 groups + ::
|
|
22
|
+
`(?:${H}:){6}::${H}`, // 6 groups + ::
|
|
23
|
+
`(?:${H}:){1,7}:`, // trailing ::
|
|
24
|
+
String.raw `(?:${H}:){1,4}:${OCTET}(?:\.${OCTET}){3}`, // mixed IPv4 form
|
|
25
|
+
];
|
|
26
|
+
const IPV6_PATTERN = `${PCT}?(${IPV6_ALTERNATIVES.join("|")})${PCT}?`;
|
|
2
27
|
export class IpRedactor extends BasicRedactor {
|
|
3
|
-
|
|
4
|
-
static
|
|
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;
|
|
28
|
+
static IPV4_REGEX = new RegExp(IPV4_PATTERN, "gi");
|
|
29
|
+
static IPV6_REGEX = new RegExp(IPV6_PATTERN, "gi");
|
|
7
30
|
redact(value) {
|
|
8
31
|
const counters = {};
|
|
9
32
|
// First pass: redact IPv4 with boundary checking
|
|
10
33
|
const tempValue = value.replace(IpRedactor.IPV4_REGEX, (match, ...args) => {
|
|
11
|
-
const offset = args
|
|
34
|
+
const offset = args.at(-2);
|
|
12
35
|
const before = offset > 0 ? value[offset - 1] : "";
|
|
13
36
|
const after = offset + match.length < value.length
|
|
14
37
|
? value[offset + match.length]
|
|
@@ -24,7 +47,7 @@ export class IpRedactor extends BasicRedactor {
|
|
|
24
47
|
});
|
|
25
48
|
// Second pass: redact IPv6 with boundary checking
|
|
26
49
|
const redactedValue = tempValue.replace(IpRedactor.IPV6_REGEX, (match, ...args) => {
|
|
27
|
-
const offset = args
|
|
50
|
+
const offset = args.at(-2);
|
|
28
51
|
const before = offset > 0 ? tempValue[offset - 1] : "";
|
|
29
52
|
const after = offset + match.length < tempValue.length
|
|
30
53
|
? tempValue[offset + match.length]
|
|
@@ -32,8 +55,8 @@ export class IpRedactor extends BasicRedactor {
|
|
|
32
55
|
// For IPv6:
|
|
33
56
|
// Reject if there's a colon before (indicating :::)
|
|
34
57
|
// Reject if there's a hex digit or colon after
|
|
35
|
-
const isValidBefore = !before || !/[
|
|
36
|
-
const isValidAfter = !after || !/[
|
|
58
|
+
const isValidBefore = !before || !/[\da-f:]/i.test(before);
|
|
59
|
+
const isValidAfter = !after || !/[\da-f:]/i.test(after);
|
|
37
60
|
if (isValidBefore && isValidAfter) {
|
|
38
61
|
counters["IPv6"] = (counters["IPv6"] || 0) + 1;
|
|
39
62
|
return "[REDACTED IPV6]";
|
|
@@ -1,7 +1,7 @@
|
|
|
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 =
|
|
4
|
+
static PPSN_REGEX = /\d{7}[a-z]{1,2}/gi;
|
|
5
5
|
redact(value) {
|
|
6
6
|
let redactedCounter = 0;
|
|
7
7
|
// Boundary checking to replace lookbehind/lookahead
|
|
@@ -11,8 +11,8 @@ export class PpsnRedactor extends BasicRedactor {
|
|
|
11
11
|
? value[offset + match.length]
|
|
12
12
|
: "";
|
|
13
13
|
// Check if surrounded by non-alphanumeric characters
|
|
14
|
-
const isValidBefore = !before ||
|
|
15
|
-
const isValidAfter = !after ||
|
|
14
|
+
const isValidBefore = !before || !/\w/.test(before);
|
|
15
|
+
const isValidAfter = !after || !/\w/.test(after);
|
|
16
16
|
if (isValidBefore && isValidAfter) {
|
|
17
17
|
redactedCounter++;
|
|
18
18
|
return "[REDACTED PPSN]";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Span } from "@opentelemetry/api";
|
|
2
|
+
/**
|
|
3
|
+
* Generates a function wrapping a given Callable `fn` into an error handling block.
|
|
4
|
+
* Setting Span status and recording any caught exception before bubbling it up.
|
|
5
|
+
*
|
|
6
|
+
* Marks the span as ended once the provided callable has ended or an error has been caught.
|
|
7
|
+
*
|
|
8
|
+
* @returns {Promise<T>} where T is the type returned by the Callable.
|
|
9
|
+
* @throws any error thrown by the original Callable `fn` provided.
|
|
10
|
+
*/
|
|
11
|
+
export declare function selfContainedSpanHandlerGenerator<T>(fn: (span: Span) => T | Promise<T>): (span: Span) => Promise<T>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { SpanStatusCode } from "@opentelemetry/api";
|
|
2
|
+
/**
|
|
3
|
+
* Generates a function wrapping a given Callable `fn` into an error handling block.
|
|
4
|
+
* Setting Span status and recording any caught exception before bubbling it up.
|
|
5
|
+
*
|
|
6
|
+
* Marks the span as ended once the provided callable has ended or an error has been caught.
|
|
7
|
+
*
|
|
8
|
+
* @returns {Promise<T>} where T is the type returned by the Callable.
|
|
9
|
+
* @throws any error thrown by the original Callable `fn` provided.
|
|
10
|
+
*/
|
|
11
|
+
export function selfContainedSpanHandlerGenerator(fn) {
|
|
12
|
+
return async (span) => {
|
|
13
|
+
try {
|
|
14
|
+
const fnResult = await fn(span);
|
|
15
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
16
|
+
return fnResult;
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
if (err instanceof Error) {
|
|
20
|
+
span.recordException(err);
|
|
21
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
|
|
22
|
+
throw err;
|
|
23
|
+
}
|
|
24
|
+
span.recordException({ message: JSON.stringify(err) });
|
|
25
|
+
span.setStatus({
|
|
26
|
+
code: SpanStatusCode.ERROR,
|
|
27
|
+
message: JSON.stringify(err),
|
|
28
|
+
});
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
span.end();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
package/dist/sdk-node/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { NodeSDK } from "@opentelemetry/sdk-node";
|
|
2
1
|
import buildNodeInstrumentation from "./lib/instrumentation.node.js";
|
|
3
|
-
export type {
|
|
2
|
+
export type { Span, SpanStatus } from "@opentelemetry/api";
|
|
3
|
+
export { SpanKind, SpanStatusCode, TraceFlags } from "@opentelemetry/api";
|
|
4
4
|
export type * from "./lib/index.js";
|
|
5
|
-
export type { NodeSDK };
|
|
5
|
+
export type { NodeSDK } from "@opentelemetry/sdk-node";
|
|
6
6
|
export { buildNodeInstrumentation as instrumentNode };
|
|
7
7
|
export * from "./lib/processor/on-ending-hook-span-processor.js";
|
|
8
8
|
export * from "./lib/metrics.js";
|
package/dist/sdk-node/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import buildNodeInstrumentation from "./lib/instrumentation.node.js";
|
|
2
|
+
export { SpanKind, SpanStatusCode, TraceFlags } from "@opentelemetry/api";
|
|
2
3
|
export { buildNodeInstrumentation as instrumentNode };
|
|
3
4
|
export * from "./lib/processor/on-ending-hook-span-processor.js";
|
|
4
5
|
export * from "./lib/metrics.js";
|
|
@@ -11,7 +11,7 @@ export const getNodeSdkConfig = () => {
|
|
|
11
11
|
// contain class instances with circular references that cannot be JSON serialized.
|
|
12
12
|
const { additionalInstrumentations, grpcMetadata, autoInstrumentationConfig, detection, ...serializableConfig } = nodeSDKConfig;
|
|
13
13
|
// Deep clone the serializable portion of the config
|
|
14
|
-
const clonedConfig = JSON.parse(JSON.stringify(serializableConfig));
|
|
14
|
+
const clonedConfig = /* NOSONAR */ JSON.parse(JSON.stringify(serializableConfig));
|
|
15
15
|
// Re-attach non-serializable properties by reference (they should be read-only)
|
|
16
16
|
if (additionalInstrumentations) {
|
|
17
17
|
clonedConfig.additionalInstrumentations = additionalInstrumentations;
|
|
@@ -116,7 +116,7 @@ export class PIIExporterDecorator extends OTLPExporterBase {
|
|
|
116
116
|
})
|
|
117
117
|
.map(([_, value]) => value);
|
|
118
118
|
const customRedactors = redactorsConfig.custom?.length
|
|
119
|
-
?
|
|
119
|
+
? redactorsConfig.custom.filter((redactor) => redactor instanceof BasicRedactor)
|
|
120
120
|
: [];
|
|
121
121
|
return [...defaultRedactors, ...customRedactors];
|
|
122
122
|
}
|
|
@@ -79,7 +79,13 @@ export default async function buildNodeInstrumentation(config) {
|
|
|
79
79
|
instrumentations: [
|
|
80
80
|
getNodeAutoInstrumentations(config.autoInstrumentationConfig ?? {
|
|
81
81
|
"@opentelemetry/instrumentation-fs": {
|
|
82
|
-
enabled:
|
|
82
|
+
enabled: (() => {
|
|
83
|
+
if (config.enableFS !== undefined) {
|
|
84
|
+
console.warn("[o11y] 'enableFS' is deprecated and will be removed in the next major version. " +
|
|
85
|
+
"Use 'autoInstrumentationConfig' instead.");
|
|
86
|
+
}
|
|
87
|
+
return config.enableFS ?? false;
|
|
88
|
+
})(),
|
|
83
89
|
},
|
|
84
90
|
}),
|
|
85
91
|
...(config.additionalInstrumentations ?? []),
|
|
@@ -100,7 +106,7 @@ function isUrl(url) {
|
|
|
100
106
|
new URL(url);
|
|
101
107
|
return true;
|
|
102
108
|
}
|
|
103
|
-
catch (_) {
|
|
109
|
+
catch (_) /* NOSONAR */ {
|
|
104
110
|
return false;
|
|
105
111
|
}
|
|
106
112
|
}
|
|
@@ -53,7 +53,7 @@ async function buildSentryNextjsComponents(sentryOptions, useSentrySampling = fa
|
|
|
53
53
|
skipOpenTelemetrySetup: true,
|
|
54
54
|
// Sentry Next.js defaults (which include distDirRewriteFramesIntegration, httpIntegration, etc...)
|
|
55
55
|
integrations: integrations ?? [],
|
|
56
|
-
tracesSampleRate: useSentrySampling ? (tracesSampleRate ?? 1
|
|
56
|
+
tracesSampleRate: useSentrySampling ? (tracesSampleRate ?? 1) : 1,
|
|
57
57
|
tracesSampler: useSentrySampling ? tracesSampler : undefined,
|
|
58
58
|
sendDefaultPii: sendDefaultPii ?? false,
|
|
59
59
|
enableLogs: enableLogs ?? true,
|
|
@@ -50,7 +50,7 @@ async function buildSentryComponents(sentryOptions, useSentrySampling = false) {
|
|
|
50
50
|
Sentry.postgresIntegration(),
|
|
51
51
|
Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] }),
|
|
52
52
|
],
|
|
53
|
-
tracesSampleRate: useSentrySampling ? (tracesSampleRate ?? 1
|
|
53
|
+
tracesSampleRate: useSentrySampling ? (tracesSampleRate ?? 1) : 1,
|
|
54
54
|
tracesSampler: useSentrySampling ? tracesSampler : undefined,
|
|
55
55
|
sendDefaultPii: sendDefaultPii ?? false,
|
|
56
56
|
enableLogs: enableLogs ?? true,
|
|
@@ -2,7 +2,7 @@ import type { SdkLogRecord, LogRecordProcessor } from "@opentelemetry/sdk-logs";
|
|
|
2
2
|
import type { Context } from "@opentelemetry/api";
|
|
3
3
|
import type { SignalAttributeValue } from "../index.js";
|
|
4
4
|
export declare class EnrichLogProcessor implements LogRecordProcessor {
|
|
5
|
-
private _spanAttributes
|
|
5
|
+
private readonly _spanAttributes;
|
|
6
6
|
constructor(spanAttributes?: Record<string, SignalAttributeValue | (() => SignalAttributeValue)>);
|
|
7
7
|
forceFlush(): Promise<void>;
|
|
8
8
|
onEmit(logRecord: SdkLogRecord, _context?: Context): void;
|
|
@@ -2,7 +2,7 @@ import type { Context } from "@opentelemetry/api";
|
|
|
2
2
|
import type { ReadableSpan, Span, SpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
3
3
|
import type { SignalAttributeValue } from "../index.js";
|
|
4
4
|
export declare class EnrichSpanProcessor implements SpanProcessor {
|
|
5
|
-
private _spanAttributes;
|
|
5
|
+
private readonly _spanAttributes;
|
|
6
6
|
constructor(spanAttributes?: Record<string, SignalAttributeValue | (() => SignalAttributeValue)>);
|
|
7
7
|
forceFlush(): Promise<void>;
|
|
8
8
|
onStart(span: Span, _context: Context): void;
|
|
@@ -14,7 +14,7 @@ export class NextJsSpanProcessor extends OnEndingHookSpanProcessor {
|
|
|
14
14
|
const events = span.events;
|
|
15
15
|
let cleaned = 0;
|
|
16
16
|
let exceptions = 0;
|
|
17
|
-
for (let i =
|
|
17
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
18
18
|
// Required only for NexJS v14
|
|
19
19
|
if (events[i].name == "exception") {
|
|
20
20
|
exceptions++;
|
|
@@ -22,7 +22,6 @@ export class NextJsSpanProcessor extends OnEndingHookSpanProcessor {
|
|
|
22
22
|
events[i].attributes?.["exception.message"] === "NEXT_REDIRECT") {
|
|
23
23
|
events.splice(i, 1);
|
|
24
24
|
cleaned++;
|
|
25
|
-
i--;
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
27
|
}
|
|
@@ -9,7 +9,7 @@ import { OnEndingHookSpanProcessor } from "./on-ending-hook-span-processor.js";
|
|
|
9
9
|
* just before the span is marked as ended, while the span is still writable.
|
|
10
10
|
*/
|
|
11
11
|
export declare class PseudoProfilingSpanProcessor extends OnEndingHookSpanProcessor {
|
|
12
|
-
private _spanProfilingData;
|
|
12
|
+
private readonly _spanProfilingData;
|
|
13
13
|
onStart(span: Span, _context: Context): void;
|
|
14
14
|
onEnding(span: Span): void;
|
|
15
15
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ResourceDetector, DetectedResource } from "@opentelemetry/resources";
|
|
2
2
|
import type { SignalAttributeValue } from "./index.js";
|
|
3
3
|
export declare class ObservabilityResourceDetector implements ResourceDetector {
|
|
4
|
-
private _resourceAttributes;
|
|
4
|
+
private readonly _resourceAttributes;
|
|
5
5
|
constructor(resourceAttributes?: Record<string, SignalAttributeValue>);
|
|
6
6
|
detect(): DetectedResource;
|
|
7
7
|
}
|
|
@@ -2,6 +2,7 @@ import { type Span, type SpanOptions } from "@opentelemetry/api";
|
|
|
2
2
|
export type WithSpanParams<T> = {
|
|
3
3
|
/**
|
|
4
4
|
* The name of the trace the span should belong to.
|
|
5
|
+
* If not provided the span will default to the "o11y-sdk" tracer or the serviceName provided in the SDK config if available.
|
|
5
6
|
* NOTE: If you want the new span to belong to an already existing trace, you should provide the same tracer name
|
|
6
7
|
*/
|
|
7
8
|
traceName?: string;
|
|
@@ -1,39 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { trace } from "@opentelemetry/api";
|
|
2
|
+
import { selfContainedSpanHandlerGenerator } from "../../sdk-core/lib/utils/traces.js";
|
|
2
3
|
import { getNodeSdkConfig } from "./config-manager.js";
|
|
3
|
-
/**
|
|
4
|
-
* Generates a function wrapping a given Callable `fn` into an error handling block.
|
|
5
|
-
* Setting Span status and recording any caught exception before bubbling it up.
|
|
6
|
-
*
|
|
7
|
-
* Marks the span as ended once the provided callable has ended or an error has been caught.
|
|
8
|
-
*
|
|
9
|
-
* @returns {Promise<T>} where T is the type returned by the Callable.
|
|
10
|
-
* @throws any error thrown by the original Callable `fn` provided.
|
|
11
|
-
*/
|
|
12
|
-
function selfContainedSpanHandlerGenerator(fn) {
|
|
13
|
-
return async (span) => {
|
|
14
|
-
try {
|
|
15
|
-
const fnResult = await fn(span);
|
|
16
|
-
span.setStatus({ code: SpanStatusCode.OK });
|
|
17
|
-
return fnResult;
|
|
18
|
-
}
|
|
19
|
-
catch (err) {
|
|
20
|
-
if (err instanceof Error) {
|
|
21
|
-
span.recordException(err);
|
|
22
|
-
span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
|
|
23
|
-
throw err;
|
|
24
|
-
}
|
|
25
|
-
span.recordException({ message: JSON.stringify(err) });
|
|
26
|
-
span.setStatus({
|
|
27
|
-
code: SpanStatusCode.ERROR,
|
|
28
|
-
message: JSON.stringify(err),
|
|
29
|
-
});
|
|
30
|
-
throw err;
|
|
31
|
-
}
|
|
32
|
-
finally {
|
|
33
|
-
span.end();
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
4
|
/**
|
|
38
5
|
* Gets the currently active OpenTelemetry span.
|
|
39
6
|
*
|
|
@@ -2,8 +2,8 @@ import { type Attributes, type Context, type Link, SpanKind } from "@opentelemet
|
|
|
2
2
|
import { type Sampler, type SamplingResult } from "@opentelemetry/sdk-trace-base";
|
|
3
3
|
import type { SamplerCondition } from "./index.js";
|
|
4
4
|
export declare class UrlSampler implements Sampler {
|
|
5
|
-
private _samplerCondition;
|
|
6
|
-
private _nextSampler;
|
|
5
|
+
private readonly _samplerCondition;
|
|
6
|
+
private readonly _nextSampler;
|
|
7
7
|
constructor(samplerCondition: SamplerCondition[] | undefined, nextSampler: Sampler);
|
|
8
8
|
shouldSample(_context: Context, traceId: string, _spanName: string, _spanKind: SpanKind, attributes: Attributes, _links: Link[]): SamplingResult;
|
|
9
9
|
toString(): string;
|
|
@@ -2,8 +2,8 @@ import { SamplingDecision, } from "@opentelemetry/sdk-trace-base";
|
|
|
2
2
|
export class UrlSampler {
|
|
3
3
|
_samplerCondition;
|
|
4
4
|
_nextSampler;
|
|
5
|
-
constructor(samplerCondition
|
|
6
|
-
this._samplerCondition = samplerCondition;
|
|
5
|
+
constructor(samplerCondition, nextSampler) {
|
|
6
|
+
this._samplerCondition = samplerCondition ?? [];
|
|
7
7
|
this._nextSampler = nextSampler;
|
|
8
8
|
}
|
|
9
9
|
shouldSample(_context, traceId, _spanName, _spanKind, attributes, _links) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ogcio/o11y-sdk-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Opentelemetry standard instrumentation SDK for NodeJS based project",
|
|
5
|
-
"main": "dist/index.js",
|
|
5
|
+
"main": "dist/sdk-node/index.js",
|
|
6
|
+
"types": "dist/sdk-node/index.d.ts",
|
|
6
7
|
"type": "module",
|
|
7
8
|
"scripts": {
|
|
8
9
|
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
@@ -35,31 +36,30 @@
|
|
|
35
36
|
"license": "ISC",
|
|
36
37
|
"dependencies": {
|
|
37
38
|
"@grpc/grpc-js": "1.14.3",
|
|
38
|
-
"@opentelemetry/api": "
|
|
39
|
-
"@opentelemetry/api-logs": "0.
|
|
40
|
-
"@opentelemetry/auto-instrumentations-node": "0.
|
|
41
|
-
"@opentelemetry/context-async-hooks": "2.6.
|
|
42
|
-
"@opentelemetry/core": "
|
|
43
|
-
"@opentelemetry/exporter-logs-otlp-grpc": "0.
|
|
44
|
-
"@opentelemetry/exporter-logs-otlp-http": "0.
|
|
45
|
-
"@opentelemetry/exporter-metrics-otlp-grpc": "0.
|
|
46
|
-
"@opentelemetry/exporter-metrics-otlp-http": "0.
|
|
47
|
-
"@opentelemetry/exporter-trace-otlp-grpc": "0.
|
|
48
|
-
"@opentelemetry/exporter-trace-otlp-http": "0.
|
|
49
|
-
"@opentelemetry/instrumentation": "0.
|
|
50
|
-
"@opentelemetry/otlp-exporter-base": "0.
|
|
51
|
-
"@opentelemetry/resources": "2.6.
|
|
52
|
-
"@opentelemetry/sdk-logs": "0.
|
|
53
|
-
"@opentelemetry/sdk-metrics": "2.6.
|
|
54
|
-
"@opentelemetry/sdk-node": "0.
|
|
55
|
-
"@opentelemetry/sdk-trace-base": "2.6.
|
|
39
|
+
"@opentelemetry/api": "catalog:",
|
|
40
|
+
"@opentelemetry/api-logs": "0.214.0",
|
|
41
|
+
"@opentelemetry/auto-instrumentations-node": "0.72.0",
|
|
42
|
+
"@opentelemetry/context-async-hooks": "2.6.1",
|
|
43
|
+
"@opentelemetry/core": "catalog:",
|
|
44
|
+
"@opentelemetry/exporter-logs-otlp-grpc": "0.214.0",
|
|
45
|
+
"@opentelemetry/exporter-logs-otlp-http": "0.214.0",
|
|
46
|
+
"@opentelemetry/exporter-metrics-otlp-grpc": "0.214.0",
|
|
47
|
+
"@opentelemetry/exporter-metrics-otlp-http": "0.214.0",
|
|
48
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "0.214.0",
|
|
49
|
+
"@opentelemetry/exporter-trace-otlp-http": "0.214.0",
|
|
50
|
+
"@opentelemetry/instrumentation": "0.214.0",
|
|
51
|
+
"@opentelemetry/otlp-exporter-base": "0.214.0",
|
|
52
|
+
"@opentelemetry/resources": "2.6.1",
|
|
53
|
+
"@opentelemetry/sdk-logs": "0.214.0",
|
|
54
|
+
"@opentelemetry/sdk-metrics": "2.6.1",
|
|
55
|
+
"@opentelemetry/sdk-node": "0.214.0",
|
|
56
|
+
"@opentelemetry/sdk-trace-base": "2.6.1"
|
|
56
57
|
},
|
|
57
58
|
"devDependencies": {
|
|
58
|
-
"@types/node": "
|
|
59
|
-
"@vitest/coverage-v8": "
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"vitest": "4.0.18"
|
|
59
|
+
"@types/node": "catalog:",
|
|
60
|
+
"@vitest/coverage-v8": "catalog:",
|
|
61
|
+
"typescript": "catalog:",
|
|
62
|
+
"vitest": "catalog:"
|
|
63
63
|
},
|
|
64
64
|
"engines": {
|
|
65
65
|
"node": ">=20.6.0"
|
package/package.json
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ogcio/o11y-sdk-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Opentelemetry standard instrumentation SDK for NodeJS based project",
|
|
5
|
-
"main": "dist/index.js",
|
|
5
|
+
"main": "dist/sdk-node/index.js",
|
|
6
|
+
"types": "dist/sdk-node/index.d.ts",
|
|
6
7
|
"type": "module",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
10
|
+
"test": "vitest",
|
|
11
|
+
"prepublishOnly": "pnpm i && rm -rf dist && tsc -p tsconfig.json",
|
|
12
|
+
"test:unit": "vitest --project unit",
|
|
13
|
+
"test:integration": "pnpm test:integration:setup && pnpm test:integration:run && pnpm test:integration:assert && pnpm test:integration:teardown",
|
|
14
|
+
"test:integration:setup": "sh ./test/integration/setup.sh integration",
|
|
15
|
+
"test:integration:run": "pnpm --filter @ogcio/o11y run prepare:integration",
|
|
16
|
+
"test:integration:assert": "vitest --project integration",
|
|
17
|
+
"test:integration:teardown": "sh ./test/integration/teardown.sh integration"
|
|
18
|
+
},
|
|
7
19
|
"exports": {
|
|
8
20
|
".": "./dist/sdk-node/index.js",
|
|
9
21
|
"./*": "./dist/*.js",
|
|
@@ -24,31 +36,30 @@
|
|
|
24
36
|
"license": "ISC",
|
|
25
37
|
"dependencies": {
|
|
26
38
|
"@grpc/grpc-js": "1.14.3",
|
|
27
|
-
"@opentelemetry/api": "
|
|
28
|
-
"@opentelemetry/api-logs": "0.
|
|
29
|
-
"@opentelemetry/auto-instrumentations-node": "0.
|
|
30
|
-
"@opentelemetry/context-async-hooks": "2.6.
|
|
31
|
-
"@opentelemetry/core": "
|
|
32
|
-
"@opentelemetry/exporter-logs-otlp-grpc": "0.
|
|
33
|
-
"@opentelemetry/exporter-logs-otlp-http": "0.
|
|
34
|
-
"@opentelemetry/exporter-metrics-otlp-grpc": "0.
|
|
35
|
-
"@opentelemetry/exporter-metrics-otlp-http": "0.
|
|
36
|
-
"@opentelemetry/exporter-trace-otlp-grpc": "0.
|
|
37
|
-
"@opentelemetry/exporter-trace-otlp-http": "0.
|
|
38
|
-
"@opentelemetry/instrumentation": "0.
|
|
39
|
-
"@opentelemetry/otlp-exporter-base": "0.
|
|
40
|
-
"@opentelemetry/resources": "2.6.
|
|
41
|
-
"@opentelemetry/sdk-logs": "0.
|
|
42
|
-
"@opentelemetry/sdk-metrics": "2.6.
|
|
43
|
-
"@opentelemetry/sdk-node": "0.
|
|
44
|
-
"@opentelemetry/sdk-trace-base": "2.6.
|
|
39
|
+
"@opentelemetry/api": "catalog:",
|
|
40
|
+
"@opentelemetry/api-logs": "0.214.0",
|
|
41
|
+
"@opentelemetry/auto-instrumentations-node": "0.72.0",
|
|
42
|
+
"@opentelemetry/context-async-hooks": "2.6.1",
|
|
43
|
+
"@opentelemetry/core": "catalog:",
|
|
44
|
+
"@opentelemetry/exporter-logs-otlp-grpc": "0.214.0",
|
|
45
|
+
"@opentelemetry/exporter-logs-otlp-http": "0.214.0",
|
|
46
|
+
"@opentelemetry/exporter-metrics-otlp-grpc": "0.214.0",
|
|
47
|
+
"@opentelemetry/exporter-metrics-otlp-http": "0.214.0",
|
|
48
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "0.214.0",
|
|
49
|
+
"@opentelemetry/exporter-trace-otlp-http": "0.214.0",
|
|
50
|
+
"@opentelemetry/instrumentation": "0.214.0",
|
|
51
|
+
"@opentelemetry/otlp-exporter-base": "0.214.0",
|
|
52
|
+
"@opentelemetry/resources": "2.6.1",
|
|
53
|
+
"@opentelemetry/sdk-logs": "0.214.0",
|
|
54
|
+
"@opentelemetry/sdk-metrics": "2.6.1",
|
|
55
|
+
"@opentelemetry/sdk-node": "0.214.0",
|
|
56
|
+
"@opentelemetry/sdk-trace-base": "2.6.1"
|
|
45
57
|
},
|
|
46
58
|
"devDependencies": {
|
|
47
|
-
"@types/node": "
|
|
48
|
-
"@vitest/coverage-v8": "
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"vitest": "4.0.18"
|
|
59
|
+
"@types/node": "catalog:",
|
|
60
|
+
"@vitest/coverage-v8": "catalog:",
|
|
61
|
+
"typescript": "catalog:",
|
|
62
|
+
"vitest": "catalog:"
|
|
52
63
|
},
|
|
53
64
|
"engines": {
|
|
54
65
|
"node": ">=20.6.0"
|
|
@@ -68,15 +79,5 @@
|
|
|
68
79
|
"@sentry/nextjs": {
|
|
69
80
|
"optional": true
|
|
70
81
|
}
|
|
71
|
-
},
|
|
72
|
-
"scripts": {
|
|
73
|
-
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
74
|
-
"test": "vitest",
|
|
75
|
-
"test:unit": "vitest --project unit",
|
|
76
|
-
"test:integration": "pnpm test:integration:setup && pnpm test:integration:run && pnpm test:integration:assert && pnpm test:integration:teardown",
|
|
77
|
-
"test:integration:setup": "sh ./test/integration/setup.sh integration",
|
|
78
|
-
"test:integration:run": "pnpm --filter @ogcio/o11y run prepare:integration",
|
|
79
|
-
"test:integration:assert": "vitest --project integration",
|
|
80
|
-
"test:integration:teardown": "sh ./test/integration/teardown.sh integration"
|
|
81
82
|
}
|
|
82
|
-
}
|
|
83
|
+
}
|