@newrelic/preflight 1.0.3 → 1.0.5
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 +7 -1
- package/dist/alerts/types.d.ts.map +1 -1
- package/dist/alerts/types.js.map +1 -1
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -3
- package/dist/config.js.map +1 -1
- package/dist/dashboard/dashboard-server.d.ts +4 -0
- package/dist/dashboard/dashboard-server.d.ts.map +1 -1
- package/dist/dashboard/dashboard-server.js +42 -1
- package/dist/dashboard/dashboard-server.js.map +1 -1
- package/dist/dashboard/live-event-bus.js +2 -2
- package/dist/dashboard/live-event-bus.js.map +1 -1
- package/dist/dashboard/routes/sse-handler.js +3 -3
- package/dist/dashboard/routes/sse-handler.js.map +1 -1
- package/dist/hooks/collector-script.d.ts.map +1 -1
- package/dist/hooks/collector-script.js +1 -5
- package/dist/hooks/collector-script.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/install/cli.d.ts +1 -0
- package/dist/install/cli.d.ts.map +1 -1
- package/dist/install/cli.js +306 -106
- package/dist/install/cli.js.map +1 -1
- package/dist/install/install-helper.d.ts +5 -4
- package/dist/install/install-helper.d.ts.map +1 -1
- package/dist/install/install-helper.js +2 -2
- package/dist/install/install-helper.js.map +1 -1
- package/dist/install/json-utils.d.ts +4 -0
- package/dist/install/json-utils.d.ts.map +1 -0
- package/dist/install/json-utils.js +88 -0
- package/dist/install/json-utils.js.map +1 -0
- package/dist/install/migrate.d.ts.map +1 -1
- package/dist/install/migrate.js +57 -1
- package/dist/install/migrate.js.map +1 -1
- package/dist/install/schedule.d.ts +1 -0
- package/dist/install/schedule.d.ts.map +1 -1
- package/dist/install/schedule.js +23 -5
- package/dist/install/schedule.js.map +1 -1
- package/dist/install/setup-wizard.d.ts.map +1 -1
- package/dist/install/setup-wizard.js +105 -44
- package/dist/install/setup-wizard.js.map +1 -1
- package/dist/metrics/anti-patterns.d.ts.map +1 -1
- package/dist/metrics/anti-patterns.js.map +1 -1
- package/dist/metrics/context-composition-tracker.d.ts.map +1 -1
- package/dist/metrics/context-composition-tracker.js.map +1 -1
- package/dist/platforms/copilot-adapter.d.ts.map +1 -1
- package/dist/platforms/copilot-adapter.js.map +1 -1
- package/dist/proxy/otlp-receiver.d.ts.map +1 -1
- package/dist/proxy/otlp-receiver.js.map +1 -1
- package/dist/proxy/proxy-manager.js +1 -1
- package/dist/proxy/proxy-manager.js.map +1 -1
- package/dist/proxy/upstream-stdio.d.ts.map +1 -1
- package/dist/proxy/upstream-stdio.js.map +1 -1
- package/dist/security/ssrf.js +1 -1
- package/dist/security/ssrf.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -1
- package/dist/server.js.map +1 -1
- package/dist/shared/__test-utils__/log-output.d.ts +1 -2
- package/dist/shared/__test-utils__/log-output.d.ts.map +1 -1
- package/dist/shared/__test-utils__/log-output.js +1 -2
- package/dist/shared/__test-utils__/log-output.js.map +1 -1
- package/dist/shared/config.d.ts +8 -2
- package/dist/shared/config.d.ts.map +1 -1
- package/dist/shared/config.js +20 -20
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/errors.d.ts +1 -1
- package/dist/shared/errors.js +10 -10
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/events/factory.js +12 -12
- package/dist/shared/events/factory.js.map +1 -1
- package/dist/shared/events/serialize.d.ts +2 -2
- package/dist/shared/events/serialize.js +19 -19
- package/dist/shared/events/serialize.js.map +1 -1
- package/dist/shared/harvest/event-buffer.d.ts +2 -2
- package/dist/shared/harvest/event-buffer.js +3 -3
- package/dist/shared/harvest/event-buffer.js.map +1 -1
- package/dist/shared/harvest/harvest-scheduler.d.ts +4 -5
- package/dist/shared/harvest/harvest-scheduler.d.ts.map +1 -1
- package/dist/shared/harvest/harvest-scheduler.js +35 -35
- package/dist/shared/harvest/harvest-scheduler.js.map +1 -1
- package/dist/shared/harvest/metric-aggregator.d.ts +9 -9
- package/dist/shared/harvest/metric-aggregator.d.ts.map +1 -1
- package/dist/shared/harvest/metric-aggregator.js +16 -18
- package/dist/shared/harvest/metric-aggregator.js.map +1 -1
- package/dist/shared/index.d.ts +0 -1
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +0 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/logger.d.ts +4 -5
- package/dist/shared/logger.d.ts.map +1 -1
- package/dist/shared/logger.js +12 -12
- package/dist/shared/logger.js.map +1 -1
- package/dist/shared/pricing-data.js +10 -10
- package/dist/shared/pricing-data.js.map +1 -1
- package/dist/shared/pricing.d.ts +3 -3
- package/dist/shared/pricing.js +12 -12
- package/dist/shared/pricing.js.map +1 -1
- package/dist/shared/redact.d.ts +1 -3
- package/dist/shared/redact.d.ts.map +1 -1
- package/dist/shared/redact.js +8 -10
- package/dist/shared/redact.js.map +1 -1
- package/dist/shared/timing.d.ts +4 -4
- package/dist/shared/timing.d.ts.map +1 -1
- package/dist/shared/timing.js +9 -9
- package/dist/shared/timing.js.map +1 -1
- package/dist/shared/tokens.d.ts +4 -4
- package/dist/shared/tokens.js +16 -16
- package/dist/shared/tokens.js.map +1 -1
- package/dist/shared/transport/events-api.d.ts +1 -1
- package/dist/shared/transport/events-api.d.ts.map +1 -1
- package/dist/shared/transport/events-api.js +2 -1
- package/dist/shared/transport/events-api.js.map +1 -1
- package/dist/shared/transport/http-client.d.ts +1 -1
- package/dist/shared/transport/http-client.d.ts.map +1 -1
- package/dist/shared/transport/http-client.js +19 -28
- package/dist/shared/transport/http-client.js.map +1 -1
- package/dist/shared/transport/logs-api.d.ts +2 -3
- package/dist/shared/transport/logs-api.d.ts.map +1 -1
- package/dist/shared/transport/logs-api.js +3 -3
- package/dist/shared/transport/logs-api.js.map +1 -1
- package/dist/shared/transport/metric-api.d.ts.map +1 -1
- package/dist/shared/transport/metric-api.js +1 -0
- package/dist/shared/transport/metric-api.js.map +1 -1
- package/dist/shared/transport/otlp-event-bridge.d.ts +10 -5
- package/dist/shared/transport/otlp-event-bridge.d.ts.map +1 -1
- package/dist/shared/transport/otlp-event-bridge.js +20 -11
- package/dist/shared/transport/otlp-event-bridge.js.map +1 -1
- package/dist/shared/transport/otlp-shared.d.ts +12 -1
- package/dist/shared/transport/otlp-shared.d.ts.map +1 -1
- package/dist/shared/transport/otlp-shared.js +20 -4
- package/dist/shared/transport/otlp-shared.js.map +1 -1
- package/dist/shared/transport/otlp-transport.d.ts +22 -19
- package/dist/shared/transport/otlp-transport.d.ts.map +1 -1
- package/dist/shared/transport/otlp-transport.js +136 -120
- package/dist/shared/transport/otlp-transport.js.map +1 -1
- package/dist/shared/transport/types.d.ts +7 -3
- package/dist/shared/transport/types.d.ts.map +1 -1
- package/dist/storage/session-store.js +1 -1
- package/dist/storage/weekly-summary.js +3 -3
- package/dist/storage/weekly-summary.js.map +1 -1
- package/dist/tools/cross-session-tools.js +1 -1
- package/dist/tools/cross-session-tools.js.map +1 -1
- package/dist/tools/session-stats.d.ts.map +1 -1
- package/dist/tools/session-stats.js +2 -1
- package/dist/tools/session-stats.js.map +1 -1
- package/dist/tracing/mcp-tracer.js +1 -1
- package/dist/tracing/mcp-tracer.js.map +1 -1
- package/dist/transport/nr-ingest.d.ts.map +1 -1
- package/dist/transport/nr-ingest.js +4 -0
- package/dist/transport/nr-ingest.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +21 -0
- package/dist/version.js.map +1 -0
- package/dist/web/assets/index-CW0UCwb9.css +2 -0
- package/dist/web/assets/index-HRyb4aZK.js +64 -0
- package/dist/web/index.html +2 -2
- package/package.json +23 -23
- package/dist/shared/version.d.ts +0 -2
- package/dist/shared/version.d.ts.map +0 -1
- package/dist/shared/version.js +0 -2
- package/dist/shared/version.js.map +0 -1
- package/dist/web/assets/index-BrL281N-.css +0 -2
- package/dist/web/assets/index-CcaYZzXm.js +0 -42
|
@@ -3,7 +3,7 @@ import { sendWithRetry, resolveRegion, getEventsApiUrl } from './http-client.js'
|
|
|
3
3
|
* Send a batch of events to NR's Events API. Compresses with gzip, retries
|
|
4
4
|
* with exponential backoff (capped, jittered, Retry-After-aware), and
|
|
5
5
|
* surfaces 4xx response bodies in the result so callers can distinguish
|
|
6
|
-
* license-key from payload-shape failures
|
|
6
|
+
* license-key from payload-shape failures.
|
|
7
7
|
*
|
|
8
8
|
* Returns a {@link TransportResult} the harvest scheduler uses to decide
|
|
9
9
|
* whether to requeue the batch. Per-request timeout is honored via
|
|
@@ -24,6 +24,7 @@ export async function sendEvents(events, licenseKey, options) {
|
|
|
24
24
|
maxDelayMs: options.maxDelayMs ?? 30_000,
|
|
25
25
|
requestTimeoutMs: options.requestTimeoutMs ?? 30_000,
|
|
26
26
|
clientName: options.clientName,
|
|
27
|
+
clientVersion: options.clientVersion,
|
|
27
28
|
});
|
|
28
29
|
}
|
|
29
30
|
//# sourceMappingURL=events-api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events-api.js","sourceRoot":"","sources":["../../../src/shared/transport/events-api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEjF;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAqB,EACrB,UAAkB,EAClB,OAAyB;IAEzB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC5D,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IAEtF,OAAO,aAAa,CAAC;QACnB,GAAG;QACH,IAAI,EAAE,MAAM;QACZ,UAAU;QACV,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC;QACnC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;QACxC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,MAAM;QACxC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,MAAM;QACpD,UAAU,EAAE,OAAO,CAAC,UAAU;
|
|
1
|
+
{"version":3,"file":"events-api.js","sourceRoot":"","sources":["../../../src/shared/transport/events-api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEjF;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAqB,EACrB,UAAkB,EAClB,OAAyB;IAEzB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC5D,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IAEtF,OAAO,aAAa,CAAC;QACnB,GAAG;QACH,IAAI,EAAE,MAAM;QACZ,UAAU;QACV,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC;QACnC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;QACxC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,MAAM;QACxC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,MAAM;QACpD,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;KACrC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -24,7 +24,7 @@ export declare function getLogsApiUrl(region: Region, collectorHost?: string | n
|
|
|
24
24
|
*
|
|
25
25
|
* The returned Buffer is immutable after the call (`zlib.gzip` is a
|
|
26
26
|
* one-shot, not a stateful stream), so it is safe for `sendWithRetry` to
|
|
27
|
-
* reuse the same `compressed` Buffer across retry attempts
|
|
27
|
+
* reuse the same `compressed` Buffer across retry attempts. If a
|
|
28
28
|
* future refactor moves to a stateful gzip stream, that reuse becomes
|
|
29
29
|
* unsafe — pin the call site outside the retry loop accordingly.
|
|
30
30
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/http-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/http-client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAgBnE;;;;;;;;;GASG;AACH,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;AAgBzC,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAsCtF;AA4DD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAC5B,MAAM,CAiBR;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAKrF;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAKnF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAEpE;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,MAAM,CAQR;AA4BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAyKtF"}
|
|
@@ -2,22 +2,12 @@ import { gzip } from 'node:zlib';
|
|
|
2
2
|
import { promisify } from 'node:util';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
4
|
import { createLogger } from '../logger.js';
|
|
5
|
-
import {
|
|
6
|
-
import { DEFAULT_CLIENT_NAME } from './otlp-shared.js';
|
|
7
|
-
/**
|
|
8
|
-
* Builds the `User-Agent` header value for outbound NR ingest requests
|
|
9
|
-
*. NR's collector logs the UA, so identifying the
|
|
10
|
-
* consuming client by name and version makes operator-side investigation
|
|
11
|
-
* tractable (e.g. "which client version is producing the malformed payload?").
|
|
12
|
-
*/
|
|
13
|
-
function buildUserAgent(clientName) {
|
|
14
|
-
return `${clientName || DEFAULT_CLIENT_NAME}/${VERSION}`;
|
|
15
|
-
}
|
|
5
|
+
import { buildUserAgent } from './otlp-shared.js';
|
|
16
6
|
const gzipAsync = promisify(gzip);
|
|
17
7
|
const logger = createLogger('transport');
|
|
18
8
|
/**
|
|
19
|
-
* Generate a short correlation ID for an outbound batch
|
|
20
|
-
*
|
|
9
|
+
* Generate a short correlation ID for an outbound batch.
|
|
10
|
+
* Eight hex chars derived from a v4 UUID is
|
|
21
11
|
* enough entropy to disambiguate concurrent retries in stderr without
|
|
22
12
|
* adding meaningful payload weight or scanning friction.
|
|
23
13
|
*/
|
|
@@ -40,7 +30,7 @@ export function resolveRegion(licenseKey, collectorHost) {
|
|
|
40
30
|
// collectorHost overrides take priority — they are an explicit user choice.
|
|
41
31
|
// Only recognise the keyword form (bare word, no dots or colons).
|
|
42
32
|
// Substring matching against FQDNs produced false positives: a host like
|
|
43
|
-
// 'bureau-collector.local' matches 'eu', 'eucalyptus.test' likewise
|
|
33
|
+
// 'bureau-collector.local' matches 'eu', 'eucalyptus.test' likewise.
|
|
44
34
|
if (collectorHost) {
|
|
45
35
|
const host = collectorHost.toLowerCase().trim();
|
|
46
36
|
if (!host.includes('.') && !host.includes(':')) {
|
|
@@ -74,14 +64,14 @@ export function resolveRegion(licenseKey, collectorHost) {
|
|
|
74
64
|
return 'us';
|
|
75
65
|
}
|
|
76
66
|
/**
|
|
77
|
-
*
|
|
67
|
+
* When `collectorHost` is provided AND looks like a real hostname (has a
|
|
78
68
|
* dot or colon — i.e. an FQDN or host:port), treat it as a literal override and
|
|
79
69
|
* use it as the URL host for ALL three APIs (events, metric, logs). The path
|
|
80
70
|
* remains per-API since the user's proxy must route by path.
|
|
81
71
|
*
|
|
82
72
|
* Without a dot or colon, `collectorHost` is treated as an exact region keyword
|
|
83
73
|
* (one of 'us', 'eu', 'gov') — `resolveRegion` maps it to the
|
|
84
|
-
* appropriate NR hostnames for all three APIs (
|
|
74
|
+
* appropriate NR hostnames for all three APIs (no substring matching).
|
|
85
75
|
*
|
|
86
76
|
*/
|
|
87
77
|
function isLiteralHostname(collectorHost) {
|
|
@@ -90,7 +80,7 @@ function isLiteralHostname(collectorHost) {
|
|
|
90
80
|
return collectorHost.includes('.') || collectorHost.includes(':');
|
|
91
81
|
}
|
|
92
82
|
/**
|
|
93
|
-
* Per-region NR ingest hostnames
|
|
83
|
+
* Per-region NR ingest hostnames.
|
|
94
84
|
*
|
|
95
85
|
* Single source of truth — the three URL builders below all read from this
|
|
96
86
|
* table instead of inlining the same nested-ternary three times. To add a
|
|
@@ -100,7 +90,7 @@ function isLiteralHostname(collectorHost) {
|
|
|
100
90
|
* The table is intentionally NOT exported. Hostnames are NR-operated
|
|
101
91
|
* implementation detail — exposing them as a public constant invites
|
|
102
92
|
* consumers to depend on specific values, which would break if NR ever
|
|
103
|
-
* renames a host
|
|
93
|
+
* renames a host. Consumers that need to override an endpoint
|
|
104
94
|
* should use the `collectorHost` option instead, which already routes
|
|
105
95
|
* through `isLiteralHostname()` above.
|
|
106
96
|
*/
|
|
@@ -122,7 +112,7 @@ const NR_INGEST_HOSTS = Object.freeze({
|
|
|
122
112
|
},
|
|
123
113
|
});
|
|
124
114
|
export function getEventsApiUrl(accountId, region, collectorHost) {
|
|
125
|
-
//
|
|
115
|
+
// Defensive guard against an empty/null/undefined accountId
|
|
126
116
|
// that bypassed `loadConfig`'s fail-fast (e.g. a JS caller, an explicit
|
|
127
117
|
// `accountId: config.accountId!` non-null assertion, or a custom config
|
|
128
118
|
// path that didn't go through loadConfig). Without this, the URL becomes
|
|
@@ -159,7 +149,7 @@ export function getLogsApiUrl(region, collectorHost) {
|
|
|
159
149
|
*
|
|
160
150
|
* The returned Buffer is immutable after the call (`zlib.gzip` is a
|
|
161
151
|
* one-shot, not a stateful stream), so it is safe for `sendWithRetry` to
|
|
162
|
-
* reuse the same `compressed` Buffer across retry attempts
|
|
152
|
+
* reuse the same `compressed` Buffer across retry attempts. If a
|
|
163
153
|
* future refactor moves to a stateful gzip stream, that reuse becomes
|
|
164
154
|
* unsafe — pin the call site outside the retry loop accordingly.
|
|
165
155
|
*/
|
|
@@ -187,7 +177,7 @@ function delay(ms) {
|
|
|
187
177
|
export function decorrelatedJitter(baseDelayMs, maxDelayMs, prevSleepMs) {
|
|
188
178
|
// Clamp upper to at least baseDelayMs so the jitter band [base, upper] is
|
|
189
179
|
// never negative when maxDelayMs < baseDelayMs (a misconfiguration, but
|
|
190
|
-
// unguarded — without the clamp the sample can be zero or negative
|
|
180
|
+
// unguarded — without the clamp the sample can be zero or negative).
|
|
191
181
|
const upper = Math.max(baseDelayMs, Math.min(maxDelayMs, prevSleepMs * 3));
|
|
192
182
|
// Math.random() returns [0, 1); spread baseDelayMs..upper.
|
|
193
183
|
const sample = baseDelayMs + (upper - baseDelayMs) * Math.random();
|
|
@@ -220,7 +210,7 @@ function parseRetryAfterMs(response) {
|
|
|
220
210
|
}
|
|
221
211
|
export async function sendWithRetry(options) {
|
|
222
212
|
const { url, body, licenseKey, maxRetries, baseDelayMs, maxDelayMs, requestTimeoutMs } = options;
|
|
223
|
-
// Per-request correlation ID
|
|
213
|
+
// Per-request correlation ID. Stamped on every
|
|
224
214
|
// log line emitted from this call so concurrent retries to different
|
|
225
215
|
// batches can be disambiguated in stderr.
|
|
226
216
|
const requestId = newRequestId();
|
|
@@ -237,6 +227,7 @@ export async function sendWithRetry(options) {
|
|
|
237
227
|
// attempts so each subsequent retry samples from a wider [base, prev*3] band.
|
|
238
228
|
// Initialize to baseDelayMs so the first retry samples [base, base*3].
|
|
239
229
|
let prevSleepMs = baseDelayMs;
|
|
230
|
+
const userAgent = buildUserAgent(options.clientName, options.clientVersion);
|
|
240
231
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
241
232
|
try {
|
|
242
233
|
// Node 18+ fetch accepts Buffer bodies, but under TS6 Buffer<ArrayBufferLike>
|
|
@@ -249,11 +240,11 @@ export async function sendWithRetry(options) {
|
|
|
249
240
|
'Api-Key': licenseKey,
|
|
250
241
|
'Content-Type': 'application/json',
|
|
251
242
|
'Content-Encoding': 'gzip',
|
|
252
|
-
'User-Agent':
|
|
243
|
+
'User-Agent': userAgent,
|
|
253
244
|
},
|
|
254
245
|
body: fetchBody,
|
|
255
246
|
signal: AbortSignal.timeout(requestTimeoutMs),
|
|
256
|
-
//
|
|
247
|
+
// `keepalive: true` is a no-op in Node fetch (undici), but
|
|
257
248
|
// safe to set. It exists for the case where this library is consumed
|
|
258
249
|
// in a runtime that *does* honor it (Cloudflare Workers, Deno, browser
|
|
259
250
|
// bundlers): the final shutdown send issued from `HarvestScheduler.stop()`
|
|
@@ -263,12 +254,12 @@ export async function sendWithRetry(options) {
|
|
|
263
254
|
const status = response.status;
|
|
264
255
|
if (status >= 200 && status < 300) {
|
|
265
256
|
// Drain the body so undici returns the socket to the keep-alive pool
|
|
266
|
-
// rather than tearing down the connection
|
|
257
|
+
// rather than tearing down the connection.
|
|
267
258
|
await response.body?.cancel().catch(() => { });
|
|
268
259
|
return { success: true, statusCode: status, retryCount: attempt };
|
|
269
260
|
}
|
|
270
261
|
// Read the body for all failure paths: gives useful diagnostics for 5xx
|
|
271
|
-
// errors and releases the socket to the keep-alive pool
|
|
262
|
+
// errors and releases the socket to the keep-alive pool.
|
|
272
263
|
const responseBody = (await response.text().catch(() => '')).slice(0, 1024);
|
|
273
264
|
if (status === 400) {
|
|
274
265
|
logger.error('Bad request — dropping batch', {
|
|
@@ -321,7 +312,7 @@ export async function sendWithRetry(options) {
|
|
|
321
312
|
// Always carry the chosen wait forward so the next jitter window
|
|
322
313
|
// widens appropriately — omitting this on the Retry-After path caused
|
|
323
314
|
// the window to stall at [base, base*3] after every server-driven
|
|
324
|
-
// wait
|
|
315
|
+
// wait.
|
|
325
316
|
prevSleepMs = waitMs;
|
|
326
317
|
await delay(waitMs);
|
|
327
318
|
continue;
|
|
@@ -375,7 +366,7 @@ export async function sendWithRetry(options) {
|
|
|
375
366
|
}
|
|
376
367
|
// Should not reach here — every loop iteration returns or continues.
|
|
377
368
|
// A throw (not a silent failure return) makes a future loop-logic regression
|
|
378
|
-
// immediately visible rather than producing a confusing success:false result
|
|
369
|
+
// immediately visible rather than producing a confusing success:false result.
|
|
379
370
|
throw new Error('sendWithRetry: unreachable code — bug in retry loop logic');
|
|
380
371
|
}
|
|
381
372
|
//# sourceMappingURL=http-client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../../src/shared/transport/http-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../../src/shared/transport/http-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,14 +16,13 @@ export interface NrLogEntry {
|
|
|
16
16
|
* map, but the option is open if a future caller wants to deduplicate
|
|
17
17
|
* across-batch attributes.
|
|
18
18
|
*
|
|
19
|
-
* **⚠️ Standalone transport helper — no harvest-scheduler integration
|
|
19
|
+
* **⚠️ Standalone transport helper — no harvest-scheduler integration.**
|
|
20
20
|
* Unlike `sendEvents` and `sendMetrics`, this function is NOT wired into
|
|
21
21
|
* `HarvestScheduler`. It has no in-memory buffer, no overflow protection, no
|
|
22
22
|
* retry-buffer cap, and no self-monitoring drop metrics. Call it directly only
|
|
23
23
|
* when you own the batching and retry logic yourself. For managed delivery
|
|
24
24
|
* analogous to event/metric harvest, a `NrLogEntry[]` buffer inside
|
|
25
|
-
* `HarvestScheduler` would be the right surface
|
|
26
|
-
*.
|
|
25
|
+
* `HarvestScheduler` would be the right surface.
|
|
27
26
|
*/
|
|
28
27
|
export declare function sendLogs(logs: NrLogEntry[], licenseKey: string, options: TransportOptions): Promise<TransportResult>;
|
|
29
28
|
//# sourceMappingURL=logs-api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs-api.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/logs-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGpE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CACxD;AAED
|
|
1
|
+
{"version":3,"file":"logs-api.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/logs-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGpE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CACxD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,UAAU,EAAE,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAmB1B"}
|
|
@@ -11,14 +11,13 @@ import { sendWithRetry, resolveRegion, getLogsApiUrl } from './http-client.js';
|
|
|
11
11
|
* map, but the option is open if a future caller wants to deduplicate
|
|
12
12
|
* across-batch attributes.
|
|
13
13
|
*
|
|
14
|
-
* **⚠️ Standalone transport helper — no harvest-scheduler integration
|
|
14
|
+
* **⚠️ Standalone transport helper — no harvest-scheduler integration.**
|
|
15
15
|
* Unlike `sendEvents` and `sendMetrics`, this function is NOT wired into
|
|
16
16
|
* `HarvestScheduler`. It has no in-memory buffer, no overflow protection, no
|
|
17
17
|
* retry-buffer cap, and no self-monitoring drop metrics. Call it directly only
|
|
18
18
|
* when you own the batching and retry logic yourself. For managed delivery
|
|
19
19
|
* analogous to event/metric harvest, a `NrLogEntry[]` buffer inside
|
|
20
|
-
* `HarvestScheduler` would be the right surface
|
|
21
|
-
*.
|
|
20
|
+
* `HarvestScheduler` would be the right surface.
|
|
22
21
|
*/
|
|
23
22
|
export async function sendLogs(logs, licenseKey, options) {
|
|
24
23
|
if (logs.length === 0) {
|
|
@@ -35,6 +34,7 @@ export async function sendLogs(logs, licenseKey, options) {
|
|
|
35
34
|
maxDelayMs: options.maxDelayMs ?? 30_000,
|
|
36
35
|
requestTimeoutMs: options.requestTimeoutMs ?? 30_000,
|
|
37
36
|
clientName: options.clientName,
|
|
37
|
+
clientVersion: options.clientVersion,
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
//# sourceMappingURL=logs-api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs-api.js","sourceRoot":"","sources":["../../../src/shared/transport/logs-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAQ/E
|
|
1
|
+
{"version":3,"file":"logs-api.js","sourceRoot":"","sources":["../../../src/shared/transport/logs-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAQ/E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAkB,EAClB,UAAkB,EAClB,OAAyB;IAEzB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC5D,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IAEjE,OAAO,aAAa,CAAC;QACnB,GAAG;QACH,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;QAChB,UAAU;QACV,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC;QACnC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;QACxC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,MAAM;QACxC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,MAAM;QACpD,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;KACrC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metric-api.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/metric-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAsB9E;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,QAAQ,EAAE,EACnB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"metric-api.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/metric-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAsB9E;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,QAAQ,EAAE,EACnB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAwB1B"}
|
|
@@ -34,6 +34,7 @@ export async function sendMetrics(metrics, licenseKey, options) {
|
|
|
34
34
|
maxDelayMs: options.maxDelayMs ?? 30_000,
|
|
35
35
|
requestTimeoutMs: options.requestTimeoutMs ?? 30_000,
|
|
36
36
|
clientName: options.clientName,
|
|
37
|
+
clientVersion: options.clientVersion,
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
//# sourceMappingURL=metric-api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metric-api.js","sourceRoot":"","sources":["../../../src/shared/transport/metric-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAUjF,SAAS,YAAY,CAAC,CAAW;IAC/B,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAC/B,2EAA2E;QAC3E,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,CAAuC,CAAC;QAC/E,KAAK,KAAK,CAAC;QACX,OAAO,IAAkB,CAAC;IAC5B,CAAC;IACD,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,GAAG,CAAsC,CAAC;IACvE,OAAO,EAAE,GAAI,IAAqC,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;AAClF,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAmB,EACnB,UAAkB,EAClB,OAAyB;IAEzB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC5D,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IAEnE,0EAA0E;IAC1E,2EAA2E;IAC3E,uBAAuB;IACvB,MAAM,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAEzD,OAAO,aAAa,CAAC;QACnB,GAAG;QACH,IAAI,EAAE,OAAO;QACb,UAAU;QACV,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC;QACnC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;QACxC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,MAAM;QACxC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,MAAM;QACpD,UAAU,EAAE,OAAO,CAAC,UAAU;
|
|
1
|
+
{"version":3,"file":"metric-api.js","sourceRoot":"","sources":["../../../src/shared/transport/metric-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAUjF,SAAS,YAAY,CAAC,CAAW;IAC/B,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAC/B,2EAA2E;QAC3E,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,CAAuC,CAAC;QAC/E,KAAK,KAAK,CAAC;QACX,OAAO,IAAkB,CAAC;IAC5B,CAAC;IACD,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,GAAG,CAAsC,CAAC;IACvE,OAAO,EAAE,GAAI,IAAqC,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;AAClF,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAmB,EACnB,UAAkB,EAClB,OAAyB;IAEzB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC5D,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IAEnE,0EAA0E;IAC1E,2EAA2E;IAC3E,uBAAuB;IACvB,MAAM,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAEzD,OAAO,aAAa,CAAC;QACnB,GAAG;QACH,IAAI,EAAE,OAAO;QACb,UAAU;QACV,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC;QACnC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;QACxC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,MAAM;QACxC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,MAAM;QACpD,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;KACrC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import type { NrEventData } from '../events/types.js';
|
|
2
2
|
export interface OtlpEventBridgeOptions {
|
|
3
|
-
endpoint: string;
|
|
4
|
-
headers?: Record<string, string>;
|
|
5
|
-
appName: string;
|
|
3
|
+
readonly endpoint: string;
|
|
4
|
+
readonly headers?: Record<string, string>;
|
|
5
|
+
readonly appName: string;
|
|
6
6
|
/**
|
|
7
7
|
* OTel logger name used to identify the source of log records emitted by
|
|
8
8
|
* this bridge. Defaults to `'ai-telemetry'` when not provided. Pass
|
|
9
|
-
* `'preflight'`, `'
|
|
9
|
+
* `'preflight'`, `'nr-ai-agent'`, etc. so telemetry from different
|
|
10
10
|
* consumers is distinguishable in the NR Logs UI.
|
|
11
11
|
*/
|
|
12
|
-
clientName?: string;
|
|
12
|
+
readonly clientName?: string;
|
|
13
|
+
/** Version of the consuming client, stamped as the OTel instrumentation scope version. */
|
|
14
|
+
readonly clientVersion?: string;
|
|
13
15
|
}
|
|
14
16
|
export declare class OtlpEventBridge {
|
|
15
17
|
private readonly loggerProvider;
|
|
16
18
|
private readonly otelLogger;
|
|
19
|
+
private readonly hasAuth;
|
|
20
|
+
private readonly endpoint;
|
|
21
|
+
private hasWarnedNoAuth;
|
|
17
22
|
constructor(options: OtlpEventBridgeOptions);
|
|
18
23
|
sendEvents(events: NrEventData[]): void;
|
|
19
24
|
flush(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otlp-event-bridge.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/otlp-event-bridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"otlp-event-bridge.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/otlp-event-bridge.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAYtD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,0FAA0F;IAC1F,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;IACrE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,eAAe,CAAS;gBAEpB,OAAO,EAAE,sBAAsB;IAyB3C,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI;IAyBjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
|
|
@@ -2,31 +2,40 @@ import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
|
|
|
2
2
|
import { LoggerProvider, BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
|
|
3
3
|
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
4
4
|
import { createLogger } from '../logger.js';
|
|
5
|
-
import { validateOtlpEndpoint, hasOtlpAuthHeader, DEFAULT_CLIENT_NAME } from './otlp-shared.js';
|
|
5
|
+
import { validateOtlpEndpoint, hasOtlpAuthHeader, DEFAULT_CLIENT_NAME, buildUserAgent, sanitizeClientString, } from './otlp-shared.js';
|
|
6
6
|
const logger = createLogger('otlp-event-bridge');
|
|
7
7
|
export class OtlpEventBridge {
|
|
8
8
|
loggerProvider;
|
|
9
9
|
otelLogger;
|
|
10
|
+
hasAuth;
|
|
11
|
+
endpoint;
|
|
12
|
+
hasWarnedNoAuth = false;
|
|
10
13
|
constructor(options) {
|
|
11
14
|
validateOtlpEndpoint(options.endpoint, 'OtlpEventBridge');
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
endpoint: options.endpoint,
|
|
17
|
-
});
|
|
18
|
-
}
|
|
15
|
+
const clientName = sanitizeClientString(options.clientName, DEFAULT_CLIENT_NAME);
|
|
16
|
+
const clientVersion = sanitizeClientString(options.clientVersion, '');
|
|
17
|
+
this.endpoint = options.endpoint;
|
|
18
|
+
this.hasAuth = hasOtlpAuthHeader(options.headers ?? {});
|
|
19
19
|
const exporter = new OTLPLogExporter({
|
|
20
20
|
url: `${options.endpoint}/v1/logs`,
|
|
21
|
-
headers:
|
|
21
|
+
headers: {
|
|
22
|
+
...(options.headers ?? {}),
|
|
23
|
+
'User-Agent': buildUserAgent(clientName, clientVersion),
|
|
24
|
+
},
|
|
22
25
|
});
|
|
23
26
|
this.loggerProvider = new LoggerProvider({
|
|
24
27
|
resource: resourceFromAttributes({ 'service.name': options.appName }),
|
|
25
28
|
processors: [new BatchLogRecordProcessor(exporter)],
|
|
26
29
|
});
|
|
27
|
-
this.otelLogger = this.loggerProvider.getLogger(
|
|
30
|
+
this.otelLogger = this.loggerProvider.getLogger(clientName, clientVersion || undefined);
|
|
28
31
|
}
|
|
29
32
|
sendEvents(events) {
|
|
33
|
+
if (!this.hasAuth && !this.hasWarnedNoAuth) {
|
|
34
|
+
this.hasWarnedNoAuth = true;
|
|
35
|
+
logger.warn('OtlpEventBridge sending events with no auth header — collector may reject', {
|
|
36
|
+
endpoint: this.endpoint,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
30
39
|
for (const event of events) {
|
|
31
40
|
this.otelLogger.emit({
|
|
32
41
|
severityText: 'INFO',
|
|
@@ -34,7 +43,7 @@ export class OtlpEventBridge {
|
|
|
34
43
|
// Filter to scalar values only — the OTel SDK's AnyValue type also
|
|
35
44
|
// accepts arrays/objects/null, and a non-scalar value would produce a
|
|
36
45
|
// malformed log record. NrEventData is typed as all-scalar but callers
|
|
37
|
-
// may pass unexpected shapes
|
|
46
|
+
// may pass unexpected shapes.
|
|
38
47
|
attributes: Object.fromEntries(Object.entries(event).filter(([, v]) => typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean')),
|
|
39
48
|
timestamp: typeof event.timestamp === 'number' ? event.timestamp : Date.now(),
|
|
40
49
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otlp-event-bridge.js","sourceRoot":"","sources":["../../../src/shared/transport/otlp-event-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"otlp-event-bridge.js","sourceRoot":"","sources":["../../../src/shared/transport/otlp-event-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,10 +4,21 @@
|
|
|
4
4
|
* import this constant rather than repeating the literal.
|
|
5
5
|
*/
|
|
6
6
|
export declare const DEFAULT_CLIENT_NAME = "ai-telemetry";
|
|
7
|
+
/**
|
|
8
|
+
* Strip HTTP header-injection characters and surrounding whitespace from a
|
|
9
|
+
* client name or version string. Falls back to `fallback` when the input is
|
|
10
|
+
* absent or reduces to an empty string after sanitization.
|
|
11
|
+
*/
|
|
12
|
+
export declare function sanitizeClientString(s: string | undefined, fallback: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Builds the `User-Agent` header value for outbound NR ingest requests.
|
|
15
|
+
* Returns `name/version` when version is non-empty, `name` alone otherwise.
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildUserAgent(clientName: string | undefined, clientVersion: string | undefined): string;
|
|
7
18
|
/**
|
|
8
19
|
* Returns true when `headers` contains at least one recognised auth header
|
|
9
20
|
* (`api-key`, `authorization`, or `x-license-key`). Shared by OtlpTransport
|
|
10
|
-
* and OtlpEventBridge so both warn when no auth header is present
|
|
21
|
+
* and OtlpEventBridge so both warn when no auth header is present.
|
|
11
22
|
*/
|
|
12
23
|
export declare function hasOtlpAuthHeader(headers: Record<string, string>): boolean;
|
|
13
24
|
export declare function validateOtlpEndpoint(endpoint: string, source: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otlp-shared.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/otlp-shared.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAM1E;AAOD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAsB3E"}
|
|
1
|
+
{"version":3,"file":"otlp-shared.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/otlp-shared.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,MAAM,CAGR;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAM1E;AAOD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAsB3E"}
|
|
@@ -6,10 +6,26 @@ const logger = createLogger('otlp-shared');
|
|
|
6
6
|
* import this constant rather than repeating the literal.
|
|
7
7
|
*/
|
|
8
8
|
export const DEFAULT_CLIENT_NAME = 'ai-telemetry';
|
|
9
|
+
/**
|
|
10
|
+
* Strip HTTP header-injection characters and surrounding whitespace from a
|
|
11
|
+
* client name or version string. Falls back to `fallback` when the input is
|
|
12
|
+
* absent or reduces to an empty string after sanitization.
|
|
13
|
+
*/
|
|
14
|
+
export function sanitizeClientString(s, fallback) {
|
|
15
|
+
return (s ?? fallback).replace(/[\r\n\x00-\x1f]/g, '').trim() || fallback;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Builds the `User-Agent` header value for outbound NR ingest requests.
|
|
19
|
+
* Returns `name/version` when version is non-empty, `name` alone otherwise.
|
|
20
|
+
*/
|
|
21
|
+
export function buildUserAgent(clientName, clientVersion) {
|
|
22
|
+
const name = clientName || DEFAULT_CLIENT_NAME;
|
|
23
|
+
return clientVersion ? `${name}/${clientVersion}` : name;
|
|
24
|
+
}
|
|
9
25
|
/**
|
|
10
26
|
* Returns true when `headers` contains at least one recognised auth header
|
|
11
27
|
* (`api-key`, `authorization`, or `x-license-key`). Shared by OtlpTransport
|
|
12
|
-
* and OtlpEventBridge so both warn when no auth header is present
|
|
28
|
+
* and OtlpEventBridge so both warn when no auth header is present.
|
|
13
29
|
*/
|
|
14
30
|
export function hasOtlpAuthHeader(headers) {
|
|
15
31
|
for (const key of Object.keys(headers)) {
|
|
@@ -19,11 +35,11 @@ export function hasOtlpAuthHeader(headers) {
|
|
|
19
35
|
}
|
|
20
36
|
return false;
|
|
21
37
|
}
|
|
22
|
-
//
|
|
38
|
+
// Validate OTLP endpoint scheme. https:// is required for
|
|
23
39
|
// any non-localhost destination because the payload may contain user prompt
|
|
24
40
|
// fragments (PII). Plain http:// is allowed only against loopback to support
|
|
25
41
|
// local development and testing. Shared by OtlpTransport and OtlpEventBridge
|
|
26
|
-
// (
|
|
42
|
+
// (deduplicates previously identical implementations).
|
|
27
43
|
export function validateOtlpEndpoint(endpoint, source) {
|
|
28
44
|
let parsed;
|
|
29
45
|
try {
|
|
@@ -40,7 +56,7 @@ export function validateOtlpEndpoint(endpoint, source) {
|
|
|
40
56
|
// http://: only acceptable on loopback
|
|
41
57
|
const host = parsed.hostname;
|
|
42
58
|
// 0.0.0.0 is a wildcard that binds to ALL interfaces, not loopback only —
|
|
43
|
-
// cleartext traffic to it is reachable from any network
|
|
59
|
+
// cleartext traffic to it is reachable from any network.
|
|
44
60
|
const isLoopback = host === 'localhost' || host === '127.0.0.1' || host === '::1';
|
|
45
61
|
if (!isLoopback) {
|
|
46
62
|
logger.warn(`${source}: OTLP endpoint uses plain http:// to a non-loopback host — payload may contain PII and should not be transmitted in cleartext`, { endpoint });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otlp-shared.js","sourceRoot":"","sources":["../../../src/shared/transport/otlp-shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;AAE3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAElD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAA+B;IAC/D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,MAAM,EAAE,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAC7B,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,eAAe,IAAI,EAAE,KAAK,eAAe;YAAE,OAAO,IAAI,CAAC;IACxF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0DAA0D;AAC1D,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,
|
|
1
|
+
{"version":3,"file":"otlp-shared.js","sourceRoot":"","sources":["../../../src/shared/transport/otlp-shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;AAE3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAElD;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,CAAqB,EAAE,QAAgB;IAC1E,OAAO,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,QAAQ,CAAC;AAC5E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,UAA8B,EAC9B,aAAiC;IAEjC,MAAM,IAAI,GAAG,UAAU,IAAI,mBAAmB,CAAC;IAC/C,OAAO,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAA+B;IAC/D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,MAAM,EAAE,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAC7B,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,eAAe,IAAI,EAAE,KAAK,eAAe;YAAE,OAAO,IAAI,CAAC;IACxF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0DAA0D;AAC1D,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,uDAAuD;AACvD,MAAM,UAAU,oBAAoB,CAAC,QAAgB,EAAE,MAAc;IACnE,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,gCAAgC,QAAQ,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO;IACzC,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,yCAAyC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,uCAAuC;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC7B,0EAA0E;IAC1E,yDAAyD;IACzD,MAAM,UAAU,GAAG,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,KAAK,CAAC;IAClF,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,CAAC,IAAI,CACT,GAAG,MAAM,gIAAgI,EACzI,EAAE,QAAQ,EAAE,CACb,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import type { NrMetric } from './types.js';
|
|
2
2
|
export interface OtlpTransportOptions {
|
|
3
|
-
endpoint: string;
|
|
4
|
-
headers?: Record<string, string>;
|
|
5
|
-
appName: string;
|
|
6
|
-
/** Override the default 30-second request timeout for exportMetrics
|
|
7
|
-
requestTimeoutMs?: number;
|
|
3
|
+
readonly endpoint: string;
|
|
4
|
+
readonly headers?: Record<string, string>;
|
|
5
|
+
readonly appName: string;
|
|
6
|
+
/** Override the default 30-second request timeout for exportMetrics. */
|
|
7
|
+
readonly requestTimeoutMs?: number;
|
|
8
8
|
/**
|
|
9
9
|
* Identifies the consuming client in the `User-Agent` header and as the
|
|
10
10
|
* OTel instrumentation scope name. Defaults to
|
|
11
|
-
* `'ai-telemetry'` when not provided. Pass `'preflight'`, `'
|
|
11
|
+
* `'ai-telemetry'` when not provided. Pass `'preflight'`, `'nr-ai-agent'`,
|
|
12
12
|
* etc. so telemetry from different consumers is distinguishable.
|
|
13
13
|
*/
|
|
14
|
-
clientName?: string;
|
|
14
|
+
readonly clientName?: string;
|
|
15
|
+
/** Version of the consuming client, stamped as the OTel instrumentation scope version. */
|
|
16
|
+
readonly clientVersion?: string;
|
|
15
17
|
}
|
|
16
18
|
export declare class OtlpTransport {
|
|
17
19
|
private readonly traceExporter;
|
|
@@ -21,24 +23,21 @@ export declare class OtlpTransport {
|
|
|
21
23
|
private readonly endpoint;
|
|
22
24
|
private readonly headers;
|
|
23
25
|
private readonly requestTimeoutMs;
|
|
24
|
-
private readonly
|
|
26
|
+
private readonly clientVersion;
|
|
27
|
+
private readonly userAgent;
|
|
28
|
+
private readonly hasAuth;
|
|
25
29
|
private hasWarnedNoAuth;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* Keeping a single resolved attribute map prevents `service.name` from
|
|
30
|
-
* drifting between the two paths — previously `this.appName` was stored
|
|
31
|
-
* separately and re-encoded into the OTLP envelope, which would silently
|
|
32
|
-
* diverge if anyone added a second resource attribute.
|
|
33
|
-
*/
|
|
34
|
-
private readonly resourceAttributes;
|
|
30
|
+
private readonly otlpResource;
|
|
31
|
+
private readonly otlpScope;
|
|
32
|
+
private readonly metricsHeaders;
|
|
35
33
|
constructor(options: OtlpTransportOptions);
|
|
36
34
|
flush(): Promise<void>;
|
|
37
35
|
shutdown(): Promise<void>;
|
|
36
|
+
private settledOrThrow;
|
|
38
37
|
/**
|
|
39
38
|
* Return an OTel `Tracer` for the given instrumentation name. The returned
|
|
40
|
-
* value is the `Tracer` interface from `@opentelemetry/api
|
|
41
|
-
|
|
39
|
+
* value is the `Tracer` interface from `@opentelemetry/api`;
|
|
40
|
+
* consumers that bind to the type explicitly should
|
|
42
41
|
* `import type { Tracer } from '@opentelemetry/api'`. `@opentelemetry/api`
|
|
43
42
|
* is already a regular dependency of this package, so no extra install is
|
|
44
43
|
* required. The type is intentionally NOT re-exported from this package's
|
|
@@ -54,5 +53,9 @@ export declare class OtlpTransport {
|
|
|
54
53
|
*/
|
|
55
54
|
getMeter(name: string): import("@opentelemetry/api").Meter;
|
|
56
55
|
exportMetrics(metrics: NrMetric[]): Promise<void>;
|
|
56
|
+
private otlpAttributes;
|
|
57
|
+
private numericDataPoint;
|
|
58
|
+
private summaryDataPoint;
|
|
59
|
+
private otlpMetric;
|
|
57
60
|
}
|
|
58
61
|
//# sourceMappingURL=otlp-transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otlp-transport.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/otlp-transport.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"otlp-transport.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/otlp-transport.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAiD,MAAM,YAAY,CAAC;AAa1F,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,0FAA0F;IAC1F,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAsB;IACrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiE;IAC9F,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuD;IACjF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAmC;gBAEtD,OAAO,EAAE,oBAAoB;IAuDnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAOjB,cAAc;IAS5B;;;;;;;;;;OAUG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM;IAItB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM;IAIf,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA8DvD,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,gBAAgB;IAyBxB,OAAO,CAAC,UAAU;CA0BnB"}
|