@newrelic/preflight 0.0.1-pre.1 → 1.0.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/LICENSE +183 -0
- package/README.md +498 -0
- package/dist/alerts/alert-log.d.ts +24 -0
- package/dist/alerts/alert-log.d.ts.map +1 -0
- package/dist/alerts/alert-log.js +159 -0
- package/dist/alerts/alert-log.js.map +1 -0
- package/dist/alerts/alert-snapshot-collector.d.ts +168 -0
- package/dist/alerts/alert-snapshot-collector.d.ts.map +1 -0
- package/dist/alerts/alert-snapshot-collector.js +243 -0
- package/dist/alerts/alert-snapshot-collector.js.map +1 -0
- package/dist/alerts/local-alert-engine.d.ts +86 -0
- package/dist/alerts/local-alert-engine.d.ts.map +1 -0
- package/dist/alerts/local-alert-engine.js +466 -0
- package/dist/alerts/local-alert-engine.js.map +1 -0
- package/dist/alerts/local-alert-rule.d.ts +439 -0
- package/dist/alerts/local-alert-rule.d.ts.map +1 -0
- package/dist/alerts/local-alert-rule.js +139 -0
- package/dist/alerts/local-alert-rule.js.map +1 -0
- package/dist/alerts/os-notifier.d.ts +39 -0
- package/dist/alerts/os-notifier.d.ts.map +1 -0
- package/dist/alerts/os-notifier.js +170 -0
- package/dist/alerts/os-notifier.js.map +1 -0
- package/dist/alerts/types.d.ts +35 -0
- package/dist/alerts/types.d.ts.map +1 -0
- package/dist/alerts/types.js +8 -0
- package/dist/alerts/types.js.map +1 -0
- package/dist/config.d.ts +169 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +860 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard/dashboard-server.d.ts +38 -0
- package/dist/dashboard/dashboard-server.d.ts.map +1 -0
- package/dist/dashboard/dashboard-server.js +207 -0
- package/dist/dashboard/dashboard-server.js.map +1 -0
- package/dist/dashboard/index.d.ts +3 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +2 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/live-event-bus.d.ts +99 -0
- package/dist/dashboard/live-event-bus.d.ts.map +1 -0
- package/dist/dashboard/live-event-bus.js +56 -0
- package/dist/dashboard/live-event-bus.js.map +1 -0
- package/dist/dashboard/routes/api-handler.d.ts +122 -0
- package/dist/dashboard/routes/api-handler.d.ts.map +1 -0
- package/dist/dashboard/routes/api-handler.js +1414 -0
- package/dist/dashboard/routes/api-handler.js.map +1 -0
- package/dist/dashboard/routes/replay-analyzer.d.ts +15 -0
- package/dist/dashboard/routes/replay-analyzer.d.ts.map +1 -0
- package/dist/dashboard/routes/replay-analyzer.js +227 -0
- package/dist/dashboard/routes/replay-analyzer.js.map +1 -0
- package/dist/dashboard/routes/sse-handler.d.ts +4 -0
- package/dist/dashboard/routes/sse-handler.d.ts.map +1 -0
- package/dist/dashboard/routes/sse-handler.js +122 -0
- package/dist/dashboard/routes/sse-handler.js.map +1 -0
- package/dist/dashboard/routes/static-handler.d.ts +3 -0
- package/dist/dashboard/routes/static-handler.d.ts.map +1 -0
- package/dist/dashboard/routes/static-handler.js +103 -0
- package/dist/dashboard/routes/static-handler.js.map +1 -0
- package/dist/data/alerts/conditions/01-daily-cost-spike.json +16 -0
- package/dist/data/alerts/conditions/02-low-efficiency-score.json +16 -0
- package/dist/data/alerts/conditions/03-stuck-loop-rate.json +16 -0
- package/dist/data/alerts/conditions/04-anti-pattern-rate.json +16 -0
- package/dist/data/alerts/conditions/05-session-cost-budget.json +16 -0
- package/dist/data/alerts/conditions-personal/01-personal-daily-cost.json +16 -0
- package/dist/data/alerts/conditions-personal/02-personal-session-cost.json +16 -0
- package/dist/data/alerts/conditions-personal/03-personal-low-efficiency.json +16 -0
- package/dist/data/alerts/conditions-personal/04-personal-anti-pattern-rate.json +16 -0
- package/dist/data/alerts/conditions-personal/05-personal-stuck-loop.json +16 -0
- package/dist/data/alerts/policy.json +4 -0
- package/dist/data/dashboards/ai-coding-assistant-manager-view.json +103 -0
- package/dist/data/dashboards/ai-coding-assistant-overview.json +239 -0
- package/dist/data/dashboards/ai-coding-assistant-personal.json +442 -0
- package/dist/data/dashboards/ai-coding-assistant-platform-comparison.json +320 -0
- package/dist/data/dashboards/ai-coding-assistant-security.json +275 -0
- package/dist/data/dashboards/ai-coding-assistant-session-detail.json +296 -0
- package/dist/data/dashboards/ai-coding-assistant-team-view.json +345 -0
- package/dist/deploy/data-paths.d.ts +22 -0
- package/dist/deploy/data-paths.d.ts.map +1 -0
- package/dist/deploy/data-paths.js +69 -0
- package/dist/deploy/data-paths.js.map +1 -0
- package/dist/deploy/deploy-alerts.d.ts +58 -0
- package/dist/deploy/deploy-alerts.d.ts.map +1 -0
- package/dist/deploy/deploy-alerts.js +371 -0
- package/dist/deploy/deploy-alerts.js.map +1 -0
- package/dist/deploy/deploy-dashboards.d.ts +92 -0
- package/dist/deploy/deploy-dashboards.d.ts.map +1 -0
- package/dist/deploy/deploy-dashboards.js +282 -0
- package/dist/deploy/deploy-dashboards.js.map +1 -0
- package/dist/digest/digest-formatter.d.ts +3 -0
- package/dist/digest/digest-formatter.d.ts.map +1 -0
- package/dist/digest/digest-formatter.js +37 -0
- package/dist/digest/digest-formatter.js.map +1 -0
- package/dist/digest/digest-sender.d.ts +2 -0
- package/dist/digest/digest-sender.d.ts.map +1 -0
- package/dist/digest/digest-sender.js +29 -0
- package/dist/digest/digest-sender.js.map +1 -0
- package/dist/hooks/bash-classifier.d.ts +26 -0
- package/dist/hooks/bash-classifier.d.ts.map +1 -0
- package/dist/hooks/bash-classifier.js +409 -0
- package/dist/hooks/bash-classifier.js.map +1 -0
- package/dist/hooks/collector-script.d.ts +47 -0
- package/dist/hooks/collector-script.d.ts.map +1 -0
- package/dist/hooks/collector-script.js +662 -0
- package/dist/hooks/collector-script.js.map +1 -0
- package/dist/hooks/event-processor.d.ts +65 -0
- package/dist/hooks/event-processor.d.ts.map +1 -0
- package/dist/hooks/event-processor.js +342 -0
- package/dist/hooks/event-processor.js.map +1 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +5 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/session-resolver.d.ts +66 -0
- package/dist/hooks/session-resolver.d.ts.map +1 -0
- package/dist/hooks/session-resolver.js +196 -0
- package/dist/hooks/session-resolver.js.map +1 -0
- package/dist/hooks/tool-parsers.d.ts +19 -0
- package/dist/hooks/tool-parsers.d.ts.map +1 -0
- package/dist/hooks/tool-parsers.js +260 -0
- package/dist/hooks/tool-parsers.js.map +1 -0
- package/dist/index.d.ts +107 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1505 -0
- package/dist/index.js.map +1 -0
- package/dist/install/cli.d.ts +11 -0
- package/dist/install/cli.d.ts.map +1 -0
- package/dist/install/cli.js +365 -0
- package/dist/install/cli.js.map +1 -0
- package/dist/install/index.d.ts +4 -0
- package/dist/install/index.d.ts.map +1 -0
- package/dist/install/index.js +3 -0
- package/dist/install/index.js.map +1 -0
- package/dist/install/install-helper.d.ts +35 -0
- package/dist/install/install-helper.d.ts.map +1 -0
- package/dist/install/install-helper.js +227 -0
- package/dist/install/install-helper.js.map +1 -0
- package/dist/install/key-validator.d.ts +19 -0
- package/dist/install/key-validator.d.ts.map +1 -0
- package/dist/install/key-validator.js +122 -0
- package/dist/install/key-validator.js.map +1 -0
- package/dist/install/migrate.d.ts +12 -0
- package/dist/install/migrate.d.ts.map +1 -0
- package/dist/install/migrate.js +115 -0
- package/dist/install/migrate.js.map +1 -0
- package/dist/install/schedule.d.ts +11 -0
- package/dist/install/schedule.d.ts.map +1 -0
- package/dist/install/schedule.js +114 -0
- package/dist/install/schedule.js.map +1 -0
- package/dist/install/setup-wizard.d.ts +40 -0
- package/dist/install/setup-wizard.d.ts.map +1 -0
- package/dist/install/setup-wizard.js +489 -0
- package/dist/install/setup-wizard.js.map +1 -0
- package/dist/lib/date.d.ts +54 -0
- package/dist/lib/date.d.ts.map +1 -0
- package/dist/lib/date.js +85 -0
- package/dist/lib/date.js.map +1 -0
- package/dist/metrics/anti-patterns.d.ts +62 -0
- package/dist/metrics/anti-patterns.d.ts.map +1 -0
- package/dist/metrics/anti-patterns.js +301 -0
- package/dist/metrics/anti-patterns.js.map +1 -0
- package/dist/metrics/api-failure-tracker.d.ts +82 -0
- package/dist/metrics/api-failure-tracker.d.ts.map +1 -0
- package/dist/metrics/api-failure-tracker.js +202 -0
- package/dist/metrics/api-failure-tracker.js.map +1 -0
- package/dist/metrics/budget-tracker.d.ts +60 -0
- package/dist/metrics/budget-tracker.d.ts.map +1 -0
- package/dist/metrics/budget-tracker.js +130 -0
- package/dist/metrics/budget-tracker.js.map +1 -0
- package/dist/metrics/claudemd-tracker.d.ts +108 -0
- package/dist/metrics/claudemd-tracker.d.ts.map +1 -0
- package/dist/metrics/claudemd-tracker.js +337 -0
- package/dist/metrics/claudemd-tracker.js.map +1 -0
- package/dist/metrics/collaboration-profile.d.ts +65 -0
- package/dist/metrics/collaboration-profile.d.ts.map +1 -0
- package/dist/metrics/collaboration-profile.js +231 -0
- package/dist/metrics/collaboration-profile.js.map +1 -0
- package/dist/metrics/context-composition-tracker.d.ts +74 -0
- package/dist/metrics/context-composition-tracker.d.ts.map +1 -0
- package/dist/metrics/context-composition-tracker.js +202 -0
- package/dist/metrics/context-composition-tracker.js.map +1 -0
- package/dist/metrics/context-tracker.d.ts +78 -0
- package/dist/metrics/context-tracker.d.ts.map +1 -0
- package/dist/metrics/context-tracker.js +222 -0
- package/dist/metrics/context-tracker.js.map +1 -0
- package/dist/metrics/context-window-tracker.d.ts +18 -0
- package/dist/metrics/context-window-tracker.d.ts.map +1 -0
- package/dist/metrics/context-window-tracker.js +35 -0
- package/dist/metrics/context-window-tracker.js.map +1 -0
- package/dist/metrics/cost-forecast.d.ts +36 -0
- package/dist/metrics/cost-forecast.d.ts.map +1 -0
- package/dist/metrics/cost-forecast.js +91 -0
- package/dist/metrics/cost-forecast.js.map +1 -0
- package/dist/metrics/cost-per-outcome.d.ts +102 -0
- package/dist/metrics/cost-per-outcome.d.ts.map +1 -0
- package/dist/metrics/cost-per-outcome.js +266 -0
- package/dist/metrics/cost-per-outcome.js.map +1 -0
- package/dist/metrics/cost-tracker.d.ts +78 -0
- package/dist/metrics/cost-tracker.d.ts.map +1 -0
- package/dist/metrics/cost-tracker.js +169 -0
- package/dist/metrics/cost-tracker.js.map +1 -0
- package/dist/metrics/decision-tracker.d.ts +49 -0
- package/dist/metrics/decision-tracker.d.ts.map +1 -0
- package/dist/metrics/decision-tracker.js +161 -0
- package/dist/metrics/decision-tracker.js.map +1 -0
- package/dist/metrics/efficiency-score.d.ts +80 -0
- package/dist/metrics/efficiency-score.d.ts.map +1 -0
- package/dist/metrics/efficiency-score.js +219 -0
- package/dist/metrics/efficiency-score.js.map +1 -0
- package/dist/metrics/git-efficiency-tracker.d.ts +165 -0
- package/dist/metrics/git-efficiency-tracker.d.ts.map +1 -0
- package/dist/metrics/git-efficiency-tracker.js +1056 -0
- package/dist/metrics/git-efficiency-tracker.js.map +1 -0
- package/dist/metrics/index.d.ts +26 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +14 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/instruction-drift-tracker.d.ts +69 -0
- package/dist/metrics/instruction-drift-tracker.d.ts.map +1 -0
- package/dist/metrics/instruction-drift-tracker.js +213 -0
- package/dist/metrics/instruction-drift-tracker.js.map +1 -0
- package/dist/metrics/latency-decomposition.d.ts +50 -0
- package/dist/metrics/latency-decomposition.d.ts.map +1 -0
- package/dist/metrics/latency-decomposition.js +112 -0
- package/dist/metrics/latency-decomposition.js.map +1 -0
- package/dist/metrics/latency-tracker.d.ts +33 -0
- package/dist/metrics/latency-tracker.d.ts.map +1 -0
- package/dist/metrics/latency-tracker.js +93 -0
- package/dist/metrics/latency-tracker.js.map +1 -0
- package/dist/metrics/live-session-registry.d.ts +29 -0
- package/dist/metrics/live-session-registry.d.ts.map +1 -0
- package/dist/metrics/live-session-registry.js +103 -0
- package/dist/metrics/live-session-registry.js.map +1 -0
- package/dist/metrics/model-usage-tracker.d.ts +21 -0
- package/dist/metrics/model-usage-tracker.d.ts.map +1 -0
- package/dist/metrics/model-usage-tracker.js +53 -0
- package/dist/metrics/model-usage-tracker.js.map +1 -0
- package/dist/metrics/percentile.d.ts +5 -0
- package/dist/metrics/percentile.d.ts.map +1 -0
- package/dist/metrics/percentile.js +10 -0
- package/dist/metrics/percentile.js.map +1 -0
- package/dist/metrics/personal-coach.d.ts +47 -0
- package/dist/metrics/personal-coach.d.ts.map +1 -0
- package/dist/metrics/personal-coach.js +241 -0
- package/dist/metrics/personal-coach.js.map +1 -0
- package/dist/metrics/prompt-feedback.d.ts +75 -0
- package/dist/metrics/prompt-feedback.d.ts.map +1 -0
- package/dist/metrics/prompt-feedback.js +286 -0
- package/dist/metrics/prompt-feedback.js.map +1 -0
- package/dist/metrics/proxy-metrics.d.ts +54 -0
- package/dist/metrics/proxy-metrics.d.ts.map +1 -0
- package/dist/metrics/proxy-metrics.js +228 -0
- package/dist/metrics/proxy-metrics.js.map +1 -0
- package/dist/metrics/quality-proxy-tracker.d.ts +51 -0
- package/dist/metrics/quality-proxy-tracker.d.ts.map +1 -0
- package/dist/metrics/quality-proxy-tracker.js +162 -0
- package/dist/metrics/quality-proxy-tracker.js.map +1 -0
- package/dist/metrics/recommendation-engine.d.ts +72 -0
- package/dist/metrics/recommendation-engine.d.ts.map +1 -0
- package/dist/metrics/recommendation-engine.js +207 -0
- package/dist/metrics/recommendation-engine.js.map +1 -0
- package/dist/metrics/retry-detector.d.ts +43 -0
- package/dist/metrics/retry-detector.d.ts.map +1 -0
- package/dist/metrics/retry-detector.js +179 -0
- package/dist/metrics/retry-detector.js.map +1 -0
- package/dist/metrics/session-tracker.d.ts +75 -0
- package/dist/metrics/session-tracker.d.ts.map +1 -0
- package/dist/metrics/session-tracker.js +249 -0
- package/dist/metrics/session-tracker.js.map +1 -0
- package/dist/metrics/task-completion-tracker.d.ts +15 -0
- package/dist/metrics/task-completion-tracker.d.ts.map +1 -0
- package/dist/metrics/task-completion-tracker.js +27 -0
- package/dist/metrics/task-completion-tracker.js.map +1 -0
- package/dist/metrics/task-detector.d.ts +84 -0
- package/dist/metrics/task-detector.d.ts.map +1 -0
- package/dist/metrics/task-detector.js +302 -0
- package/dist/metrics/task-detector.js.map +1 -0
- package/dist/metrics/tool-selection-scorer.d.ts +39 -0
- package/dist/metrics/tool-selection-scorer.d.ts.map +1 -0
- package/dist/metrics/tool-selection-scorer.js +193 -0
- package/dist/metrics/tool-selection-scorer.js.map +1 -0
- package/dist/metrics/trend-analyzer.d.ts +92 -0
- package/dist/metrics/trend-analyzer.d.ts.map +1 -0
- package/dist/metrics/trend-analyzer.js +293 -0
- package/dist/metrics/trend-analyzer.js.map +1 -0
- package/dist/metrics/turn-cost-attributor.d.ts +41 -0
- package/dist/metrics/turn-cost-attributor.d.ts.map +1 -0
- package/dist/metrics/turn-cost-attributor.js +118 -0
- package/dist/metrics/turn-cost-attributor.js.map +1 -0
- package/dist/metrics/turn-tracker.d.ts +49 -0
- package/dist/metrics/turn-tracker.d.ts.map +1 -0
- package/dist/metrics/turn-tracker.js +192 -0
- package/dist/metrics/turn-tracker.js.map +1 -0
- package/dist/platforms/amazon-q-adapter.d.ts +10 -0
- package/dist/platforms/amazon-q-adapter.d.ts.map +1 -0
- package/dist/platforms/amazon-q-adapter.js +75 -0
- package/dist/platforms/amazon-q-adapter.js.map +1 -0
- package/dist/platforms/claude-code-adapter.d.ts +10 -0
- package/dist/platforms/claude-code-adapter.d.ts.map +1 -0
- package/dist/platforms/claude-code-adapter.js +48 -0
- package/dist/platforms/claude-code-adapter.js.map +1 -0
- package/dist/platforms/continue-adapter.d.ts +10 -0
- package/dist/platforms/continue-adapter.d.ts.map +1 -0
- package/dist/platforms/continue-adapter.js +73 -0
- package/dist/platforms/continue-adapter.js.map +1 -0
- package/dist/platforms/copilot-adapter.d.ts +37 -0
- package/dist/platforms/copilot-adapter.d.ts.map +1 -0
- package/dist/platforms/copilot-adapter.js +66 -0
- package/dist/platforms/copilot-adapter.js.map +1 -0
- package/dist/platforms/cursor-adapter.d.ts +10 -0
- package/dist/platforms/cursor-adapter.d.ts.map +1 -0
- package/dist/platforms/cursor-adapter.js +60 -0
- package/dist/platforms/cursor-adapter.js.map +1 -0
- package/dist/platforms/generic-mcp-adapter.d.ts +113 -0
- package/dist/platforms/generic-mcp-adapter.d.ts.map +1 -0
- package/dist/platforms/generic-mcp-adapter.js +139 -0
- package/dist/platforms/generic-mcp-adapter.js.map +1 -0
- package/dist/platforms/index.d.ts +15 -0
- package/dist/platforms/index.d.ts.map +1 -0
- package/dist/platforms/index.js +12 -0
- package/dist/platforms/index.js.map +1 -0
- package/dist/platforms/platform-registry.d.ts +11 -0
- package/dist/platforms/platform-registry.d.ts.map +1 -0
- package/dist/platforms/platform-registry.js +54 -0
- package/dist/platforms/platform-registry.js.map +1 -0
- package/dist/platforms/types.d.ts +36 -0
- package/dist/platforms/types.d.ts.map +1 -0
- package/dist/platforms/types.js +2 -0
- package/dist/platforms/types.js.map +1 -0
- package/dist/platforms/windsurf-adapter.d.ts +10 -0
- package/dist/platforms/windsurf-adapter.d.ts.map +1 -0
- package/dist/platforms/windsurf-adapter.js +63 -0
- package/dist/platforms/windsurf-adapter.js.map +1 -0
- package/dist/platforms/zed-adapter.d.ts +10 -0
- package/dist/platforms/zed-adapter.d.ts.map +1 -0
- package/dist/platforms/zed-adapter.js +72 -0
- package/dist/platforms/zed-adapter.js.map +1 -0
- package/dist/proxy/index.d.ts +7 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/index.js +5 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/proxy/otlp-receiver.d.ts +28 -0
- package/dist/proxy/otlp-receiver.d.ts.map +1 -0
- package/dist/proxy/otlp-receiver.js +319 -0
- package/dist/proxy/otlp-receiver.js.map +1 -0
- package/dist/proxy/proxy-manager.d.ts +47 -0
- package/dist/proxy/proxy-manager.d.ts.map +1 -0
- package/dist/proxy/proxy-manager.js +338 -0
- package/dist/proxy/proxy-manager.js.map +1 -0
- package/dist/proxy/types.d.ts +72 -0
- package/dist/proxy/types.d.ts.map +1 -0
- package/dist/proxy/types.js +33 -0
- package/dist/proxy/types.js.map +1 -0
- package/dist/proxy/upstream-http.d.ts +26 -0
- package/dist/proxy/upstream-http.d.ts.map +1 -0
- package/dist/proxy/upstream-http.js +209 -0
- package/dist/proxy/upstream-http.js.map +1 -0
- package/dist/proxy/upstream-stdio.d.ts +25 -0
- package/dist/proxy/upstream-stdio.d.ts.map +1 -0
- package/dist/proxy/upstream-stdio.js +256 -0
- package/dist/proxy/upstream-stdio.js.map +1 -0
- package/dist/security/audit-trail.d.ts +74 -0
- package/dist/security/audit-trail.d.ts.map +1 -0
- package/dist/security/audit-trail.js +338 -0
- package/dist/security/audit-trail.js.map +1 -0
- package/dist/security/index.d.ts +5 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +4 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/ssrf.d.ts +2 -0
- package/dist/security/ssrf.d.ts.map +1 -0
- package/dist/security/ssrf.js +126 -0
- package/dist/security/ssrf.js.map +1 -0
- package/dist/server.d.ts +14 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +117 -0
- package/dist/server.js.map +1 -0
- package/dist/shared/__test-utils__/log-output.d.ts +49 -0
- package/dist/shared/__test-utils__/log-output.d.ts.map +1 -0
- package/dist/shared/__test-utils__/log-output.js +38 -0
- package/dist/shared/__test-utils__/log-output.js.map +1 -0
- package/dist/shared/config.d.ts +56 -0
- package/dist/shared/config.d.ts.map +1 -0
- package/dist/shared/config.js +290 -0
- package/dist/shared/config.js.map +1 -0
- package/dist/shared/errors.d.ts +139 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/errors.js +406 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/events/factory.d.ts +143 -0
- package/dist/shared/events/factory.d.ts.map +1 -0
- package/dist/shared/events/factory.js +351 -0
- package/dist/shared/events/factory.js.map +1 -0
- package/dist/shared/events/index.d.ts +6 -0
- package/dist/shared/events/index.d.ts.map +1 -0
- package/dist/shared/events/index.js +3 -0
- package/dist/shared/events/index.js.map +1 -0
- package/dist/shared/events/serialize.d.ts +87 -0
- package/dist/shared/events/serialize.d.ts.map +1 -0
- package/dist/shared/events/serialize.js +510 -0
- package/dist/shared/events/serialize.js.map +1 -0
- package/dist/shared/events/types.d.ts +139 -0
- package/dist/shared/events/types.d.ts.map +1 -0
- package/dist/shared/events/types.js +2 -0
- package/dist/shared/events/types.js.map +1 -0
- package/dist/shared/harvest/event-buffer.d.ts +59 -0
- package/dist/shared/harvest/event-buffer.d.ts.map +1 -0
- package/dist/shared/harvest/event-buffer.js +100 -0
- package/dist/shared/harvest/event-buffer.js.map +1 -0
- package/dist/shared/harvest/harvest-scheduler.d.ts +200 -0
- package/dist/shared/harvest/harvest-scheduler.d.ts.map +1 -0
- package/dist/shared/harvest/harvest-scheduler.js +647 -0
- package/dist/shared/harvest/harvest-scheduler.js.map +1 -0
- package/dist/shared/harvest/index.d.ts +7 -0
- package/dist/shared/harvest/index.d.ts.map +1 -0
- package/dist/shared/harvest/index.js +4 -0
- package/dist/shared/harvest/index.js.map +1 -0
- package/dist/shared/harvest/metric-aggregator.d.ts +115 -0
- package/dist/shared/harvest/metric-aggregator.d.ts.map +1 -0
- package/dist/shared/harvest/metric-aggregator.js +247 -0
- package/dist/shared/harvest/metric-aggregator.js.map +1 -0
- package/dist/shared/index.d.ts +22 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +13 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/logger.d.ts +57 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +166 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/pricing-data.d.ts +4 -0
- package/dist/shared/pricing-data.d.ts.map +1 -0
- package/dist/shared/pricing-data.js +473 -0
- package/dist/shared/pricing-data.js.map +1 -0
- package/dist/shared/pricing.d.ts +148 -0
- package/dist/shared/pricing.d.ts.map +1 -0
- package/dist/shared/pricing.js +528 -0
- package/dist/shared/pricing.js.map +1 -0
- package/dist/shared/redact.d.ts +33 -0
- package/dist/shared/redact.d.ts.map +1 -0
- package/dist/shared/redact.js +110 -0
- package/dist/shared/redact.js.map +1 -0
- package/dist/shared/timing.d.ts +96 -0
- package/dist/shared/timing.d.ts.map +1 -0
- package/dist/shared/timing.js +173 -0
- package/dist/shared/timing.js.map +1 -0
- package/dist/shared/tokens.d.ts +145 -0
- package/dist/shared/tokens.d.ts.map +1 -0
- package/dist/shared/tokens.js +492 -0
- package/dist/shared/tokens.js.map +1 -0
- package/dist/shared/transport/events-api.d.ts +14 -0
- package/dist/shared/transport/events-api.d.ts.map +1 -0
- package/dist/shared/transport/events-api.js +29 -0
- package/dist/shared/transport/events-api.js.map +1 -0
- package/dist/shared/transport/http-client.d.ts +49 -0
- package/dist/shared/transport/http-client.d.ts.map +1 -0
- package/dist/shared/transport/http-client.js +381 -0
- package/dist/shared/transport/http-client.js.map +1 -0
- package/dist/shared/transport/index.d.ts +10 -0
- package/dist/shared/transport/index.d.ts.map +1 -0
- package/dist/shared/transport/index.js +6 -0
- package/dist/shared/transport/index.js.map +1 -0
- package/dist/shared/transport/logs-api.d.ts +29 -0
- package/dist/shared/transport/logs-api.d.ts.map +1 -0
- package/dist/shared/transport/logs-api.js +40 -0
- package/dist/shared/transport/logs-api.js.map +1 -0
- package/dist/shared/transport/metric-api.d.ts +9 -0
- package/dist/shared/transport/metric-api.d.ts.map +1 -0
- package/dist/shared/transport/metric-api.js +39 -0
- package/dist/shared/transport/metric-api.js.map +1 -0
- package/dist/shared/transport/otlp-event-bridge.d.ts +22 -0
- package/dist/shared/transport/otlp-event-bridge.d.ts.map +1 -0
- package/dist/shared/transport/otlp-event-bridge.js +50 -0
- package/dist/shared/transport/otlp-event-bridge.js.map +1 -0
- package/dist/shared/transport/otlp-shared.d.ts +14 -0
- package/dist/shared/transport/otlp-shared.d.ts.map +1 -0
- package/dist/shared/transport/otlp-shared.js +49 -0
- package/dist/shared/transport/otlp-shared.js.map +1 -0
- package/dist/shared/transport/otlp-transport.d.ts +58 -0
- package/dist/shared/transport/otlp-transport.d.ts.map +1 -0
- package/dist/shared/transport/otlp-transport.js +236 -0
- package/dist/shared/transport/otlp-transport.js.map +1 -0
- package/dist/shared/transport/types.d.ts +129 -0
- package/dist/shared/transport/types.d.ts.map +1 -0
- package/dist/shared/transport/types.js +2 -0
- package/dist/shared/transport/types.js.map +1 -0
- package/dist/shared/version.d.ts +2 -0
- package/dist/shared/version.d.ts.map +1 -0
- package/dist/shared/version.js +2 -0
- package/dist/shared/version.js.map +1 -0
- package/dist/storage/index.d.ts +7 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +4 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/local-store.d.ts +153 -0
- package/dist/storage/local-store.d.ts.map +1 -0
- package/dist/storage/local-store.js +719 -0
- package/dist/storage/local-store.js.map +1 -0
- package/dist/storage/retention.d.ts +2 -0
- package/dist/storage/retention.d.ts.map +1 -0
- package/dist/storage/retention.js +53 -0
- package/dist/storage/retention.js.map +1 -0
- package/dist/storage/session-store.d.ts +97 -0
- package/dist/storage/session-store.d.ts.map +1 -0
- package/dist/storage/session-store.js +391 -0
- package/dist/storage/session-store.js.map +1 -0
- package/dist/storage/types.d.ts +64 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/storage/weekly-summary.d.ts +61 -0
- package/dist/storage/weekly-summary.d.ts.map +1 -0
- package/dist/storage/weekly-summary.js +243 -0
- package/dist/storage/weekly-summary.js.map +1 -0
- package/dist/tools/analytics-tools.d.ts +101 -0
- package/dist/tools/analytics-tools.d.ts.map +1 -0
- package/dist/tools/analytics-tools.js +71 -0
- package/dist/tools/analytics-tools.js.map +1 -0
- package/dist/tools/cost-tools.d.ts +121 -0
- package/dist/tools/cost-tools.d.ts.map +1 -0
- package/dist/tools/cost-tools.js +174 -0
- package/dist/tools/cost-tools.js.map +1 -0
- package/dist/tools/cross-session-tools.d.ts +376 -0
- package/dist/tools/cross-session-tools.d.ts.map +1 -0
- package/dist/tools/cross-session-tools.js +820 -0
- package/dist/tools/cross-session-tools.js.map +1 -0
- package/dist/tools/extended-analytics-tools.d.ts +164 -0
- package/dist/tools/extended-analytics-tools.d.ts.map +1 -0
- package/dist/tools/extended-analytics-tools.js +121 -0
- package/dist/tools/extended-analytics-tools.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/session-stats.d.ts +162 -0
- package/dist/tools/session-stats.d.ts.map +1 -0
- package/dist/tools/session-stats.js +1054 -0
- package/dist/tools/session-stats.js.map +1 -0
- package/dist/tools/workflow-tools.d.ts +126 -0
- package/dist/tools/workflow-tools.d.ts.map +1 -0
- package/dist/tools/workflow-tools.js +274 -0
- package/dist/tools/workflow-tools.js.map +1 -0
- package/dist/tracing/mcp-tracer.d.ts +4 -0
- package/dist/tracing/mcp-tracer.d.ts.map +1 -0
- package/dist/tracing/mcp-tracer.js +14 -0
- package/dist/tracing/mcp-tracer.js.map +1 -0
- package/dist/tracing/session-span.d.ts +14 -0
- package/dist/tracing/session-span.d.ts.map +1 -0
- package/dist/tracing/session-span.js +53 -0
- package/dist/tracing/session-span.js.map +1 -0
- package/dist/tracing/task-span-tracker.d.ts +11 -0
- package/dist/tracing/task-span-tracker.d.ts.map +1 -0
- package/dist/tracing/task-span-tracker.js +59 -0
- package/dist/tracing/task-span-tracker.js.map +1 -0
- package/dist/tracing/tool-call-span.d.ts +4 -0
- package/dist/tracing/tool-call-span.d.ts.map +1 -0
- package/dist/tracing/tool-call-span.js +60 -0
- package/dist/tracing/tool-call-span.js.map +1 -0
- package/dist/transport/index.d.ts +3 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +2 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/log-ingest.d.ts +42 -0
- package/dist/transport/log-ingest.d.ts.map +1 -0
- package/dist/transport/log-ingest.js +151 -0
- package/dist/transport/log-ingest.js.map +1 -0
- package/dist/transport/nr-ingest.d.ts +171 -0
- package/dist/transport/nr-ingest.d.ts.map +1 -0
- package/dist/transport/nr-ingest.js +659 -0
- package/dist/transport/nr-ingest.js.map +1 -0
- package/dist/types.d.ts +45 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/web/assets/index-BrL281N-.css +2 -0
- package/dist/web/assets/index-CcaYZzXm.js +42 -0
- package/dist/web/favicon.svg +15 -0
- package/dist/web/index.html +15 -0
- package/examples/local-alert-rules.json +106 -0
- package/package.json +125 -1
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { gzip } from 'node:zlib';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { createLogger } from '../logger.js';
|
|
5
|
+
import { VERSION } from '../version.js';
|
|
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
|
+
}
|
|
16
|
+
const gzipAsync = promisify(gzip);
|
|
17
|
+
const logger = createLogger('transport');
|
|
18
|
+
/**
|
|
19
|
+
* Generate a short correlation ID for an outbound batch
|
|
20
|
+
* (14 / §10.5). Eight hex chars derived from a v4 UUID is
|
|
21
|
+
* enough entropy to disambiguate concurrent retries in stderr without
|
|
22
|
+
* adding meaningful payload weight or scanning friction.
|
|
23
|
+
*/
|
|
24
|
+
function newRequestId() {
|
|
25
|
+
return randomUUID().slice(0, 8);
|
|
26
|
+
}
|
|
27
|
+
// Exact license-key prefixes we recognize, plus the region they map to.
|
|
28
|
+
// Prefixes are matched case-insensitively.
|
|
29
|
+
const LICENSE_KEY_REGION_PREFIXES = {
|
|
30
|
+
us01: 'us',
|
|
31
|
+
eu01: 'eu',
|
|
32
|
+
gov01: 'gov',
|
|
33
|
+
};
|
|
34
|
+
// Pattern for *any* string that looks like a region prefix (2-4 letters then
|
|
35
|
+
// 2 digits at the start of the key). If a key matches this pattern but the
|
|
36
|
+
// specific prefix is not in LICENSE_KEY_REGION_PREFIXES, we throw — silently
|
|
37
|
+
// defaulting to US would misroute data to the wrong data center.
|
|
38
|
+
const REGION_PREFIX_SHAPE_RE = /^[a-z]{2,4}\d{2}/;
|
|
39
|
+
export function resolveRegion(licenseKey, collectorHost) {
|
|
40
|
+
// collectorHost overrides take priority — they are an explicit user choice.
|
|
41
|
+
// Only recognise the keyword form (bare word, no dots or colons).
|
|
42
|
+
// Substring matching against FQDNs produced false positives: a host like
|
|
43
|
+
// 'bureau-collector.local' matches 'eu', 'eucalyptus.test' likewise (§HC2).
|
|
44
|
+
if (collectorHost) {
|
|
45
|
+
const host = collectorHost.toLowerCase().trim();
|
|
46
|
+
if (!host.includes('.') && !host.includes(':')) {
|
|
47
|
+
if (host === 'gov')
|
|
48
|
+
return 'gov';
|
|
49
|
+
if (host === 'eu')
|
|
50
|
+
return 'eu';
|
|
51
|
+
if (host === 'us')
|
|
52
|
+
return 'us';
|
|
53
|
+
}
|
|
54
|
+
// FQDN form: licence-key prefix detection below handles region routing.
|
|
55
|
+
}
|
|
56
|
+
const lowerKey = licenseKey.toLowerCase();
|
|
57
|
+
// Exact prefix match — the only path that reliably resolves to a known region.
|
|
58
|
+
for (const [prefix, region] of Object.entries(LICENSE_KEY_REGION_PREFIXES)) {
|
|
59
|
+
if (lowerKey.startsWith(prefix))
|
|
60
|
+
return region;
|
|
61
|
+
}
|
|
62
|
+
// Key has the *shape* of a region prefix but not one we recognize. This
|
|
63
|
+
// most likely means New Relic launched a new region we don't yet support,
|
|
64
|
+
// OR the key is corrupted. Either way, defaulting to US silently misroutes
|
|
65
|
+
// data — fail loudly instead.
|
|
66
|
+
if (REGION_PREFIX_SHAPE_RE.test(lowerKey)) {
|
|
67
|
+
const observedPrefix = lowerKey.match(REGION_PREFIX_SHAPE_RE)[0];
|
|
68
|
+
const supported = Object.keys(LICENSE_KEY_REGION_PREFIXES).join(', ');
|
|
69
|
+
throw new Error(`Unrecognized New Relic license-key region prefix "${observedPrefix}". ` +
|
|
70
|
+
`Supported prefixes: ${supported}. ` +
|
|
71
|
+
`Set 'collectorHost' explicitly to override region detection.`);
|
|
72
|
+
}
|
|
73
|
+
// No region prefix shape — assume legacy US key (40-char hex, no prefix).
|
|
74
|
+
return 'us';
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* §5.9: When `collectorHost` is provided AND looks like a real hostname (has a
|
|
78
|
+
* dot or colon — i.e. an FQDN or host:port), treat it as a literal override and
|
|
79
|
+
* use it as the URL host for ALL three APIs (events, metric, logs). The path
|
|
80
|
+
* remains per-API since the user's proxy must route by path.
|
|
81
|
+
*
|
|
82
|
+
* Without a dot or colon, `collectorHost` is treated as an exact region keyword
|
|
83
|
+
* (one of 'us', 'eu', 'gov') — `resolveRegion` maps it to the
|
|
84
|
+
* appropriate NR hostnames for all three APIs (§HC2 — no substring matching).
|
|
85
|
+
*
|
|
86
|
+
*/
|
|
87
|
+
function isLiteralHostname(collectorHost) {
|
|
88
|
+
if (!collectorHost)
|
|
89
|
+
return false;
|
|
90
|
+
return collectorHost.includes('.') || collectorHost.includes(':');
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Per-region NR ingest hostnames (23 / §5.24).
|
|
94
|
+
*
|
|
95
|
+
* Single source of truth — the three URL builders below all read from this
|
|
96
|
+
* table instead of inlining the same nested-ternary three times. To add a
|
|
97
|
+
* new region, widen `Region` plus `LICENSE_KEY_REGION_PREFIXES` and add
|
|
98
|
+
* one row here; nothing else needs to change.
|
|
99
|
+
*
|
|
100
|
+
* The table is intentionally NOT exported. Hostnames are NR-operated
|
|
101
|
+
* implementation detail — exposing them as a public constant invites
|
|
102
|
+
* consumers to depend on specific values, which would break if NR ever
|
|
103
|
+
* renames a host (§5.23). Consumers that need to override an endpoint
|
|
104
|
+
* should use the `collectorHost` option instead, which already routes
|
|
105
|
+
* through `isLiteralHostname()` above.
|
|
106
|
+
*/
|
|
107
|
+
const NR_INGEST_HOSTS = Object.freeze({
|
|
108
|
+
us: {
|
|
109
|
+
events: 'insights-collector.newrelic.com',
|
|
110
|
+
metric: 'metric-api.newrelic.com',
|
|
111
|
+
log: 'log-api.newrelic.com',
|
|
112
|
+
},
|
|
113
|
+
eu: {
|
|
114
|
+
events: 'insights-collector.eu01.nr-data.net',
|
|
115
|
+
metric: 'metric-api.eu.newrelic.com',
|
|
116
|
+
log: 'log-api.eu.newrelic.com',
|
|
117
|
+
},
|
|
118
|
+
gov: {
|
|
119
|
+
events: 'gov-insights-collector.newrelic.com',
|
|
120
|
+
metric: 'gov-metric-api.newrelic.com',
|
|
121
|
+
log: 'gov-log-api.newrelic.com',
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
export function getEventsApiUrl(accountId, region, collectorHost) {
|
|
125
|
+
// F3: defensive guard against an empty/null/undefined accountId
|
|
126
|
+
// that bypassed `loadConfig`'s fail-fast (e.g. a JS caller, an explicit
|
|
127
|
+
// `accountId: config.accountId!` non-null assertion, or a custom config
|
|
128
|
+
// path that didn't go through loadConfig). Without this, the URL becomes
|
|
129
|
+
// `.../accounts/null/events` and NR responds 404 to every harvest — the
|
|
130
|
+
// scheduler silently retry-loops until the retry buffer overflows.
|
|
131
|
+
if (!accountId || accountId === 'null' || accountId === 'undefined') {
|
|
132
|
+
throw new Error(`getEventsApiUrl: accountId is required (got: ${JSON.stringify(accountId)}). ` +
|
|
133
|
+
`Set the NEW_RELIC_ACCOUNT_ID environment variable or pass accountId in options.`);
|
|
134
|
+
}
|
|
135
|
+
if (isLiteralHostname(collectorHost)) {
|
|
136
|
+
return `https://${collectorHost}/v1/accounts/${accountId}/events`;
|
|
137
|
+
}
|
|
138
|
+
return `https://${NR_INGEST_HOSTS[region].events}/v1/accounts/${accountId}/events`;
|
|
139
|
+
}
|
|
140
|
+
export function getMetricApiUrl(region, collectorHost) {
|
|
141
|
+
if (isLiteralHostname(collectorHost)) {
|
|
142
|
+
return `https://${collectorHost}/metric/v1`;
|
|
143
|
+
}
|
|
144
|
+
return `https://${NR_INGEST_HOSTS[region].metric}/metric/v1`;
|
|
145
|
+
}
|
|
146
|
+
export function getLogsApiUrl(region, collectorHost) {
|
|
147
|
+
if (isLiteralHostname(collectorHost)) {
|
|
148
|
+
return `https://${collectorHost}/log/v1`;
|
|
149
|
+
}
|
|
150
|
+
return `https://${NR_INGEST_HOSTS[region].log}/log/v1`;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* gzip-compress a JSON-serializable payload.
|
|
154
|
+
*
|
|
155
|
+
* Node 18+'s `zlib.gzip` accepts a string directly and performs UTF-8
|
|
156
|
+
* encoding internally, so we hand it `JSON.stringify(data)` and skip the
|
|
157
|
+
* extra `Buffer.from(json)` allocation that the previous implementation
|
|
158
|
+
* incurred (one less buffer per harvest).
|
|
159
|
+
*
|
|
160
|
+
* The returned Buffer is immutable after the call (`zlib.gzip` is a
|
|
161
|
+
* one-shot, not a stateful stream), so it is safe for `sendWithRetry` to
|
|
162
|
+
* reuse the same `compressed` Buffer across retry attempts (§5.16). If a
|
|
163
|
+
* future refactor moves to a stateful gzip stream, that reuse becomes
|
|
164
|
+
* unsafe — pin the call site outside the retry loop accordingly.
|
|
165
|
+
*/
|
|
166
|
+
export async function compressPayload(data) {
|
|
167
|
+
return gzipAsync(JSON.stringify(data));
|
|
168
|
+
}
|
|
169
|
+
function delay(ms) {
|
|
170
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* AWS-recommended decorrelated-jitter exponential backoff.
|
|
174
|
+
*
|
|
175
|
+
* sleep = min(maxDelayMs, random_between(baseDelayMs, prevSleepMs * 3))
|
|
176
|
+
*
|
|
177
|
+
* Compared to "equal jitter" (`backoff * (0.5 + Math.random() * 0.5)`),
|
|
178
|
+
* decorrelated jitter:
|
|
179
|
+
* - smears retries more uniformly across time, reducing the thundering-herd
|
|
180
|
+
* effect when many clients are retrying the same 429,
|
|
181
|
+
* - lets a slow-start grow naturally toward `maxDelayMs` rather than locking
|
|
182
|
+
* the schedule to powers of two of `baseDelayMs`.
|
|
183
|
+
*
|
|
184
|
+
* `prevSleepMs` should start at `baseDelayMs` for the first retry, then carry
|
|
185
|
+
* the chosen wait forward so each subsequent retry samples from a wider band.
|
|
186
|
+
*/
|
|
187
|
+
export function decorrelatedJitter(baseDelayMs, maxDelayMs, prevSleepMs) {
|
|
188
|
+
// Clamp upper to at least baseDelayMs so the jitter band [base, upper] is
|
|
189
|
+
// never negative when maxDelayMs < baseDelayMs (a misconfiguration, but
|
|
190
|
+
// unguarded — without the clamp the sample can be zero or negative, §TR3).
|
|
191
|
+
const upper = Math.max(baseDelayMs, Math.min(maxDelayMs, prevSleepMs * 3));
|
|
192
|
+
// Math.random() returns [0, 1); spread baseDelayMs..upper.
|
|
193
|
+
const sample = baseDelayMs + (upper - baseDelayMs) * Math.random();
|
|
194
|
+
return Math.min(maxDelayMs, Math.max(baseDelayMs, sample));
|
|
195
|
+
}
|
|
196
|
+
function isRetryable(status) {
|
|
197
|
+
return status === 408 || status === 429 || (status >= 500 && status <= 599);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Parse a Retry-After header per RFC 7231:
|
|
201
|
+
* - delta-seconds: a non-negative integer, e.g. "120"
|
|
202
|
+
* - HTTP-date: an absolute date, e.g. "Wed, 21 Oct 2026 07:28:00 GMT"
|
|
203
|
+
* Returns the wait time in milliseconds, or null if absent or malformed.
|
|
204
|
+
*/
|
|
205
|
+
function parseRetryAfterMs(response) {
|
|
206
|
+
const raw = response.headers.get('retry-after');
|
|
207
|
+
if (!raw)
|
|
208
|
+
return null;
|
|
209
|
+
const trimmed = raw.trim();
|
|
210
|
+
// Try delta-seconds first
|
|
211
|
+
if (/^\d+$/.test(trimmed)) {
|
|
212
|
+
return parseInt(trimmed, 10) * 1000;
|
|
213
|
+
}
|
|
214
|
+
// Try HTTP-date
|
|
215
|
+
const ts = Date.parse(trimmed);
|
|
216
|
+
if (!Number.isNaN(ts)) {
|
|
217
|
+
return Math.max(0, ts - Date.now());
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
export async function sendWithRetry(options) {
|
|
222
|
+
const { url, body, licenseKey, maxRetries, baseDelayMs, maxDelayMs, requestTimeoutMs } = options;
|
|
223
|
+
// Per-request correlation ID (14 / §10.5). Stamped on every
|
|
224
|
+
// log line emitted from this call so concurrent retries to different
|
|
225
|
+
// batches can be disambiguated in stderr.
|
|
226
|
+
const requestId = newRequestId();
|
|
227
|
+
let compressed;
|
|
228
|
+
try {
|
|
229
|
+
compressed = await compressPayload(body);
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
233
|
+
logger.error('Failed to compress payload', { requestId, error: message });
|
|
234
|
+
return { success: false, statusCode: null, retryCount: 0, error: `gzip failed: ${message}` };
|
|
235
|
+
}
|
|
236
|
+
// Decorrelated jitter tracks the previous sleep across
|
|
237
|
+
// attempts so each subsequent retry samples from a wider [base, prev*3] band.
|
|
238
|
+
// Initialize to baseDelayMs so the first retry samples [base, base*3].
|
|
239
|
+
let prevSleepMs = baseDelayMs;
|
|
240
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
241
|
+
try {
|
|
242
|
+
// Node 18+ fetch accepts Buffer bodies, but under TS6 Buffer<ArrayBufferLike>
|
|
243
|
+
// no longer satisfies BodyInit (tightened Uint8Array generics). Double-cast
|
|
244
|
+
// through unknown is the standard escape hatch; runtime behaviour is unchanged.
|
|
245
|
+
const fetchBody = compressed;
|
|
246
|
+
const response = await fetch(url, {
|
|
247
|
+
method: 'POST',
|
|
248
|
+
headers: {
|
|
249
|
+
'Api-Key': licenseKey,
|
|
250
|
+
'Content-Type': 'application/json',
|
|
251
|
+
'Content-Encoding': 'gzip',
|
|
252
|
+
'User-Agent': buildUserAgent(options.clientName),
|
|
253
|
+
},
|
|
254
|
+
body: fetchBody,
|
|
255
|
+
signal: AbortSignal.timeout(requestTimeoutMs),
|
|
256
|
+
// §5.20 — `keepalive: true` is a no-op in Node fetch (undici), but
|
|
257
|
+
// safe to set. It exists for the case where this library is consumed
|
|
258
|
+
// in a runtime that *does* honor it (Cloudflare Workers, Deno, browser
|
|
259
|
+
// bundlers): the final shutdown send issued from `HarvestScheduler.stop()`
|
|
260
|
+
// can survive page-unload / process-teardown there. No effect on Node.
|
|
261
|
+
keepalive: true,
|
|
262
|
+
});
|
|
263
|
+
const status = response.status;
|
|
264
|
+
if (status >= 200 && status < 300) {
|
|
265
|
+
// Drain the body so undici returns the socket to the keep-alive pool
|
|
266
|
+
// rather than tearing down the connection (§HC1).
|
|
267
|
+
await response.body?.cancel().catch(() => { });
|
|
268
|
+
return { success: true, statusCode: status, retryCount: attempt };
|
|
269
|
+
}
|
|
270
|
+
// Read the body for all failure paths: gives useful diagnostics for 5xx
|
|
271
|
+
// errors and releases the socket to the keep-alive pool (§HC1).
|
|
272
|
+
const responseBody = (await response.text().catch(() => '')).slice(0, 1024);
|
|
273
|
+
if (status === 400) {
|
|
274
|
+
logger.error('Bad request — dropping batch', {
|
|
275
|
+
requestId,
|
|
276
|
+
statusCode: status,
|
|
277
|
+
response: responseBody,
|
|
278
|
+
});
|
|
279
|
+
return {
|
|
280
|
+
success: false,
|
|
281
|
+
statusCode: status,
|
|
282
|
+
retryCount: attempt,
|
|
283
|
+
// Surface the server's body in the result so the harvest scheduler's
|
|
284
|
+
// log line carries diagnostic detail (e.g. "Reserved attribute name
|
|
285
|
+
// 'accountId'", "Body too large", "Invalid timestamp"). Truncated.
|
|
286
|
+
error: responseBody ? `bad request: ${responseBody}` : 'bad request',
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
if (status === 403) {
|
|
290
|
+
logger.error('Forbidden — possible invalid license key or account permission', {
|
|
291
|
+
requestId,
|
|
292
|
+
statusCode: status,
|
|
293
|
+
response: responseBody,
|
|
294
|
+
});
|
|
295
|
+
return {
|
|
296
|
+
success: false,
|
|
297
|
+
statusCode: status,
|
|
298
|
+
retryCount: attempt,
|
|
299
|
+
error: responseBody ? `forbidden: ${responseBody}` : 'forbidden',
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
if (isRetryable(status)) {
|
|
303
|
+
logger.warn('Retryable status received', {
|
|
304
|
+
requestId,
|
|
305
|
+
statusCode: status,
|
|
306
|
+
attempt,
|
|
307
|
+
response: responseBody.slice(0, 256),
|
|
308
|
+
});
|
|
309
|
+
if (attempt < maxRetries) {
|
|
310
|
+
// Respect server-supplied Retry-After when present; cap at maxDelayMs
|
|
311
|
+
// to avoid pathological values. Otherwise use decorrelated-jitter
|
|
312
|
+
// exponential backoff.
|
|
313
|
+
const retryAfter = parseRetryAfterMs(response);
|
|
314
|
+
let waitMs;
|
|
315
|
+
if (retryAfter !== null) {
|
|
316
|
+
waitMs = Math.min(retryAfter, maxDelayMs);
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
waitMs = decorrelatedJitter(baseDelayMs, maxDelayMs, prevSleepMs);
|
|
320
|
+
}
|
|
321
|
+
// Always carry the chosen wait forward so the next jitter window
|
|
322
|
+
// widens appropriately — omitting this on the Retry-After path caused
|
|
323
|
+
// the window to stall at [base, base*3] after every server-driven
|
|
324
|
+
// wait (§TR4).
|
|
325
|
+
prevSleepMs = waitMs;
|
|
326
|
+
await delay(waitMs);
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
logger.warn('Max retries exhausted — dropping batch', {
|
|
330
|
+
requestId,
|
|
331
|
+
statusCode: status,
|
|
332
|
+
attempts: attempt + 1,
|
|
333
|
+
});
|
|
334
|
+
return {
|
|
335
|
+
success: false,
|
|
336
|
+
statusCode: status,
|
|
337
|
+
retryCount: attempt,
|
|
338
|
+
error: `max retries exhausted (last status: ${status})`,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
// Non-retryable, non-standard status
|
|
342
|
+
logger.warn('Unexpected status code — dropping batch', {
|
|
343
|
+
requestId,
|
|
344
|
+
statusCode: status,
|
|
345
|
+
response: responseBody.slice(0, 256),
|
|
346
|
+
});
|
|
347
|
+
return {
|
|
348
|
+
success: false,
|
|
349
|
+
statusCode: status,
|
|
350
|
+
retryCount: attempt,
|
|
351
|
+
error: `unexpected status: ${status}`,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
catch (err) {
|
|
355
|
+
// Network error — retryable
|
|
356
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
357
|
+
logger.warn('Network error during send', { requestId, error: message, attempt });
|
|
358
|
+
if (attempt < maxRetries) {
|
|
359
|
+
const waitMs = decorrelatedJitter(baseDelayMs, maxDelayMs, prevSleepMs);
|
|
360
|
+
prevSleepMs = waitMs;
|
|
361
|
+
await delay(waitMs);
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
logger.warn('Max retries exhausted after network errors — dropping batch', {
|
|
365
|
+
requestId,
|
|
366
|
+
attempts: attempt + 1,
|
|
367
|
+
});
|
|
368
|
+
return {
|
|
369
|
+
success: false,
|
|
370
|
+
statusCode: null,
|
|
371
|
+
retryCount: attempt,
|
|
372
|
+
error: `network error: ${message}`,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
// Should not reach here — every loop iteration returns or continues.
|
|
377
|
+
// A throw (not a silent failure return) makes a future loop-logic regression
|
|
378
|
+
// immediately visible rather than producing a confusing success:false result (§TR6).
|
|
379
|
+
throw new Error('sendWithRetry: unreachable code — bug in retry loop logic');
|
|
380
|
+
}
|
|
381
|
+
//# sourceMappingURL=http-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../../src/shared/transport/http-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { sendEvents } from './events-api.js';
|
|
2
|
+
export { sendMetrics } from './metric-api.js';
|
|
3
|
+
export { sendLogs } from './logs-api.js';
|
|
4
|
+
export { OtlpTransport } from './otlp-transport.js';
|
|
5
|
+
export { OtlpEventBridge } from './otlp-event-bridge.js';
|
|
6
|
+
export type { NrLogEntry } from './logs-api.js';
|
|
7
|
+
export type { NrMetric, TransportMode, TransportOptions, TransportResult } from './types.js';
|
|
8
|
+
export type { OtlpTransportOptions } from './otlp-transport.js';
|
|
9
|
+
export type { OtlpEventBridgeOptions } from './otlp-event-bridge.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7F,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { sendEvents } from './events-api.js';
|
|
2
|
+
export { sendMetrics } from './metric-api.js';
|
|
3
|
+
export { sendLogs } from './logs-api.js';
|
|
4
|
+
export { OtlpTransport } from './otlp-transport.js';
|
|
5
|
+
export { OtlpEventBridge } from './otlp-event-bridge.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shared/transport/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { TransportOptions, TransportResult } from './types.js';
|
|
2
|
+
export interface NrLogEntry {
|
|
3
|
+
timestamp: number;
|
|
4
|
+
message: string;
|
|
5
|
+
attributes?: Record<string, string | number | boolean>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Send a batch of log entries to the New Relic Logs API.
|
|
9
|
+
*
|
|
10
|
+
* Body shape: `[{ logs: [...] }]` — the "Detailed JSON"
|
|
11
|
+
* format documented at
|
|
12
|
+
* https://docs.newrelic.com/docs/logs/log-api/introduction-log-api/.
|
|
13
|
+
* NR also accepts a top-level `common` block sibling to `logs` for shared
|
|
14
|
+
* attributes (e.g. `[{ common: { attributes: {…} }, logs: [...] }]`); we
|
|
15
|
+
* don't use it because each log entry already carries its own `attributes`
|
|
16
|
+
* map, but the option is open if a future caller wants to deduplicate
|
|
17
|
+
* across-batch attributes.
|
|
18
|
+
*
|
|
19
|
+
* **⚠️ Standalone transport helper — no harvest-scheduler integration (§11.9).**
|
|
20
|
+
* Unlike `sendEvents` and `sendMetrics`, this function is NOT wired into
|
|
21
|
+
* `HarvestScheduler`. It has no in-memory buffer, no overflow protection, no
|
|
22
|
+
* retry-buffer cap, and no self-monitoring drop metrics. Call it directly only
|
|
23
|
+
* when you own the batching and retry logic yourself. For managed delivery
|
|
24
|
+
* analogous to event/metric harvest, a `NrLogEntry[]` buffer inside
|
|
25
|
+
* `HarvestScheduler` would be the right surface — that work is tracked under
|
|
26
|
+
*.
|
|
27
|
+
*/
|
|
28
|
+
export declare function sendLogs(logs: NrLogEntry[], licenseKey: string, options: TransportOptions): Promise<TransportResult>;
|
|
29
|
+
//# sourceMappingURL=logs-api.d.ts.map
|
|
@@ -0,0 +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;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,UAAU,EAAE,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAkB1B"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { sendWithRetry, resolveRegion, getLogsApiUrl } from './http-client.js';
|
|
2
|
+
/**
|
|
3
|
+
* Send a batch of log entries to the New Relic Logs API.
|
|
4
|
+
*
|
|
5
|
+
* Body shape: `[{ logs: [...] }]` — the "Detailed JSON"
|
|
6
|
+
* format documented at
|
|
7
|
+
* https://docs.newrelic.com/docs/logs/log-api/introduction-log-api/.
|
|
8
|
+
* NR also accepts a top-level `common` block sibling to `logs` for shared
|
|
9
|
+
* attributes (e.g. `[{ common: { attributes: {…} }, logs: [...] }]`); we
|
|
10
|
+
* don't use it because each log entry already carries its own `attributes`
|
|
11
|
+
* map, but the option is open if a future caller wants to deduplicate
|
|
12
|
+
* across-batch attributes.
|
|
13
|
+
*
|
|
14
|
+
* **⚠️ Standalone transport helper — no harvest-scheduler integration (§11.9).**
|
|
15
|
+
* Unlike `sendEvents` and `sendMetrics`, this function is NOT wired into
|
|
16
|
+
* `HarvestScheduler`. It has no in-memory buffer, no overflow protection, no
|
|
17
|
+
* retry-buffer cap, and no self-monitoring drop metrics. Call it directly only
|
|
18
|
+
* when you own the batching and retry logic yourself. For managed delivery
|
|
19
|
+
* analogous to event/metric harvest, a `NrLogEntry[]` buffer inside
|
|
20
|
+
* `HarvestScheduler` would be the right surface — that work is tracked under
|
|
21
|
+
*.
|
|
22
|
+
*/
|
|
23
|
+
export async function sendLogs(logs, licenseKey, options) {
|
|
24
|
+
if (logs.length === 0) {
|
|
25
|
+
return { success: true, statusCode: null, retryCount: 0 };
|
|
26
|
+
}
|
|
27
|
+
const region = resolveRegion(licenseKey, options.collectorHost ?? null);
|
|
28
|
+
const url = getLogsApiUrl(region, options.collectorHost ?? null);
|
|
29
|
+
return sendWithRetry({
|
|
30
|
+
url,
|
|
31
|
+
body: [{ logs }],
|
|
32
|
+
licenseKey,
|
|
33
|
+
maxRetries: options.maxRetries ?? 3,
|
|
34
|
+
baseDelayMs: options.baseDelayMs ?? 1000,
|
|
35
|
+
maxDelayMs: options.maxDelayMs ?? 30_000,
|
|
36
|
+
requestTimeoutMs: options.requestTimeoutMs ?? 30_000,
|
|
37
|
+
clientName: options.clientName,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=logs-api.js.map
|
|
@@ -0,0 +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;;;;;;;;;;;;;;;;;;;;GAoBG;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;KAC/B,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NrMetric, TransportOptions, TransportResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Send a batch of `NrMetric` records to NR's Metric API. Encodes the
|
|
4
|
+
* discriminated union (`gauge`, `count`, `summary`) per NR's wire format,
|
|
5
|
+
* compresses with gzip, and uses the same retry / timeout machinery as
|
|
6
|
+
* `sendEvents`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function sendMetrics(metrics: NrMetric[], licenseKey: string, options: TransportOptions): Promise<TransportResult>;
|
|
9
|
+
//# sourceMappingURL=metric-api.d.ts.map
|
|
@@ -0,0 +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,CAuB1B"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { sendWithRetry, resolveRegion, getMetricApiUrl } from './http-client.js';
|
|
2
|
+
function toWireMetric(m) {
|
|
3
|
+
if (m.intervalMs === undefined) {
|
|
4
|
+
// Gauge with no intervalMs — emit unchanged, drop the field name entirely.
|
|
5
|
+
const { intervalMs: _omit, ...rest } = m;
|
|
6
|
+
void _omit;
|
|
7
|
+
return rest;
|
|
8
|
+
}
|
|
9
|
+
const { intervalMs, ...rest } = m;
|
|
10
|
+
return { ...rest, 'interval.ms': intervalMs };
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Send a batch of `NrMetric` records to NR's Metric API. Encodes the
|
|
14
|
+
* discriminated union (`gauge`, `count`, `summary`) per NR's wire format,
|
|
15
|
+
* compresses with gzip, and uses the same retry / timeout machinery as
|
|
16
|
+
* `sendEvents`.
|
|
17
|
+
*/
|
|
18
|
+
export async function sendMetrics(metrics, licenseKey, options) {
|
|
19
|
+
if (metrics.length === 0) {
|
|
20
|
+
return { success: true, statusCode: null, retryCount: 0 };
|
|
21
|
+
}
|
|
22
|
+
const region = resolveRegion(licenseKey, options.collectorHost ?? null);
|
|
23
|
+
const url = getMetricApiUrl(region, options.collectorHost ?? null);
|
|
24
|
+
// NR Metric API expects: [{ metrics: [...] }]. Rewrite each metric so the
|
|
25
|
+
// camelCase `intervalMs` becomes the literal wire key `interval.ms` per NR
|
|
26
|
+
// Metric API contract.
|
|
27
|
+
const payload = [{ metrics: metrics.map(toWireMetric) }];
|
|
28
|
+
return sendWithRetry({
|
|
29
|
+
url,
|
|
30
|
+
body: payload,
|
|
31
|
+
licenseKey,
|
|
32
|
+
maxRetries: options.maxRetries ?? 3,
|
|
33
|
+
baseDelayMs: options.baseDelayMs ?? 1000,
|
|
34
|
+
maxDelayMs: options.maxDelayMs ?? 30_000,
|
|
35
|
+
requestTimeoutMs: options.requestTimeoutMs ?? 30_000,
|
|
36
|
+
clientName: options.clientName,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=metric-api.js.map
|
|
@@ -0,0 +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;KAC/B,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { NrEventData } from '../events/types.js';
|
|
2
|
+
export interface OtlpEventBridgeOptions {
|
|
3
|
+
endpoint: string;
|
|
4
|
+
headers?: Record<string, string>;
|
|
5
|
+
appName: string;
|
|
6
|
+
/**
|
|
7
|
+
* OTel logger name used to identify the source of log records emitted by
|
|
8
|
+
* this bridge. Defaults to `'ai-telemetry'` when not provided. Pass
|
|
9
|
+
* `'preflight'`, `'my-agent'`, etc. so telemetry from different
|
|
10
|
+
* consumers is distinguishable in the NR Logs UI.
|
|
11
|
+
*/
|
|
12
|
+
clientName?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class OtlpEventBridge {
|
|
15
|
+
private readonly loggerProvider;
|
|
16
|
+
private readonly otelLogger;
|
|
17
|
+
constructor(options: OtlpEventBridgeOptions);
|
|
18
|
+
sendEvents(events: NrEventData[]): void;
|
|
19
|
+
flush(): Promise<void>;
|
|
20
|
+
shutdown(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=otlp-event-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlp-event-bridge.d.ts","sourceRoot":"","sources":["../../../src/shared/transport/otlp-event-bridge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMtD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;gBAEzD,OAAO,EAAE,sBAAsB;IAwB3C,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI;IAmBjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
|
|
2
|
+
import { LoggerProvider, BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
|
|
3
|
+
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
4
|
+
import { createLogger } from '../logger.js';
|
|
5
|
+
import { validateOtlpEndpoint, hasOtlpAuthHeader, DEFAULT_CLIENT_NAME } from './otlp-shared.js';
|
|
6
|
+
const logger = createLogger('otlp-event-bridge');
|
|
7
|
+
export class OtlpEventBridge {
|
|
8
|
+
loggerProvider;
|
|
9
|
+
otelLogger;
|
|
10
|
+
constructor(options) {
|
|
11
|
+
validateOtlpEndpoint(options.endpoint, 'OtlpEventBridge');
|
|
12
|
+
// Warn once at construction time when no auth header is present (§TR4),
|
|
13
|
+
// matching the behaviour of OtlpTransport.exportMetrics().
|
|
14
|
+
if (!hasOtlpAuthHeader(options.headers ?? {})) {
|
|
15
|
+
logger.warn('OtlpEventBridge constructed with no auth header — collector may reject events', {
|
|
16
|
+
endpoint: options.endpoint,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
const exporter = new OTLPLogExporter({
|
|
20
|
+
url: `${options.endpoint}/v1/logs`,
|
|
21
|
+
headers: options.headers ?? {},
|
|
22
|
+
});
|
|
23
|
+
this.loggerProvider = new LoggerProvider({
|
|
24
|
+
resource: resourceFromAttributes({ 'service.name': options.appName }),
|
|
25
|
+
processors: [new BatchLogRecordProcessor(exporter)],
|
|
26
|
+
});
|
|
27
|
+
this.otelLogger = this.loggerProvider.getLogger(options.clientName || DEFAULT_CLIENT_NAME);
|
|
28
|
+
}
|
|
29
|
+
sendEvents(events) {
|
|
30
|
+
for (const event of events) {
|
|
31
|
+
this.otelLogger.emit({
|
|
32
|
+
severityText: 'INFO',
|
|
33
|
+
body: String(event['eventType'] ?? 'AiEvent'),
|
|
34
|
+
// Filter to scalar values only — the OTel SDK's AnyValue type also
|
|
35
|
+
// accepts arrays/objects/null, and a non-scalar value would produce a
|
|
36
|
+
// malformed log record. NrEventData is typed as all-scalar but callers
|
|
37
|
+
// may pass unexpected shapes (§TR2).
|
|
38
|
+
attributes: Object.fromEntries(Object.entries(event).filter(([, v]) => typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean')),
|
|
39
|
+
timestamp: typeof event.timestamp === 'number' ? event.timestamp : Date.now(),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async flush() {
|
|
44
|
+
await this.loggerProvider.forceFlush();
|
|
45
|
+
}
|
|
46
|
+
async shutdown() {
|
|
47
|
+
await this.loggerProvider.shutdown();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=otlp-event-bridge.js.map
|
|
@@ -0,0 +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;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEhG,MAAM,MAAM,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAAC;AAejD,MAAM,OAAO,eAAe;IACT,cAAc,CAAiB;IAC/B,UAAU,CAA0C;IAErE,YAAY,OAA+B;QACzC,oBAAoB,CAAC,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;QAE1D,wEAAwE;QACxE,2DAA2D;QAC3D,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC,+EAA+E,EAAE;gBAC3F,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC3B,CAAC,CAAC;QACL,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC;YACnC,GAAG,EAAE,GAAG,OAAO,CAAC,QAAQ,UAAU;YAClC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;SAC/B,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CAAC;YACvC,QAAQ,EAAE,sBAAsB,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;YACrE,UAAU,EAAE,CAAC,IAAI,uBAAuB,CAAC,QAAQ,CAAC,CAAC;SACpD,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAC,CAAC;IAC7F,CAAC;IAED,UAAU,CAAC,MAAqB;QAC9B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBACnB,YAAY,EAAE,MAAM;gBACpB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,SAAS,CAAC;gBAC7C,mEAAmE;gBACnE,sEAAsE;gBACtE,uEAAuE;gBACvE,qCAAqC;gBACrC,UAAU,EAAE,MAAM,CAAC,WAAW,CAC5B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAC1B,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,SAAS,CACpF,CACF;gBACD,SAAS,EAAE,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;aAC9E,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;IACvC,CAAC;CACF"}
|