@adonis-agora/telescope 0.5.2 → 0.7.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/CHANGELOG.md +26 -0
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +6 -0
- package/dist/configure.js.map +1 -1
- package/dist/providers/telescope_alerts_provider.d.ts.map +1 -1
- package/dist/providers/telescope_alerts_provider.js +1 -1
- package/dist/providers/telescope_alerts_provider.js.map +1 -1
- package/dist/providers/telescope_cpu_profiling_provider.d.ts +28 -0
- package/dist/providers/telescope_cpu_profiling_provider.d.ts.map +1 -0
- package/dist/providers/telescope_cpu_profiling_provider.js +45 -0
- package/dist/providers/telescope_cpu_profiling_provider.js.map +1 -0
- package/dist/providers/telescope_mcp_provider.d.ts.map +1 -1
- package/dist/providers/telescope_mcp_provider.js +1 -1
- package/dist/providers/telescope_mcp_provider.js.map +1 -1
- package/dist/providers/telescope_provider.d.ts.map +1 -1
- package/dist/providers/telescope_provider.js +9 -3
- package/dist/providers/telescope_provider.js.map +1 -1
- package/dist/providers/telescope_ui_provider.d.ts.map +1 -1
- package/dist/providers/telescope_ui_provider.js +163 -12
- package/dist/providers/telescope_ui_provider.js.map +1 -1
- package/dist/providers/telescope_watchers_provider.d.ts +10 -0
- package/dist/providers/telescope_watchers_provider.d.ts.map +1 -1
- package/dist/providers/telescope_watchers_provider.js +32 -0
- package/dist/providers/telescope_watchers_provider.js.map +1 -1
- package/dist/src/ai/index.d.ts +1 -1
- package/dist/src/ai/index.js +1 -1
- package/dist/src/alerts/alert_rule.d.ts +84 -3
- package/dist/src/alerts/alert_rule.d.ts.map +1 -1
- package/dist/src/alerts/alerter.d.ts +24 -2
- package/dist/src/alerts/alerter.d.ts.map +1 -1
- package/dist/src/alerts/alerter.js +122 -11
- package/dist/src/alerts/alerter.js.map +1 -1
- package/dist/src/alerts/define_config.d.ts +9 -1
- package/dist/src/alerts/define_config.d.ts.map +1 -1
- package/dist/src/alerts/define_config.js +8 -0
- package/dist/src/alerts/define_config.js.map +1 -1
- package/dist/src/alerts/exception_source.d.ts +16 -7
- package/dist/src/alerts/exception_source.d.ts.map +1 -1
- package/dist/src/alerts/exception_source.js +29 -17
- package/dist/src/alerts/exception_source.js.map +1 -1
- package/dist/src/alerts/index.d.ts +2 -2
- package/dist/src/alerts/index.d.ts.map +1 -1
- package/dist/src/alerts/index.js +1 -1
- package/dist/src/alerts/index.js.map +1 -1
- package/dist/src/alerts/slack_format.d.ts +8 -0
- package/dist/src/alerts/slack_format.d.ts.map +1 -1
- package/dist/src/alerts/slack_format.js +128 -3
- package/dist/src/alerts/slack_format.js.map +1 -1
- package/dist/src/client_errors/ingestor.d.ts.map +1 -1
- package/dist/src/client_errors/ingestor.js +20 -1
- package/dist/src/client_errors/ingestor.js.map +1 -1
- package/dist/src/client_errors/validation.d.ts.map +1 -1
- package/dist/src/client_errors/validation.js +7 -2
- package/dist/src/client_errors/validation.js.map +1 -1
- package/dist/src/define_config.d.ts +51 -0
- package/dist/src/define_config.d.ts.map +1 -1
- package/dist/src/define_config.js +6 -0
- package/dist/src/define_config.js.map +1 -1
- package/dist/src/diagnostics_registry.d.ts +15 -0
- package/dist/src/diagnostics_registry.d.ts.map +1 -1
- package/dist/src/diagnostics_registry.js +19 -0
- package/dist/src/diagnostics_registry.js.map +1 -1
- package/dist/src/diagnostics_watcher.d.ts +28 -1
- package/dist/src/diagnostics_watcher.d.ts.map +1 -1
- package/dist/src/diagnostics_watcher.js +17 -2
- package/dist/src/diagnostics_watcher.js.map +1 -1
- package/dist/src/entry.d.ts +8 -0
- package/dist/src/entry.d.ts.map +1 -1
- package/dist/src/entry.js +8 -0
- package/dist/src/entry.js.map +1 -1
- package/dist/src/extension/types.d.ts +35 -2
- package/dist/src/extension/types.d.ts.map +1 -1
- package/dist/src/extension/types.js.map +1 -1
- package/dist/src/index.d.ts +7 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/index.d.ts +1 -1
- package/dist/src/mcp/index.js +1 -1
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +7 -2
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/metrics/waterfall.d.ts.map +1 -1
- package/dist/src/metrics/waterfall.js +6 -0
- package/dist/src/metrics/waterfall.js.map +1 -1
- package/dist/src/profiling/aggregate-profile.d.ts +21 -0
- package/dist/src/profiling/aggregate-profile.d.ts.map +1 -0
- package/dist/src/profiling/aggregate-profile.js +124 -0
- package/dist/src/profiling/aggregate-profile.js.map +1 -0
- package/dist/src/profiling/cpu-profiler.d.ts +59 -0
- package/dist/src/profiling/cpu-profiler.d.ts.map +1 -0
- package/dist/src/profiling/cpu-profiler.js +94 -0
- package/dist/src/profiling/cpu-profiler.js.map +1 -0
- package/dist/src/profiling/define_config.d.ts +38 -0
- package/dist/src/profiling/define_config.d.ts.map +1 -0
- package/dist/src/profiling/define_config.js +23 -0
- package/dist/src/profiling/define_config.js.map +1 -0
- package/dist/src/profiling/index.d.ts +11 -0
- package/dist/src/profiling/index.d.ts.map +1 -0
- package/dist/src/profiling/index.js +7 -0
- package/dist/src/profiling/index.js.map +1 -0
- package/dist/src/profiling/profiler_service.d.ts +100 -0
- package/dist/src/profiling/profiler_service.d.ts.map +1 -0
- package/dist/src/profiling/profiler_service.js +162 -0
- package/dist/src/profiling/profiler_service.js.map +1 -0
- package/dist/src/profiling/types.d.ts +86 -0
- package/dist/src/profiling/types.d.ts.map +1 -0
- package/dist/src/profiling/types.js +5 -0
- package/dist/src/profiling/types.js.map +1 -0
- package/dist/src/redaction/redact.d.ts +21 -0
- package/dist/src/redaction/redact.d.ts.map +1 -1
- package/dist/src/redaction/redact.js +18 -0
- package/dist/src/redaction/redact.js.map +1 -1
- package/dist/src/redaction/redacting_store.d.ts.map +1 -1
- package/dist/src/redaction/redacting_store.js +10 -1
- package/dist/src/redaction/redacting_store.js.map +1 -1
- package/dist/src/registry.d.ts +36 -1
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +24 -1
- package/dist/src/registry.js.map +1 -1
- package/dist/src/request_watcher.d.ts +68 -0
- package/dist/src/request_watcher.d.ts.map +1 -1
- package/dist/src/request_watcher.js +101 -0
- package/dist/src/request_watcher.js.map +1 -1
- package/dist/src/service.d.ts.map +1 -1
- package/dist/src/service.js.map +1 -1
- package/dist/src/telescope_middleware.d.ts.map +1 -1
- package/dist/src/telescope_middleware.js +30 -1
- package/dist/src/telescope_middleware.js.map +1 -1
- package/dist/src/ui/api.d.ts +41 -1
- package/dist/src/ui/api.d.ts.map +1 -1
- package/dist/src/ui/api.js +27 -1
- package/dist/src/ui/api.js.map +1 -1
- package/dist/src/ui/dashboard.html +58 -10
- package/dist/src/ui/define_config.d.ts +26 -0
- package/dist/src/ui/define_config.d.ts.map +1 -1
- package/dist/src/ui/define_config.js +8 -0
- package/dist/src/ui/define_config.js.map +1 -1
- package/dist/src/ui/diagnosis_api.d.ts +33 -0
- package/dist/src/ui/diagnosis_api.d.ts.map +1 -0
- package/dist/src/ui/diagnosis_api.js +60 -0
- package/dist/src/ui/diagnosis_api.js.map +1 -0
- package/dist/src/ui/ext_table.d.ts +50 -0
- package/dist/src/ui/ext_table.d.ts.map +1 -0
- package/dist/src/ui/ext_table.js +42 -0
- package/dist/src/ui/ext_table.js.map +1 -0
- package/dist/src/ui/extension_api.d.ts +6 -2
- package/dist/src/ui/extension_api.d.ts.map +1 -1
- package/dist/src/ui/extension_api.js +7 -2
- package/dist/src/ui/extension_api.js.map +1 -1
- package/dist/src/ui/index.d.ts +10 -2
- package/dist/src/ui/index.d.ts.map +1 -1
- package/dist/src/ui/index.js +9 -1
- package/dist/src/ui/index.js.map +1 -1
- package/dist/src/ui/profiles_api.d.ts +48 -0
- package/dist/src/ui/profiles_api.d.ts.map +1 -0
- package/dist/src/ui/profiles_api.js +94 -0
- package/dist/src/ui/profiles_api.js.map +1 -0
- package/dist/src/ui/queue_manager_api.d.ts +46 -0
- package/dist/src/ui/queue_manager_api.d.ts.map +1 -0
- package/dist/src/ui/queue_manager_api.js +118 -0
- package/dist/src/ui/queue_manager_api.js.map +1 -0
- package/dist/src/ui/schedules_api.d.ts +43 -0
- package/dist/src/ui/schedules_api.d.ts.map +1 -0
- package/dist/src/ui/schedules_api.js +46 -0
- package/dist/src/ui/schedules_api.js.map +1 -0
- package/dist/src/watchers/cron_next_run.d.ts +8 -0
- package/dist/src/watchers/cron_next_run.d.ts.map +1 -0
- package/dist/src/watchers/cron_next_run.js +67 -0
- package/dist/src/watchers/cron_next_run.js.map +1 -0
- package/dist/src/watchers/define_config.d.ts +28 -1
- package/dist/src/watchers/define_config.d.ts.map +1 -1
- package/dist/src/watchers/define_config.js +5 -0
- package/dist/src/watchers/define_config.js.map +1 -1
- package/dist/src/watchers/index.d.ts +7 -4
- package/dist/src/watchers/index.d.ts.map +1 -1
- package/dist/src/watchers/index.js +5 -2
- package/dist/src/watchers/index.js.map +1 -1
- package/dist/src/watchers/queue_manager.d.ts +229 -0
- package/dist/src/watchers/queue_manager.d.ts.map +1 -0
- package/dist/src/watchers/queue_manager.js +223 -0
- package/dist/src/watchers/queue_manager.js.map +1 -0
- package/dist/src/watchers/schedule_watcher.d.ts +94 -1
- package/dist/src/watchers/schedule_watcher.d.ts.map +1 -1
- package/dist/src/watchers/schedule_watcher.js +89 -2
- package/dist/src/watchers/schedule_watcher.js.map +1 -1
- package/dist/stubs/config/telescope_cpu_profiling.stub +0 -0
- package/package.json +29 -14
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { type RecordInput } from '../entry.js';
|
|
2
|
+
import { type CpuProfilerResult } from './cpu-profiler.js';
|
|
3
|
+
import type { ResolvedTelescopeCpuProfilingConfig } from './define_config.js';
|
|
4
|
+
import type { CpuProfileContent } from './types.js';
|
|
5
|
+
/** The `type` of the entries this service records. */
|
|
6
|
+
export declare const CPU_PROFILE_ENTRY_TYPE: "cpu_profile";
|
|
7
|
+
/** Opaque handle for an in-flight capture, returned by {@link ProfilerService.begin}. */
|
|
8
|
+
export interface ProfileHandle {
|
|
9
|
+
readonly profiler: ProfilerLike;
|
|
10
|
+
readonly startedAt: number;
|
|
11
|
+
readonly reason: 'manual' | 'sampled';
|
|
12
|
+
/**
|
|
13
|
+
* The (fire-and-forget) start promise. {@link ProfilerService.end} awaits it
|
|
14
|
+
* before calling `stop()` so a capture that ends before `start()` settled (a
|
|
15
|
+
* very fast request, or a synchronous test) is still stopped correctly rather
|
|
16
|
+
* than seeing `isRunning === false` and silently dropping the profile.
|
|
17
|
+
*/
|
|
18
|
+
readonly started: Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
/** Minimal profiler contract so the service can be tested with a fake. */
|
|
21
|
+
export interface ProfilerLike {
|
|
22
|
+
readonly isRunning: boolean;
|
|
23
|
+
start(): Promise<void>;
|
|
24
|
+
stop(): Promise<CpuProfilerResult | null>;
|
|
25
|
+
}
|
|
26
|
+
export interface ProfilerServiceDeps {
|
|
27
|
+
/** RNG for sampling — injectable for deterministic tests. */
|
|
28
|
+
random?: () => number;
|
|
29
|
+
/** Builds a profiler; injectable so tests avoid the real inspector. */
|
|
30
|
+
profilerFactory?: () => ProfilerLike;
|
|
31
|
+
/** Records the finished profile; injectable for tests. Defaults to `safeRecord`
|
|
32
|
+
* through the runtime store slot (mirrors every other watcher). */
|
|
33
|
+
record?: (input: RecordInput<CpuProfileContent>) => void;
|
|
34
|
+
}
|
|
35
|
+
export interface ProfilerStatus {
|
|
36
|
+
enabled: boolean;
|
|
37
|
+
sampleRate: number;
|
|
38
|
+
/** Currently in-flight captures. */
|
|
39
|
+
active: number;
|
|
40
|
+
maxConcurrent: number;
|
|
41
|
+
/** Remaining manual budget across all arms. */
|
|
42
|
+
pendingManual: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Decides whether to profile a request and drives the capture lifecycle around
|
|
46
|
+
* it. {@link TelescopeMiddleware} calls {@link shouldProfile} (cheap gate), then
|
|
47
|
+
* {@link begin}/{@link end} around the request body — ported near-verbatim from
|
|
48
|
+
* `nestjs-telescope`'s `ProfilerService`; only the recording seam changed (fire-and-forget
|
|
49
|
+
* `safeRecord` through the runtime store slot, matching every other Adonis watcher, instead of a
|
|
50
|
+
* NestJS-injected recorder).
|
|
51
|
+
*
|
|
52
|
+
* OVERHEAD: while disabled, {@link shouldProfile} returns false and {@link begin}
|
|
53
|
+
* returns null after a single boolean check — no profiler is ever constructed
|
|
54
|
+
* and `node:inspector` is never required. While enabled but a request isn't
|
|
55
|
+
* selected, the only added cost is the gate and (if sampling) one RNG call.
|
|
56
|
+
*/
|
|
57
|
+
export declare class ProfilerService {
|
|
58
|
+
private readonly config;
|
|
59
|
+
private active;
|
|
60
|
+
private readonly manual;
|
|
61
|
+
private readonly random;
|
|
62
|
+
private readonly profilerFactory;
|
|
63
|
+
private readonly recordFn;
|
|
64
|
+
constructor(config: ResolvedTelescopeCpuProfilingConfig, deps?: ProfilerServiceDeps);
|
|
65
|
+
/**
|
|
66
|
+
* Arm a manual capture for the next `count` requests (optionally only those
|
|
67
|
+
* matching `label`). Returns the pending budget. No-op when disabled.
|
|
68
|
+
*/
|
|
69
|
+
arm(arm: {
|
|
70
|
+
count: number;
|
|
71
|
+
label?: string;
|
|
72
|
+
}): {
|
|
73
|
+
pendingManual: number;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Whether this request should be profiled. Consults the manual arm budget
|
|
77
|
+
* first (targeted captures win), then sampling. Cheap and side-effect-free
|
|
78
|
+
* EXCEPT it does not yet consume the manual budget — that happens in
|
|
79
|
+
* {@link begin} so a request rejected by the concurrency cap doesn't waste it.
|
|
80
|
+
*/
|
|
81
|
+
shouldProfile(label: string | null): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Begin a capture for a request that {@link shouldProfile} accepted. Returns a
|
|
84
|
+
* handle to pass to {@link end}, or `null` if the request should not be
|
|
85
|
+
* profiled (disabled, concurrency cap reached, or not selected). The caller
|
|
86
|
+
* MUST treat a null handle as "no profiling" and proceed untouched.
|
|
87
|
+
*/
|
|
88
|
+
begin(label: string | null): ProfileHandle | null;
|
|
89
|
+
/**
|
|
90
|
+
* Stop a capture and record it as a `cpu_profile` entry. Safe to call with a
|
|
91
|
+
* null handle (no-op). Never throws into the host request path. Captures below
|
|
92
|
+
* the `minDurationMs` floor are discarded.
|
|
93
|
+
*/
|
|
94
|
+
end(handle: ProfileHandle | null, label: string | null): Promise<void>;
|
|
95
|
+
status(): ProfilerStatus;
|
|
96
|
+
private pendingManual;
|
|
97
|
+
/** First arm matching this label (labelled arms require an exact match). */
|
|
98
|
+
private matchingArm;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=profiler_service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiler_service.d.ts","sourceRoot":"","sources":["../../../src/profiling/profiler_service.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,sDAAsD;AACtD,eAAO,MAAM,sBAAsB,eAAuB,CAAC;AAE3D,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CAC3C;AASD,MAAM,WAAW,mBAAmB;IAClC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,uEAAuE;IACvE,eAAe,CAAC,EAAE,MAAM,YAAY,CAAC;IACrC;wEACoE;IACpE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;CAC1D;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAe;IAQxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkD;gBAGxD,MAAM,EAAE,mCAAmC,EAC5D,IAAI,GAAE,mBAAwB;IAShC;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE;IAOtE;;;;;OAKG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO;IAO5C;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,GAAG,IAAI;IAuBjD;;;;OAIG;IACG,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAgC5E,MAAM,IAAI,cAAc;IAUxB,OAAO,CAAC,aAAa;IAIrB,4EAA4E;IAC5E,OAAO,CAAC,WAAW;CAQpB"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { currentTraceId } from '../context_accessor.js';
|
|
2
|
+
import { EntryType } from '../entry.js';
|
|
3
|
+
import { safeRecord } from '../watchers/record.js';
|
|
4
|
+
import { CpuProfiler } from './cpu-profiler.js';
|
|
5
|
+
/** The `type` of the entries this service records. */
|
|
6
|
+
export const CPU_PROFILE_ENTRY_TYPE = EntryType.CpuProfile;
|
|
7
|
+
/**
|
|
8
|
+
* Decides whether to profile a request and drives the capture lifecycle around
|
|
9
|
+
* it. {@link TelescopeMiddleware} calls {@link shouldProfile} (cheap gate), then
|
|
10
|
+
* {@link begin}/{@link end} around the request body — ported near-verbatim from
|
|
11
|
+
* `nestjs-telescope`'s `ProfilerService`; only the recording seam changed (fire-and-forget
|
|
12
|
+
* `safeRecord` through the runtime store slot, matching every other Adonis watcher, instead of a
|
|
13
|
+
* NestJS-injected recorder).
|
|
14
|
+
*
|
|
15
|
+
* OVERHEAD: while disabled, {@link shouldProfile} returns false and {@link begin}
|
|
16
|
+
* returns null after a single boolean check — no profiler is ever constructed
|
|
17
|
+
* and `node:inspector` is never required. While enabled but a request isn't
|
|
18
|
+
* selected, the only added cost is the gate and (if sampling) one RNG call.
|
|
19
|
+
*/
|
|
20
|
+
export class ProfilerService {
|
|
21
|
+
config;
|
|
22
|
+
active = 0;
|
|
23
|
+
manual = [];
|
|
24
|
+
random;
|
|
25
|
+
profilerFactory;
|
|
26
|
+
recordFn;
|
|
27
|
+
constructor(config, deps = {}) {
|
|
28
|
+
this.config = config;
|
|
29
|
+
this.random = deps.random ?? Math.random;
|
|
30
|
+
this.profilerFactory =
|
|
31
|
+
deps.profilerFactory ??
|
|
32
|
+
(() => new CpuProfiler(undefined, { samplingIntervalMicros: config.samplingIntervalMicros }));
|
|
33
|
+
this.recordFn = deps.record ?? ((input) => safeRecord(input, 'ProfilerService'));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Arm a manual capture for the next `count` requests (optionally only those
|
|
37
|
+
* matching `label`). Returns the pending budget. No-op when disabled.
|
|
38
|
+
*/
|
|
39
|
+
arm(arm) {
|
|
40
|
+
if (!this.config.enabled)
|
|
41
|
+
return { pendingManual: 0 };
|
|
42
|
+
const count = Math.max(1, Math.floor(arm.count));
|
|
43
|
+
this.manual.push({ count, ...(arm.label ? { label: arm.label } : {}) });
|
|
44
|
+
return { pendingManual: this.pendingManual() };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Whether this request should be profiled. Consults the manual arm budget
|
|
48
|
+
* first (targeted captures win), then sampling. Cheap and side-effect-free
|
|
49
|
+
* EXCEPT it does not yet consume the manual budget — that happens in
|
|
50
|
+
* {@link begin} so a request rejected by the concurrency cap doesn't waste it.
|
|
51
|
+
*/
|
|
52
|
+
shouldProfile(label) {
|
|
53
|
+
if (!this.config.enabled)
|
|
54
|
+
return false;
|
|
55
|
+
if (this.matchingArm(label) !== null)
|
|
56
|
+
return true;
|
|
57
|
+
if (this.config.sampleRate <= 0)
|
|
58
|
+
return false;
|
|
59
|
+
return this.random() < this.config.sampleRate;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Begin a capture for a request that {@link shouldProfile} accepted. Returns a
|
|
63
|
+
* handle to pass to {@link end}, or `null` if the request should not be
|
|
64
|
+
* profiled (disabled, concurrency cap reached, or not selected). The caller
|
|
65
|
+
* MUST treat a null handle as "no profiling" and proceed untouched.
|
|
66
|
+
*/
|
|
67
|
+
begin(label) {
|
|
68
|
+
if (!this.config.enabled)
|
|
69
|
+
return null;
|
|
70
|
+
const arm = this.matchingArm(label);
|
|
71
|
+
const reason = arm !== null ? 'manual' : 'sampled';
|
|
72
|
+
if (reason === 'sampled') {
|
|
73
|
+
if (this.config.sampleRate <= 0 || this.random() >= this.config.sampleRate)
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
// Respect the concurrency cap BEFORE consuming the manual budget so a capped
|
|
77
|
+
// request can be retried by a later arm.
|
|
78
|
+
if (this.active >= this.config.maxConcurrent)
|
|
79
|
+
return null;
|
|
80
|
+
if (arm !== null) {
|
|
81
|
+
arm.count -= 1;
|
|
82
|
+
if (arm.count <= 0)
|
|
83
|
+
this.manual.splice(this.manual.indexOf(arm), 1);
|
|
84
|
+
}
|
|
85
|
+
const profiler = this.profilerFactory();
|
|
86
|
+
this.active += 1;
|
|
87
|
+
// Start asynchronously; the handle is valid immediately. A start failure
|
|
88
|
+
// simply yields an empty/partial profile at stop — never throws into the host.
|
|
89
|
+
// The promise is retained on the handle so `end` can await it before stopping.
|
|
90
|
+
const started = profiler.start().catch(() => { });
|
|
91
|
+
return { profiler, startedAt: now(), reason, started };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Stop a capture and record it as a `cpu_profile` entry. Safe to call with a
|
|
95
|
+
* null handle (no-op). Never throws into the host request path. Captures below
|
|
96
|
+
* the `minDurationMs` floor are discarded.
|
|
97
|
+
*/
|
|
98
|
+
async end(handle, label) {
|
|
99
|
+
if (handle === null)
|
|
100
|
+
return;
|
|
101
|
+
try {
|
|
102
|
+
// Ensure `start()` settled so `stop()` sees a running profiler. (Real
|
|
103
|
+
// requests run long enough that start is done; this guards the fast path.)
|
|
104
|
+
await handle.started;
|
|
105
|
+
const result = await handle.profiler.stop();
|
|
106
|
+
if (result === null)
|
|
107
|
+
return;
|
|
108
|
+
if (result.durationMs < this.config.minDurationMs)
|
|
109
|
+
return;
|
|
110
|
+
const content = {
|
|
111
|
+
durationMs: result.durationMs,
|
|
112
|
+
sampleCount: result.sampleCount,
|
|
113
|
+
reason: handle.reason,
|
|
114
|
+
label: label ?? null,
|
|
115
|
+
tree: result.tree,
|
|
116
|
+
hot: result.hot,
|
|
117
|
+
};
|
|
118
|
+
this.recordFn({
|
|
119
|
+
type: CPU_PROFILE_ENTRY_TYPE,
|
|
120
|
+
content,
|
|
121
|
+
familyHash: label ?? null,
|
|
122
|
+
tags: ['profile', handle.reason],
|
|
123
|
+
durationMs: result.durationMs,
|
|
124
|
+
traceId: currentTraceId(),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// A failed capture must never affect the request it wrapped.
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
this.active = Math.max(0, this.active - 1);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
status() {
|
|
135
|
+
return {
|
|
136
|
+
enabled: this.config.enabled,
|
|
137
|
+
sampleRate: this.config.sampleRate,
|
|
138
|
+
active: this.active,
|
|
139
|
+
maxConcurrent: this.config.maxConcurrent,
|
|
140
|
+
pendingManual: this.pendingManual(),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
pendingManual() {
|
|
144
|
+
return this.manual.reduce((sum, a) => sum + a.count, 0);
|
|
145
|
+
}
|
|
146
|
+
/** First arm matching this label (labelled arms require an exact match). */
|
|
147
|
+
matchingArm(label) {
|
|
148
|
+
for (const arm of this.manual) {
|
|
149
|
+
if (arm.count <= 0)
|
|
150
|
+
continue;
|
|
151
|
+
if (arm.label === undefined)
|
|
152
|
+
return arm;
|
|
153
|
+
if (label !== null && arm.label === label)
|
|
154
|
+
return arm;
|
|
155
|
+
}
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function now() {
|
|
160
|
+
return Date.now();
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=profiler_service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiler_service.js","sourceRoot":"","sources":["../../../src/profiling/profiler_service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The raw V8 CPU profile shape produced by `Profiler.stop` over the inspector
|
|
3
|
+
* protocol. We model only the fields we consume so we never depend on the
|
|
4
|
+
* inspector typings at our public surface (the `inspector` module is required
|
|
5
|
+
* lazily and ONLY when profiling is enabled — see {@link CpuProfiler} in
|
|
6
|
+
* `cpu-profiler.ts`).
|
|
7
|
+
*
|
|
8
|
+
* @see https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#type-Profile
|
|
9
|
+
*/
|
|
10
|
+
export interface V8CpuProfile {
|
|
11
|
+
/** Flat list of unique call-frame nodes. */
|
|
12
|
+
nodes: V8ProfileNode[];
|
|
13
|
+
/** Profile start time in microseconds. */
|
|
14
|
+
startTime: number;
|
|
15
|
+
/** Profile end time in microseconds. */
|
|
16
|
+
endTime: number;
|
|
17
|
+
/** Node ids sampled, one per sample, in time order. */
|
|
18
|
+
samples?: number[];
|
|
19
|
+
/** Time deltas (microseconds) between consecutive samples. */
|
|
20
|
+
timeDeltas?: number[];
|
|
21
|
+
}
|
|
22
|
+
export interface V8ProfileNode {
|
|
23
|
+
id: number;
|
|
24
|
+
callFrame: V8CallFrame;
|
|
25
|
+
/** Number of samples where this exact node was on top of the stack. */
|
|
26
|
+
hitCount?: number;
|
|
27
|
+
/** Child node ids (callees). */
|
|
28
|
+
children?: number[];
|
|
29
|
+
}
|
|
30
|
+
export interface V8CallFrame {
|
|
31
|
+
functionName: string;
|
|
32
|
+
scriptId: string;
|
|
33
|
+
url: string;
|
|
34
|
+
lineNumber: number;
|
|
35
|
+
columnNumber: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* An aggregated flamegraph node. Time is in MILLISECONDS. `selfMs` is time spent
|
|
39
|
+
* in this frame with nothing above it; `totalMs` includes all descendants. The
|
|
40
|
+
* tree is rooted at a synthetic `(root)` frame so the dashboard can render a
|
|
41
|
+
* single top bar spanning the whole capture.
|
|
42
|
+
*/
|
|
43
|
+
export interface FlameNode {
|
|
44
|
+
/** Human-readable function name (`(anonymous)` / `(idle)` etc. preserved). */
|
|
45
|
+
name: string;
|
|
46
|
+
/** Source location `url:line`, or empty when V8 reported none (native/builtin). */
|
|
47
|
+
file: string;
|
|
48
|
+
/** Inclusive time across this frame and all descendants, in ms. */
|
|
49
|
+
totalMs: number;
|
|
50
|
+
/** Exclusive time in this frame only (samples landing directly here), in ms. */
|
|
51
|
+
selfMs: number;
|
|
52
|
+
/** Sample count attributed inclusively to this subtree. */
|
|
53
|
+
totalSamples: number;
|
|
54
|
+
children: FlameNode[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The persisted content of a `cpu_profile` entry. Deliberately stores the
|
|
58
|
+
* AGGREGATED frame tree (bounded by the call-graph size) rather than the raw
|
|
59
|
+
* per-sample `.cpuprofile` (which is unbounded and would blow the entry content
|
|
60
|
+
* budget). The frame tree is everything the flamegraph renderer needs.
|
|
61
|
+
*/
|
|
62
|
+
export interface CpuProfileContent {
|
|
63
|
+
/** Wall-clock capture duration in ms (endTime - startTime). */
|
|
64
|
+
durationMs: number;
|
|
65
|
+
/** Number of samples collected. */
|
|
66
|
+
sampleCount: number;
|
|
67
|
+
/** What triggered the capture. */
|
|
68
|
+
reason: 'manual' | 'sampled';
|
|
69
|
+
/** Route / label the profile is associated with, when known (e.g. "GET /users/:id"). */
|
|
70
|
+
label: string | null;
|
|
71
|
+
/** The aggregated flamegraph tree (single synthetic root). */
|
|
72
|
+
tree: FlameNode;
|
|
73
|
+
/**
|
|
74
|
+
* Hottest frames by SELF time, precomputed for the dashboard's "hot functions"
|
|
75
|
+
* list so the UI doesn't have to walk the tree. Capped to a small number.
|
|
76
|
+
*/
|
|
77
|
+
hot: HotFrame[];
|
|
78
|
+
}
|
|
79
|
+
export interface HotFrame {
|
|
80
|
+
name: string;
|
|
81
|
+
file: string;
|
|
82
|
+
selfMs: number;
|
|
83
|
+
/** Percentage of total captured time spent self in this frame (0–100). */
|
|
84
|
+
selfPct: number;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/profiling/types.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,WAAW,CAAC;IACvB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,SAAS,EAAE,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC7B,wFAAwF;IACxF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8DAA8D;IAC9D,IAAI,EAAE,SAAS,CAAC;IAChB;;;OAGG;IACH,GAAG,EAAE,QAAQ,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Ported near-verbatim from `nestjs-telescope`'s `packages/core/src/profiling/types.ts` — the V8
|
|
2
|
+
// inspector Profiler protocol shapes and the aggregated flame tree are framework-agnostic (pure
|
|
3
|
+
// `node:inspector` + arithmetic, no NestJS/AdonisJS dependency at all).
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/profiling/types.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,gGAAgG;AAChG,wEAAwE"}
|
|
@@ -44,7 +44,28 @@ export interface RedactOptions {
|
|
|
44
44
|
* remaining subtrees become `'[Truncated: size]'`. ON BY DEFAULT (16_384).
|
|
45
45
|
*/
|
|
46
46
|
maxContentBytes?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Per-entry-type overrides of the numeric bounds above, keyed by the entry's
|
|
49
|
+
* `type` (e.g. `'exception'`, `'client_exception'`). A listed type's bounds are
|
|
50
|
+
* merged OVER the top-level bounds for that entry only; unlisted types use the
|
|
51
|
+
* top-level bounds unchanged. The masking spec (`keys`/`paths`/`mask`) is never
|
|
52
|
+
* per-type — it stays uniform (and is compiled once).
|
|
53
|
+
*
|
|
54
|
+
* Motivation: the content-byte budget is really an OOM guard on HIGH-VOLUME
|
|
55
|
+
* entries (request/query/cache clone big live graphs). Rare, high-value entries
|
|
56
|
+
* — exceptions and client exceptions, whose stacks/componentStacks are
|
|
57
|
+
* legitimately many KB — can be given a bigger budget WITHOUT loosening the
|
|
58
|
+
* guard on the noisy ones.
|
|
59
|
+
*/
|
|
60
|
+
perType?: Record<string, RedactBounds>;
|
|
47
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* The numeric memory bounds of {@link RedactOptions} — the subset overridable
|
|
64
|
+
* PER ENTRY TYPE via {@link RedactOptions.perType}. The masking spec
|
|
65
|
+
* (`keys`/`paths`/`mask`) is deliberately excluded: masking is a security
|
|
66
|
+
* invariant that stays uniform across every entry.
|
|
67
|
+
*/
|
|
68
|
+
export type RedactBounds = Pick<RedactOptions, 'maxDepth' | 'maxStringLength' | 'maxArrayLength' | 'maxNodes' | 'maxContentBytes'>;
|
|
48
69
|
/** Result of a bounded redaction: the detached clone plus whether anything was clipped. */
|
|
49
70
|
export interface RedactBoundedResult {
|
|
50
71
|
/** The detached, masked, bounded clone. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../../src/redaction/redact.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAgBhD,CAAC;AAyBF,2DAA2D;AAC3D,eAAO,MAAM,YAAY,eAAe,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../../src/redaction/redact.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAgBhD,CAAC;AAyBF,2DAA2D;AAC3D,eAAO,MAAM,YAAY,eAAe,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACxC;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,CAC7B,aAAa,EACb,UAAU,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,UAAU,GAAG,iBAAiB,CACnF,CAAC;AAEF,2FAA2F;AAC3F,MAAM,WAAW,mBAAmB;IAClC,2CAA2C;IAC3C,KAAK,EAAE,OAAO,CAAC;IACf,+EAA+E;IAC/E,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5B,sDAAsD;IACtD,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,kBAAkB,CAO5E;AAKD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,aAAkB,GAAG,mBAAmB,CAE9F;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,kBAAkB,GACvB,mBAAmB,CAwHrB;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAE3E"}
|
|
@@ -139,6 +139,24 @@ export function redactBoundedWith(value, options, spec) {
|
|
|
139
139
|
seen.delete(node);
|
|
140
140
|
return mapped;
|
|
141
141
|
}
|
|
142
|
+
// Binary blobs (Buffer, TypedArrays, DataView, ArrayBuffer) are opaque
|
|
143
|
+
// bytes, not a traversable graph — summarize them as a bounded marker
|
|
144
|
+
// instead of walking them. This is load-bearing: a Buffer is `typeof
|
|
145
|
+
// 'object'` and not an Array, so without this it satisfies isPlainObject()
|
|
146
|
+
// and `Object.entries()` EAGERLY materializes one [index, byte] pair per
|
|
147
|
+
// byte BEFORE the node/byte budget is ever consulted. On a multi-MB body
|
|
148
|
+
// (e.g. a raw file-upload chunk) that is seconds of synchronous CPU and
|
|
149
|
+
// hundreds of MB allocated on the event loop — the budgets never get a
|
|
150
|
+
// chance to bite. O(1) here.
|
|
151
|
+
if (ArrayBuffer.isView(node)) {
|
|
152
|
+
truncated = true;
|
|
153
|
+
const name = node.constructor?.name ?? 'Binary';
|
|
154
|
+
return `[${name}: ${node.byteLength} bytes]`;
|
|
155
|
+
}
|
|
156
|
+
if (node instanceof ArrayBuffer) {
|
|
157
|
+
truncated = true;
|
|
158
|
+
return `[ArrayBuffer: ${node.byteLength} bytes]`;
|
|
159
|
+
}
|
|
142
160
|
if (isPlainObject(node)) {
|
|
143
161
|
if (seen.has(node))
|
|
144
162
|
return '[Circular]';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../../src/redaction/redact.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,iFAAiF;AACjF,+EAA+E;AAC/E,iFAAiF;AACjF,oFAAoF;AAEpF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAsB;IACpD,eAAe;IACf,QAAQ;IACR,YAAY;IACZ,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,cAAc;IACd,eAAe;IACf,SAAS;IACT,SAAS;IACT,QAAQ;IACR,WAAW;IACX,eAAe;IACf,aAAa;CACd,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,yBAAyB,GAAG,KAAK,CAAC;AACxC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AACrC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAChC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AACzC;qEACqE;AACrE,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,8EAA8E;AAC9E,MAAM,YAAY,GAAG,oBAAoB,CAAC;AAC1C,gEAAgE;AAChE,MAAM,wBAAwB,GAAG,cAAc,CAAC;AAChD,oFAAoF;AACpF,MAAM,WAAW,GAAG,mBAAmB,CAAC;AACxC,2DAA2D;AAC3D,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../../src/redaction/redact.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redacting_store.d.ts","sourceRoot":"","sources":["../../../src/redaction/redacting_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAEL,KAAK,aAAa,EAGnB,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAwB,YAAW,cAAc;IAI1D,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;gBAGvB,KAAK,EAAE,cAAc,EACrB,OAAO,GAAE,aAAkB;IAKxC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"redacting_store.d.ts","sourceRoot":"","sources":["../../../src/redaction/redacting_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAEL,KAAK,aAAa,EAGnB,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAwB,YAAW,cAAc;IAI1D,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;gBAGvB,KAAK,EAAE,cAAc,EACrB,OAAO,GAAE,aAAkB;IAKxC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAoB9E,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAItC,IAAI,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAI1C,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxB,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvB"}
|
|
@@ -21,11 +21,20 @@ export class RedactingTelescopeStore {
|
|
|
21
21
|
this.spec = compileRedactSpec(options);
|
|
22
22
|
}
|
|
23
23
|
async record(input) {
|
|
24
|
+
// Per-type content bounds: a rare, high-value entry (exception/
|
|
25
|
+
// client_exception, whose stacks are legitimately many KB) can carry a bigger
|
|
26
|
+
// content budget than the high-volume request/query/cache entries the global
|
|
27
|
+
// bound exists to guard. Only the NUMERIC bounds differ per type; the masking
|
|
28
|
+
// spec is shared (compiled once). Most entries have no override → the common
|
|
29
|
+
// path reuses the global options object and allocates nothing.
|
|
30
|
+
const perType = this.options.perType?.[input.type];
|
|
31
|
+
const contentOptions = perType ? { ...this.options, ...perType } : this.options;
|
|
24
32
|
const redacted = {
|
|
25
33
|
...input,
|
|
26
|
-
content: redactBoundedWith(input.content,
|
|
34
|
+
content: redactBoundedWith(input.content, contentOptions, this.spec).value,
|
|
27
35
|
};
|
|
28
36
|
if (input.tags !== undefined) {
|
|
37
|
+
// Tags are small and uniform — always the global bounds (never per-type).
|
|
29
38
|
redacted.tags = redactBoundedWith(input.tags, this.options, this.spec).value;
|
|
30
39
|
}
|
|
31
40
|
return this.inner.record(redacted);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redacting_store.js","sourceRoot":"","sources":["../../../src/redaction/redacting_store.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,uBAAuB;IAIf;IACA;IAJF,IAAI,CAAqB;IAE1C,YACmB,KAAqB,EACrB,UAAyB,EAAE;QAD3B,UAAK,GAAL,KAAK,CAAgB;QACrB,YAAO,GAAP,OAAO,CAAoB;QAE5C,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,MAAM,CAAW,KAA4B;QACjD,MAAM,QAAQ,GAA0B;YACtC,GAAG,KAAK;YACR,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"redacting_store.js","sourceRoot":"","sources":["../../../src/redaction/redacting_store.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,uBAAuB;IAIf;IACA;IAJF,IAAI,CAAqB;IAE1C,YACmB,KAAqB,EACrB,UAAyB,EAAE;QAD3B,UAAK,GAAL,KAAK,CAAgB;QACrB,YAAO,GAAP,OAAO,CAAoB;QAE5C,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,MAAM,CAAW,KAA4B;QACjD,gEAAgE;QAChE,8EAA8E;QAC9E,6EAA6E;QAC7E,8EAA8E;QAC9E,6EAA6E;QAC7E,+DAA+D;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QAChF,MAAM,QAAQ,GAA0B;YACtC,GAAG,KAAK;YACR,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAiB;SACvF,CAAC;QACF,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,0EAA0E;YAC1E,QAAQ,CAAC,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAiB,CAAC;QAC3F,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,KAAkB;QACrB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,SAAe,EAAE,QAAiB;QACtC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;CACF"}
|
package/dist/src/registry.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { DiagnosisCoordinator } from './ai/diagnosis_coordinator.js';
|
|
2
2
|
import type { ExtensionRegistry } from './extension/registry.js';
|
|
3
|
+
import type { ProfilerService } from './profiling/profiler_service.js';
|
|
4
|
+
import type { RequestCaptureOptions } from './request_watcher.js';
|
|
3
5
|
import type { TelescopeStore } from './store.js';
|
|
4
6
|
import type { EntryEvents } from './stream/entry_events.js';
|
|
7
|
+
import type { QueueManager } from './watchers/queue_manager.js';
|
|
5
8
|
/**
|
|
6
9
|
* The live runtime telescope handles, published on a cross-copy-stable global slot
|
|
7
10
|
* so the request middleware can reach the active store WITHOUT constructor wiring
|
|
@@ -14,6 +17,12 @@ export interface TelescopeRuntime {
|
|
|
14
17
|
store: TelescopeStore | null;
|
|
15
18
|
/** Whether the request watcher should record. */
|
|
16
19
|
requestWatcherEnabled: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Resolved request body-capture gates the middleware feeds to the request
|
|
22
|
+
* watcher, or `null` when body capture is off (the default). See
|
|
23
|
+
* {@link RequestCaptureOptions}.
|
|
24
|
+
*/
|
|
25
|
+
requestCapture: RequestCaptureOptions | null;
|
|
17
26
|
/** The booted extension registry (entry types / dashboards / data providers), or `null`. */
|
|
18
27
|
registry: ExtensionRegistry | null;
|
|
19
28
|
/**
|
|
@@ -36,11 +45,25 @@ export interface TelescopeRuntime {
|
|
|
36
45
|
* when its `isConfigured()` is `false` — both degrade to their non-AI behaviour.
|
|
37
46
|
*/
|
|
38
47
|
diagnosisCoordinator: DiagnosisCoordinator | null;
|
|
48
|
+
/**
|
|
49
|
+
* The CPU profiler service published by `@adonis-agora/telescope/cpu_profiling_provider`, or
|
|
50
|
+
* `null` when that OPTIONAL feature is not installed/enabled. `TelescopeMiddleware` reads it (no
|
|
51
|
+
* DI) to gate/begin/end a `node:inspector` capture around each request; the UI routes read it to
|
|
52
|
+
* serve `/api/profiles/*`. `null` degrades every touchpoint to inert (no overhead, 404 routes).
|
|
53
|
+
*/
|
|
54
|
+
cpuProfiler: ProfilerService | null;
|
|
55
|
+
/**
|
|
56
|
+
* The Live Queue Manager driver the `queue-manager` watcher publishes, or `null` when that OPTIONAL
|
|
57
|
+
* capability is not enabled/configured (`@adonisjs/queue` absent, or `queue-manager` not in
|
|
58
|
+
* `config/telescope_watchers.ts`'s `watchers` list). The UI's `/api/queues/live*` routes read it
|
|
59
|
+
* (no DI) to serve the queue console; `null` degrades those routes to a clear "not configured" 404.
|
|
60
|
+
*/
|
|
61
|
+
queueManager: QueueManager | null;
|
|
39
62
|
}
|
|
40
63
|
/** The shared runtime handle. */
|
|
41
64
|
export declare function getTelescopeRuntime(): TelescopeRuntime;
|
|
42
65
|
/** Install the active store + flags (called by the provider at boot). */
|
|
43
|
-
export declare function setTelescopeRuntime(store: TelescopeStore, requestWatcherEnabled: boolean): void;
|
|
66
|
+
export declare function setTelescopeRuntime(store: TelescopeStore, requestWatcherEnabled: boolean, requestCapture?: RequestCaptureOptions | null): void;
|
|
44
67
|
/** Publish the booted extension registry so the UI can serve its dashboards + providers. */
|
|
45
68
|
export declare function setTelescopeExtensionRegistry(registry: ExtensionRegistry | null): void;
|
|
46
69
|
/** Publish the SSE entry-events bus so the UI stream route can subscribe to it. */
|
|
@@ -51,6 +74,18 @@ export declare function setTelescopeEntryEvents(entryEvents: EntryEvents | null)
|
|
|
51
74
|
* clear it (AI disabled / provider shutdown).
|
|
52
75
|
*/
|
|
53
76
|
export declare function setTelescopeDiagnosisCoordinator(coordinator: DiagnosisCoordinator | null): void;
|
|
77
|
+
/**
|
|
78
|
+
* Publish the CPU profiler service (called by `telescope_cpu_profiling_provider` at register) so
|
|
79
|
+
* the request middleware and the UI's `/api/profiles/*` routes can reach it without DI. Pass `null`
|
|
80
|
+
* to clear it (feature disabled / provider shutdown).
|
|
81
|
+
*/
|
|
82
|
+
export declare function setTelescopeCpuProfiler(profiler: ProfilerService | null): void;
|
|
83
|
+
/**
|
|
84
|
+
* Publish the Live Queue Manager driver (called by `TelescopeWatchersProvider` when the
|
|
85
|
+
* `queue-manager` watcher is enabled) so the UI's `/api/queues/live*` routes can reach it without DI.
|
|
86
|
+
* Pass `null` to clear it (capability disabled / provider shutdown).
|
|
87
|
+
*/
|
|
88
|
+
export declare function setTelescopeQueueManager(manager: QueueManager | null): void;
|
|
54
89
|
/**
|
|
55
90
|
* Toggle the overload-shed flag (called by the overload guard). While paused,
|
|
56
91
|
* every ingestion entry point drops new entries. Idempotent.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7B,iDAAiD;IACjD,qBAAqB,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,cAAc,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC7C,4FAA4F;IAC5F,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC;;;;OAIG;IACH,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC;;;;;OAKG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,oBAAoB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClD;;;;;OAKG;IACH,WAAW,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC;;;;;OAKG;IACH,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;CACnC;AAkBD,iCAAiC;AACjC,wBAAgB,mBAAmB,IAAI,gBAAgB,CAEtD;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EACrB,qBAAqB,EAAE,OAAO,EAC9B,cAAc,GAAE,qBAAqB,GAAG,IAAW,GAClD,IAAI,CAIN;AAED,4FAA4F;AAC5F,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI,CAEtF;AAED,mFAAmF;AACnF,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAE/F;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI,CAE9E;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAE3E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAExD;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,IAAI,IAAI,CAU5C"}
|