@sentienguard/apm 1.0.14 → 1.0.15
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/package.json +1 -1
- package/src/tracing.js +76 -0
package/package.json
CHANGED
package/src/tracing.js
CHANGED
|
@@ -18,6 +18,54 @@ import { SentienGuardTraceSpanExporter } from './traceSpanExporter.js';
|
|
|
18
18
|
let sdk = null;
|
|
19
19
|
let tracingActive = false;
|
|
20
20
|
|
|
21
|
+
function setAttr(span, key, value) {
|
|
22
|
+
try {
|
|
23
|
+
if (!span || typeof span.setAttribute !== 'function') return;
|
|
24
|
+
if (value == null) return;
|
|
25
|
+
const v = typeof value === 'string' ? value : String(value);
|
|
26
|
+
if (!v) return;
|
|
27
|
+
span.setAttribute(key, v);
|
|
28
|
+
} catch {
|
|
29
|
+
// ignore
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function setAttrNumber(span, key, value) {
|
|
34
|
+
try {
|
|
35
|
+
if (!span || typeof span.setAttribute !== 'function') return;
|
|
36
|
+
const n = Number(value);
|
|
37
|
+
if (!Number.isFinite(n)) return;
|
|
38
|
+
span.setAttribute(key, n);
|
|
39
|
+
} catch {
|
|
40
|
+
// ignore
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function safeUrlFromOutgoingRequest(requestOptions) {
|
|
45
|
+
try {
|
|
46
|
+
if (!requestOptions) return '';
|
|
47
|
+
if (typeof requestOptions === 'string') return requestOptions;
|
|
48
|
+
if (requestOptions instanceof URL) return requestOptions.toString();
|
|
49
|
+
const protocol = requestOptions.protocol || 'http:';
|
|
50
|
+
const hostRaw = requestOptions.hostname || requestOptions.host || '';
|
|
51
|
+
const host = String(hostRaw).trim();
|
|
52
|
+
const path = requestOptions.path || requestOptions.pathname || '/';
|
|
53
|
+
if (!host) return '';
|
|
54
|
+
return `${protocol}//${host}${path}`;
|
|
55
|
+
} catch {
|
|
56
|
+
return '';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function safeHostFromIncoming(req) {
|
|
61
|
+
try {
|
|
62
|
+
const h = req?.headers?.host;
|
|
63
|
+
return h ? String(h).split(',')[0].trim() : '';
|
|
64
|
+
} catch {
|
|
65
|
+
return '';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
21
69
|
function shouldIgnoreOutgoingHost(hostname) {
|
|
22
70
|
if (!hostname) return false;
|
|
23
71
|
const host = hostname.split(':')[0];
|
|
@@ -64,6 +112,34 @@ export function startTracing() {
|
|
|
64
112
|
ignoreOutgoingRequestHook: (requestOptions) => {
|
|
65
113
|
const host = requestOptions.hostname || (requestOptions.host ? String(requestOptions.host).split(':')[0] : '');
|
|
66
114
|
return shouldIgnoreOutgoingHost(host);
|
|
115
|
+
},
|
|
116
|
+
/**
|
|
117
|
+
* Ensure we always attach basic HTTP attributes.
|
|
118
|
+
* This protects us from cases where the underlying instrumentation
|
|
119
|
+
* doesn't populate attributes (common in some Node/Jest/undici combos).
|
|
120
|
+
*/
|
|
121
|
+
requestHook: (span, request) => {
|
|
122
|
+
// Incoming request (SERVER)
|
|
123
|
+
if (request && typeof request === 'object' && 'headers' in request && 'method' in request) {
|
|
124
|
+
setAttr(span, 'http.method', request.method);
|
|
125
|
+
setAttr(span, 'http.target', request.url);
|
|
126
|
+
setAttr(span, 'http.host', safeHostFromIncoming(request));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Outgoing request (CLIENT) — requestOptions
|
|
131
|
+
setAttr(span, 'http.method', request?.method);
|
|
132
|
+
const url = safeUrlFromOutgoingRequest(request);
|
|
133
|
+
if (url) setAttr(span, 'http.url', url);
|
|
134
|
+
const host = request?.hostname || (request?.host ? String(request.host).split(':')[0] : '');
|
|
135
|
+
if (host) setAttr(span, 'net.peer.name', host);
|
|
136
|
+
if (request?.port) setAttrNumber(span, 'net.peer.port', request.port);
|
|
137
|
+
},
|
|
138
|
+
responseHook: (span, response) => {
|
|
139
|
+
// Incoming response (SERVER): ServerResponse
|
|
140
|
+
if (response && typeof response === 'object' && 'statusCode' in response) {
|
|
141
|
+
setAttrNumber(span, 'http.status_code', response.statusCode);
|
|
142
|
+
}
|
|
67
143
|
}
|
|
68
144
|
});
|
|
69
145
|
|