@adonis-agora/telescope 0.1.0 → 0.3.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 +37 -0
- package/dist/providers/telescope_provider.d.ts +16 -0
- package/dist/providers/telescope_provider.d.ts.map +1 -1
- package/dist/providers/telescope_provider.js +33 -2
- 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 +87 -1
- package/dist/providers/telescope_ui_provider.js.map +1 -1
- package/dist/providers/telescope_watchers_provider.d.ts +11 -0
- package/dist/providers/telescope_watchers_provider.d.ts.map +1 -1
- package/dist/providers/telescope_watchers_provider.js +58 -0
- package/dist/providers/telescope_watchers_provider.js.map +1 -1
- package/dist/src/define_config.d.ts +50 -0
- package/dist/src/define_config.d.ts.map +1 -1
- package/dist/src/define_config.js +9 -0
- package/dist/src/define_config.js.map +1 -1
- package/dist/src/index.d.ts +23 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +17 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/metrics/metrics_service.d.ts +63 -0
- package/dist/src/metrics/metrics_service.d.ts.map +1 -0
- package/dist/src/metrics/metrics_service.js +116 -0
- package/dist/src/metrics/metrics_service.js.map +1 -0
- package/dist/src/metrics/rollup.d.ts +61 -0
- package/dist/src/metrics/rollup.d.ts.map +1 -0
- package/dist/src/metrics/rollup.js +114 -0
- package/dist/src/metrics/rollup.js.map +1 -0
- package/dist/src/metrics/stats.d.ts +112 -0
- package/dist/src/metrics/stats.d.ts.map +1 -0
- package/dist/src/metrics/stats.js +255 -0
- package/dist/src/metrics/stats.js.map +1 -0
- package/dist/src/metrics/timeseries.d.ts +22 -0
- package/dist/src/metrics/timeseries.d.ts.map +1 -0
- package/dist/src/metrics/timeseries.js +34 -0
- package/dist/src/metrics/timeseries.js.map +1 -0
- package/dist/src/metrics/traces.d.ts +27 -0
- package/dist/src/metrics/traces.d.ts.map +1 -0
- package/dist/src/metrics/traces.js +71 -0
- package/dist/src/metrics/traces.js.map +1 -0
- package/dist/src/metrics/waterfall.d.ts +44 -0
- package/dist/src/metrics/waterfall.d.ts.map +1 -0
- package/dist/src/metrics/waterfall.js +99 -0
- package/dist/src/metrics/waterfall.js.map +1 -0
- package/dist/src/query/n_plus_one.d.ts +60 -0
- package/dist/src/query/n_plus_one.d.ts.map +1 -0
- package/dist/src/query/n_plus_one.js +102 -0
- package/dist/src/query/n_plus_one.js.map +1 -0
- package/dist/src/registry.d.ts +9 -0
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +6 -0
- package/dist/src/registry.js.map +1 -1
- package/dist/src/sampling/sampling.d.ts +52 -0
- package/dist/src/sampling/sampling.d.ts.map +1 -0
- package/dist/src/sampling/sampling.js +111 -0
- package/dist/src/sampling/sampling.js.map +1 -0
- package/dist/src/sampling/sampling_store.d.ts +33 -0
- package/dist/src/sampling/sampling_store.d.ts.map +1 -0
- package/dist/src/sampling/sampling_store.js +65 -0
- package/dist/src/sampling/sampling_store.js.map +1 -0
- package/dist/src/stream/entry_events.d.ts +45 -0
- package/dist/src/stream/entry_events.d.ts.map +1 -0
- package/dist/src/stream/entry_events.js +56 -0
- package/dist/src/stream/entry_events.js.map +1 -0
- package/dist/src/stream/index.d.ts +6 -0
- package/dist/src/stream/index.d.ts.map +1 -0
- package/dist/src/stream/index.js +5 -0
- package/dist/src/stream/index.js.map +1 -0
- package/dist/src/stream/stream_handler.d.ts +42 -0
- package/dist/src/stream/stream_handler.d.ts.map +1 -0
- package/dist/src/stream/stream_handler.js +48 -0
- package/dist/src/stream/stream_handler.js.map +1 -0
- package/dist/src/stream/streaming_store.d.ts +31 -0
- package/dist/src/stream/streaming_store.d.ts.map +1 -0
- package/dist/src/stream/streaming_store.js +49 -0
- package/dist/src/stream/streaming_store.js.map +1 -0
- package/dist/src/ui/api.d.ts +39 -1
- package/dist/src/ui/api.d.ts.map +1 -1
- package/dist/src/ui/api.js +116 -1
- package/dist/src/ui/api.js.map +1 -1
- package/dist/src/ui/define_config.d.ts +27 -0
- package/dist/src/ui/define_config.d.ts.map +1 -1
- package/dist/src/ui/define_config.js +6 -0
- package/dist/src/ui/define_config.js.map +1 -1
- package/dist/src/ui/http.d.ts +40 -0
- package/dist/src/ui/http.d.ts.map +1 -1
- package/dist/src/ui/http.js +43 -0
- package/dist/src/ui/http.js.map +1 -1
- package/dist/src/ui/index.d.ts +5 -3
- package/dist/src/ui/index.d.ts.map +1 -1
- package/dist/src/ui/index.js +3 -1
- package/dist/src/ui/index.js.map +1 -1
- package/dist/src/ui/request_replay.d.ts +56 -0
- package/dist/src/ui/request_replay.d.ts.map +1 -0
- package/dist/src/ui/request_replay.js +120 -0
- package/dist/src/ui/request_replay.js.map +1 -0
- package/dist/src/watchers/define_config.d.ts +17 -1
- package/dist/src/watchers/define_config.d.ts.map +1 -1
- package/dist/src/watchers/define_config.js +13 -0
- package/dist/src/watchers/define_config.js.map +1 -1
- package/dist/src/watchers/events_watcher.d.ts +63 -0
- package/dist/src/watchers/events_watcher.d.ts.map +1 -0
- package/dist/src/watchers/events_watcher.js +81 -0
- package/dist/src/watchers/events_watcher.js.map +1 -0
- package/dist/src/watchers/index.d.ts +6 -0
- package/dist/src/watchers/index.d.ts.map +1 -1
- package/dist/src/watchers/index.js +6 -0
- package/dist/src/watchers/index.js.map +1 -1
- package/dist/src/watchers/queue_watcher.d.ts +97 -0
- package/dist/src/watchers/queue_watcher.d.ts.map +1 -0
- package/dist/src/watchers/queue_watcher.js +114 -0
- package/dist/src/watchers/queue_watcher.js.map +1 -0
- package/dist/src/watchers/redis_watcher.d.ts +103 -0
- package/dist/src/watchers/redis_watcher.d.ts.map +1 -0
- package/dist/src/watchers/redis_watcher.js +161 -0
- package/dist/src/watchers/redis_watcher.js.map +1 -0
- package/dist/stubs/config/telescope.stub +9 -0
- package/dist/stubs/config/telescope_ui.stub +13 -0
- package/dist/stubs/config/telescope_watchers.stub +14 -3
- package/package.json +8 -8
package/dist/src/ui/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/ui/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4BH;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAC5B,UAAU,GAAG,GAAG,CAAC;IACR,OAAO,GAA2B,EAAE,CAAC;IAC9C,IAAI,GAAY,SAAS,CAAC;IAC1B,IAAI,GAAG,KAAK,CAAC;IAEb,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,KAAa;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,IAAa;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,KAA8B,EAAE,EAChC,UAAkC,EAAE;IAEpC,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;IACrF,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM;QACpB,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;QACZ,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;KAC5C,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/ui/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4BH;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAC5B,UAAU,GAAG,GAAG,CAAC;IACR,OAAO,GAA2B,EAAE,CAAC;IAC9C,IAAI,GAAY,SAAS,CAAC;IAC1B,IAAI,GAAG,KAAK,CAAC;IAEb,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,KAAa;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,IAAa;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAmBD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,IAAa,EAAE,KAAc;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,OAAO,GAAG,MAAM,SAAS,OAAO,MAAM,CAAC;AACzC,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,kBAAkB;IAChC,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,aAAa;IACf,MAAM,GAAa,EAAE,CAAC;IAC/B,MAAM,GAAG,KAAK,CAAC;IACE,aAAa,GAAsB,EAAE,CAAC;IAEvD,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,CAAC,OAAmB;QACzB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,gFAAgF;IAChF,KAAK;QACH,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;IAChE,CAAC;CACF;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,KAA8B,EAAE,EAChC,UAAkC,EAAE;IAEpC,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;IACrF,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM;QACpB,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;QACZ,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;KAC5C,CAAC;AACJ,CAAC"}
|
package/dist/src/ui/index.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/** Keep in sync with this package's `version` in package.json. */
|
|
2
2
|
export declare const VERSION = "0.1.0";
|
|
3
3
|
export { defineConfig, resolveConfig, normalizePath, defaultAuthorize } from './define_config.js';
|
|
4
|
-
export type { AuthorizeHook, ResolvedTelescopeUiConfig, TelescopeUiConfig, UiCredentials, } from './define_config.js';
|
|
5
|
-
export { RecordingResponse, makeRequest } from './http.js';
|
|
6
|
-
export type { UiHttpContext, UiRequest, UiResponse } from './http.js';
|
|
4
|
+
export type { AuthorizeHook, ReplayConfig, ResolvedTelescopeUiConfig, TelescopeUiConfig, UiCredentials, } from './define_config.js';
|
|
5
|
+
export { RecordingResponse, RecordingSink, formatSseFrame, formatSseHeartbeat, makeRequest, } from './http.js';
|
|
6
|
+
export type { SseSink, UiHttpContext, UiRequest, UiResponse } from './http.js';
|
|
7
7
|
export { enforceGuard, runGuard } from './guard.js';
|
|
8
8
|
export type { GuardResult } from './guard.js';
|
|
9
9
|
export { TelescopeApi, buildQuery, toSummary } from './api.js';
|
|
10
10
|
export type { EntrySummary } from './api.js';
|
|
11
|
+
export { replayRequest, REPLAY_BODY_CAP, REPLAY_STRIPPED_HEADERS, REPLAY_TIMEOUT_MS, } from './request_replay.js';
|
|
12
|
+
export type { ReplayOptions, ReplayResult, ReplayTransport } from './request_replay.js';
|
|
11
13
|
export { renderDashboard } from './dashboard.js';
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClG,YAAY,EACV,aAAa,EACb,yBAAyB,EACzB,iBAAiB,EACjB,aAAa,GACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClG,YAAY,EACV,aAAa,EACb,YAAY,EACZ,yBAAyB,EACzB,iBAAiB,EACjB,aAAa,GACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,WAAW,GACZ,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAG/E,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC/D,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,EACL,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGxF,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/src/ui/index.js
CHANGED
|
@@ -3,11 +3,13 @@ export const VERSION = '0.1.0';
|
|
|
3
3
|
// — config —
|
|
4
4
|
export { defineConfig, resolveConfig, normalizePath, defaultAuthorize } from './define_config.js';
|
|
5
5
|
// — HTTP shapes (framework-light) —
|
|
6
|
-
export { RecordingResponse, makeRequest } from './http.js';
|
|
6
|
+
export { RecordingResponse, RecordingSink, formatSseFrame, formatSseHeartbeat, makeRequest, } from './http.js';
|
|
7
7
|
// — auth guard —
|
|
8
8
|
export { enforceGuard, runGuard } from './guard.js';
|
|
9
9
|
// — JSON API —
|
|
10
10
|
export { TelescopeApi, buildQuery, toSummary } from './api.js';
|
|
11
|
+
// — request replay —
|
|
12
|
+
export { replayRequest, REPLAY_BODY_CAP, REPLAY_STRIPPED_HEADERS, REPLAY_TIMEOUT_MS, } from './request_replay.js';
|
|
11
13
|
// — dashboard —
|
|
12
14
|
export { renderDashboard } from './dashboard.js';
|
|
13
15
|
//# sourceMappingURL=index.js.map
|
package/dist/src/ui/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AASlG,oCAAoC;AACpC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,WAAW,GACZ,MAAM,WAAW,CAAC;AAGnB,iBAAiB;AACjB,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGpD,eAAe;AACf,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG/D,qBAAqB;AACrB,OAAO,EACL,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAG7B,gBAAgB;AAChB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { RequestEntryContent } from '../request_watcher.js';
|
|
2
|
+
/** A minimal `fetch`-shaped transport, injectable so tests don't hit the network. */
|
|
3
|
+
export type ReplayTransport = (url: string, init: {
|
|
4
|
+
method: string;
|
|
5
|
+
headers: Record<string, string>;
|
|
6
|
+
body?: string;
|
|
7
|
+
signal: AbortSignal;
|
|
8
|
+
redirect: 'manual';
|
|
9
|
+
}) => Promise<{
|
|
10
|
+
status: number;
|
|
11
|
+
text(): Promise<string>;
|
|
12
|
+
}>;
|
|
13
|
+
/** Options for {@link replayRequest} (all injectable for tests). */
|
|
14
|
+
export interface ReplayOptions {
|
|
15
|
+
/** Transport used to re-issue the call. Defaults to the global `fetch`,
|
|
16
|
+
* marked internal so the http-client watcher skips it. */
|
|
17
|
+
transport?: ReplayTransport;
|
|
18
|
+
/** The local server port to target. Defaults to `PORT` env or 3000. */
|
|
19
|
+
port?: number;
|
|
20
|
+
/** Per-call timeout in ms. Default {@link REPLAY_TIMEOUT_MS}. */
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
/** Time source; injectable for tests. Default `Date.now`. */
|
|
23
|
+
clock?: {
|
|
24
|
+
now(): number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** Outcome of a request replay. */
|
|
28
|
+
export interface ReplayResult {
|
|
29
|
+
/** HTTP status of the replayed response, or `0` when the call never completed. */
|
|
30
|
+
status: number;
|
|
31
|
+
/** Wall-clock duration of the replay in ms. */
|
|
32
|
+
durationMs: number;
|
|
33
|
+
/** The response body, capped at {@link REPLAY_BODY_CAP} bytes. */
|
|
34
|
+
body: string;
|
|
35
|
+
/** Present when the replay failed to complete (timeout / network error). */
|
|
36
|
+
error?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Default per-call timeout for a replay (30s). */
|
|
39
|
+
export declare const REPLAY_TIMEOUT_MS = 30000;
|
|
40
|
+
/** Max bytes of the replayed response body returned (4 KB). */
|
|
41
|
+
export declare const REPLAY_BODY_CAP = 4096;
|
|
42
|
+
/** Headers stripped from the replayed request (auth/session/routing leakage). */
|
|
43
|
+
export declare const REPLAY_STRIPPED_HEADERS: Set<string>;
|
|
44
|
+
/**
|
|
45
|
+
* Re-issue a captured `request` entry against the LOCAL server (127.0.0.1:<port>)
|
|
46
|
+
* so a developer can reproduce it from the dashboard.
|
|
47
|
+
*
|
|
48
|
+
* The Adonis `request` watcher only captures `method` + `url` (path), so the
|
|
49
|
+
* replay reconstructs exactly that: a GET-style call to the same local path. The
|
|
50
|
+
* call carries `x-telescope-replay: 1`, strips cookie/authorization/host headers
|
|
51
|
+
* (see the SAFETY POSTURE at the top of this file), is bounded by a timeout, and
|
|
52
|
+
* caps the returned body at 4 KB. Never throws — a failed call returns
|
|
53
|
+
* `status: 0` with an `error`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function replayRequest(content: RequestEntryContent, options?: ReplayOptions): Promise<ReplayResult>;
|
|
56
|
+
//# sourceMappingURL=request_replay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request_replay.d.ts","sourceRoot":"","sources":["../../../src/ui/request_replay.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,qFAAqF;AACrF,MAAM,MAAM,eAAe,GAAG,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IACJ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;CACpB,KACE,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAE1D,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B;+DAC2D;IAC3D,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,KAAK,CAAC,EAAE;QAAE,GAAG,IAAI,MAAM,CAAA;KAAE,CAAC;CAC3B;AAED,mCAAmC;AACnC,MAAM,WAAW,YAAY;IAC3B,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,QAAS,CAAC;AACxC,+DAA+D;AAC/D,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,aAKlC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,mBAAmB,EAC5B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAqCvB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// packages/core/src/ui/request_replay.ts
|
|
2
|
+
//
|
|
3
|
+
// Request REPLAY subsystem: re-issue a captured `request` entry against the LOCAL
|
|
4
|
+
// server so a developer can reproduce it from the dashboard. Ported from the
|
|
5
|
+
// NestJS `nestjs-telescope` `nest/request-replay.ts` (the source of truth) and
|
|
6
|
+
// adapted to the Adonis telescope data model and outbound-fetch conventions.
|
|
7
|
+
//
|
|
8
|
+
// SAFETY POSTURE (read before changing anything here):
|
|
9
|
+
// - DISABLED BY DEFAULT. Replaying re-issues a real request that may MUTATE
|
|
10
|
+
// application state (a captured `POST`/`DELETE` will run again), so the host
|
|
11
|
+
// must opt in via `config/telescope_ui.ts` → `replay: { enabled: true }`.
|
|
12
|
+
// This mirrors the NestJS original, which gates replay behind a default-deny
|
|
13
|
+
// `authorizeAction` mutation gate. A disabled replay never issues a call.
|
|
14
|
+
// - SAME-ORIGIN ONLY. The replay always targets `127.0.0.1:<port>` (the local
|
|
15
|
+
// server) — never an arbitrary URL — so it can't be turned into an SSRF
|
|
16
|
+
// primitive against internal services. Only the captured PATH is reused.
|
|
17
|
+
// - CREDENTIAL STRIPPING. `cookie` / `authorization` / `host` / `content-length`
|
|
18
|
+
// are stripped (see {@link REPLAY_STRIPPED_HEADERS}): a replay must not
|
|
19
|
+
// silently reuse the original caller's credentials or session.
|
|
20
|
+
// - SELF-IDENTIFYING. The replay carries `x-telescope-replay: 1` so the host
|
|
21
|
+
// can recognize/skip it, and the outbound fetch is marked internal so the
|
|
22
|
+
// http-client watcher never records (or recurses on) it.
|
|
23
|
+
// - BOUNDED. A 30s timeout and a 4 KB response-body cap; never throws — a
|
|
24
|
+
// failed call resolves to `status: 0` with an `error`.
|
|
25
|
+
//
|
|
26
|
+
// REDACTION / CAPTURED-DATA LIMITATION:
|
|
27
|
+
// The Adonis `request` watcher records only `method` + `url` (path, no query
|
|
28
|
+
// string), `status` and timing — it deliberately does NOT capture request
|
|
29
|
+
// headers or the request body (the NestJS original captured `headers`/`payload`
|
|
30
|
+
// and so could replay them; this port has no such fields to replay). A stored
|
|
31
|
+
// entry's `content` is also run through telescope's redaction before
|
|
32
|
+
// persistence, so even where a value exists it may be `[REDACTED]`. We therefore
|
|
33
|
+
// reconstruct only what is safe and present (method + path) and NEVER forward a
|
|
34
|
+
// redacted value upstream — there is nothing to leak.
|
|
35
|
+
/** Default per-call timeout for a replay (30s). */
|
|
36
|
+
export const REPLAY_TIMEOUT_MS = 30_000;
|
|
37
|
+
/** Max bytes of the replayed response body returned (4 KB). */
|
|
38
|
+
export const REPLAY_BODY_CAP = 4096;
|
|
39
|
+
/** Headers stripped from the replayed request (auth/session/routing leakage). */
|
|
40
|
+
export const REPLAY_STRIPPED_HEADERS = new Set([
|
|
41
|
+
'cookie',
|
|
42
|
+
'authorization',
|
|
43
|
+
'host',
|
|
44
|
+
'content-length',
|
|
45
|
+
]);
|
|
46
|
+
/**
|
|
47
|
+
* Re-issue a captured `request` entry against the LOCAL server (127.0.0.1:<port>)
|
|
48
|
+
* so a developer can reproduce it from the dashboard.
|
|
49
|
+
*
|
|
50
|
+
* The Adonis `request` watcher only captures `method` + `url` (path), so the
|
|
51
|
+
* replay reconstructs exactly that: a GET-style call to the same local path. The
|
|
52
|
+
* call carries `x-telescope-replay: 1`, strips cookie/authorization/host headers
|
|
53
|
+
* (see the SAFETY POSTURE at the top of this file), is bounded by a timeout, and
|
|
54
|
+
* caps the returned body at 4 KB. Never throws — a failed call returns
|
|
55
|
+
* `status: 0` with an `error`.
|
|
56
|
+
*/
|
|
57
|
+
export async function replayRequest(content, options = {}) {
|
|
58
|
+
const transport = options.transport ?? defaultTransport;
|
|
59
|
+
const clock = options.clock ?? { now: () => Date.now() };
|
|
60
|
+
const timeoutMs = options.timeoutMs ?? REPLAY_TIMEOUT_MS;
|
|
61
|
+
const port = resolvePort(options.port);
|
|
62
|
+
const path = content.url.startsWith('/') ? content.url : `/${content.url}`;
|
|
63
|
+
const url = `http://127.0.0.1:${port}${path}`;
|
|
64
|
+
const headers = buildReplayHeaders();
|
|
65
|
+
const method = (content.method || 'GET').toUpperCase();
|
|
66
|
+
const controller = new AbortController();
|
|
67
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
68
|
+
const startedAt = clock.now();
|
|
69
|
+
try {
|
|
70
|
+
const response = await transport(url, {
|
|
71
|
+
method,
|
|
72
|
+
headers,
|
|
73
|
+
signal: controller.signal,
|
|
74
|
+
redirect: 'manual',
|
|
75
|
+
});
|
|
76
|
+
const text = await response.text();
|
|
77
|
+
return {
|
|
78
|
+
status: response.status,
|
|
79
|
+
durationMs: clock.now() - startedAt,
|
|
80
|
+
body: text.slice(0, REPLAY_BODY_CAP),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
return {
|
|
85
|
+
status: 0,
|
|
86
|
+
durationMs: clock.now() - startedAt,
|
|
87
|
+
body: '',
|
|
88
|
+
error: error instanceof Error ? error.message : String(error),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
clearTimeout(timer);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Build the replay request headers. Because the Adonis watcher captures no
|
|
97
|
+
* request headers, there is nothing to copy (and so nothing to leak) — we only
|
|
98
|
+
* force the self-identifying `x-telescope-replay: 1` marker. The
|
|
99
|
+
* {@link REPLAY_STRIPPED_HEADERS} set is documented/exported so the safety
|
|
100
|
+
* contract is explicit and unit-testable even though no source headers exist.
|
|
101
|
+
*/
|
|
102
|
+
function buildReplayHeaders() {
|
|
103
|
+
return { 'x-telescope-replay': '1' };
|
|
104
|
+
}
|
|
105
|
+
/** Resolve the local server port: explicit override, then `PORT` env, then 3000. */
|
|
106
|
+
function resolvePort(explicit) {
|
|
107
|
+
if (typeof explicit === 'number' && Number.isFinite(explicit) && explicit > 0) {
|
|
108
|
+
return explicit;
|
|
109
|
+
}
|
|
110
|
+
const envPort = Number(process.env.PORT);
|
|
111
|
+
return Number.isFinite(envPort) && envPort > 0 ? envPort : 3000;
|
|
112
|
+
}
|
|
113
|
+
/** The default transport: the global `fetch`, marked internal so the http-client
|
|
114
|
+
* watcher never records (or recurses on) the replay call. */
|
|
115
|
+
const defaultTransport = (url, init) => fetch(url, { ...init, [INTERNAL]: true });
|
|
116
|
+
/** Mirror of `markInternalFetch`'s marker (`@agora/telescope:internalFetch`) so a
|
|
117
|
+
* replay's outbound fetch is skipped by the http-client watcher without creating
|
|
118
|
+
* a hard import cycle through the watcher module. */
|
|
119
|
+
const INTERNAL = Symbol.for('@agora/telescope:internalFetch');
|
|
120
|
+
//# sourceMappingURL=request_replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request_replay.js","sourceRoot":"","sources":["../../../src/ui/request_replay.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NOTE — no `'schedule'` watcher is shipped, intentionally. The NestJS original
|
|
3
|
+
* (`@dudousxd/nestjs-telescope`'s schedule package) wraps `@nestjs/schedule`'s
|
|
4
|
+
* `@Cron`/`@Interval`/`@Timeout` decorators via its `SchedulerRegistry`. AdonisJS
|
|
5
|
+
* has NO first-party scheduler, and the popular community schedulers
|
|
6
|
+
* (`adonisjs-scheduler` et al.) emit nothing on the app emitter and expose no
|
|
7
|
+
* lifecycle hooks — so a generic schedule watcher could only be built by inventing
|
|
8
|
+
* /wrapping a private API. It is therefore deliberately omitted. In the Agora
|
|
9
|
+
* ecosystem, `@adonis-agora/durable` already bridges its scheduled/cron + workflow
|
|
10
|
+
* run events onto the diagnostics bus, which the generic {@link DiagnosticsWatcher}
|
|
11
|
+
* records — so scheduled-run observability is covered there, not by a bespoke
|
|
12
|
+
* schedule watcher.
|
|
13
|
+
*/
|
|
1
14
|
/** The per-technology watchers this package ships. */
|
|
2
|
-
export type WatcherName = 'query' | 'mail' | 'cache' | 'http-client' | 'logs';
|
|
15
|
+
export type WatcherName = 'query' | 'mail' | 'cache' | 'http-client' | 'logs' | 'queue' | 'events' | 'redis';
|
|
3
16
|
/**
|
|
4
17
|
* The shape of `config/telescope_watchers.ts`. Everything is optional: by default
|
|
5
18
|
* only the Lucid `query` watcher is enabled (it is the one whose events are
|
|
@@ -18,6 +31,9 @@ export interface TelescopeWatchersConfig {
|
|
|
18
31
|
* - `'cache'` — records `@adonisjs/cache` hit/miss/write/delete events.
|
|
19
32
|
* - `'http-client'` — records every outbound `fetch` call.
|
|
20
33
|
* - `'logs'` — records AdonisJS logger output as `log` entries.
|
|
34
|
+
* - `'queue'` — records `@adonisjs/queue` job executions (optional peer).
|
|
35
|
+
* - `'events'` — records every event emitted through the core Emitter.
|
|
36
|
+
* - `'redis'` — records `@adonisjs/redis` commands (optional peer).
|
|
21
37
|
*/
|
|
22
38
|
watchers?: WatcherName[];
|
|
23
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../../src/watchers/define_config.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,MAAM,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../../src/watchers/define_config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,sDAAsD;AACtD,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,MAAM,GACN,OAAO,GACP,aAAa,GACb,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,CAAC;AAEZ;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,8EAA8E;AAC9E,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;CAC5B;AAED,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,EAAE,WAAW,EAAc,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,uBAAuB,GAAG,uBAAuB,CAErF;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAC3B,MAAM,GAAE,uBAA4B,GACnC,+BAA+B,CAKjC"}
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NOTE — no `'schedule'` watcher is shipped, intentionally. The NestJS original
|
|
3
|
+
* (`@dudousxd/nestjs-telescope`'s schedule package) wraps `@nestjs/schedule`'s
|
|
4
|
+
* `@Cron`/`@Interval`/`@Timeout` decorators via its `SchedulerRegistry`. AdonisJS
|
|
5
|
+
* has NO first-party scheduler, and the popular community schedulers
|
|
6
|
+
* (`adonisjs-scheduler` et al.) emit nothing on the app emitter and expose no
|
|
7
|
+
* lifecycle hooks — so a generic schedule watcher could only be built by inventing
|
|
8
|
+
* /wrapping a private API. It is therefore deliberately omitted. In the Agora
|
|
9
|
+
* ecosystem, `@adonis-agora/durable` already bridges its scheduled/cron + workflow
|
|
10
|
+
* run events onto the diagnostics bus, which the generic {@link DiagnosticsWatcher}
|
|
11
|
+
* records — so scheduled-run observability is covered there, not by a bespoke
|
|
12
|
+
* schedule watcher.
|
|
13
|
+
*/
|
|
1
14
|
/** The default set of enabled watchers — the verified Lucid query watcher only. */
|
|
2
15
|
export const DEFAULT_WATCHERS = ['query'];
|
|
3
16
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../../src/watchers/define_config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../../src/watchers/define_config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA6CH,mFAAmF;AACnF,MAAM,CAAC,MAAM,gBAAgB,GAAkB,CAAC,OAAO,CAAC,CAAC;AAEzD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAA+B;IAC1D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,aAAa,CAC3B,SAAkC,EAAE;IAEpC,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;QAC/B,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,gBAAgB,CAAC;KACvD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type RecordInput } from '../entry.js';
|
|
2
|
+
/**
|
|
3
|
+
* The narrow structural slice of the `@adonisjs/core` Emitter this watcher needs:
|
|
4
|
+
* `onAny(listener)` to observe EVERY emitted event, returning an unsubscribe
|
|
5
|
+
* function (the exact contract `@adonisjs/events` ships — its emitter, built on
|
|
6
|
+
* `emittery`, returns `() => void` from `onAny`). Mirrored structurally rather than
|
|
7
|
+
* imported so the watcher stays unit-testable with a plain double and carries no
|
|
8
|
+
* build-time coupling to a specific emitter version.
|
|
9
|
+
*
|
|
10
|
+
* The listener receives `(event, data)`: the event NAME (a string, or a class
|
|
11
|
+
* constructor for class-based events) and the single emitted payload.
|
|
12
|
+
*/
|
|
13
|
+
export interface EmitterAnyLike {
|
|
14
|
+
onAny(listener: (event: unknown, data: unknown) => unknown): () => void;
|
|
15
|
+
}
|
|
16
|
+
/** Narrow an arbitrary resolved provider to one with a usable `onAny`. */
|
|
17
|
+
export declare function hasOnAny(value: unknown): value is EmitterAnyLike;
|
|
18
|
+
/** The recorded body of an `event` entry. */
|
|
19
|
+
export interface EventEntryContent {
|
|
20
|
+
/** The emitted event name (string events) or class name (class-based events). */
|
|
21
|
+
name: string;
|
|
22
|
+
/** The single emitted payload, recorded as-is (redaction applies downstream). */
|
|
23
|
+
payload: unknown;
|
|
24
|
+
/** The active trace id at emit time, or `null`. */
|
|
25
|
+
traceId: string | null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Captures EVERY event emitted through the core `@adonisjs/core` Emitter and
|
|
29
|
+
* records one `event` telescope entry per emit — the name and payload — correlated
|
|
30
|
+
* to the active request via the trace id. It attaches a single wildcard listener
|
|
31
|
+
* via `emitter.onAny(...)`.
|
|
32
|
+
*
|
|
33
|
+
* An ignore-list (constructor option, matched against the resolved event name)
|
|
34
|
+
* filters out noisy or already-watched events — e.g. `'db:query'` (the Lucid query
|
|
35
|
+
* watcher already records those) or `'mail:sent'`. Mirrors the filtering of the
|
|
36
|
+
* NestJS `EventsWatcher` original.
|
|
37
|
+
*
|
|
38
|
+
* Recording is fire-and-forget and fully guarded: a telescope failure can never
|
|
39
|
+
* break or block an emit.
|
|
40
|
+
*/
|
|
41
|
+
export declare class EventsWatcher {
|
|
42
|
+
readonly type: "event";
|
|
43
|
+
private readonly ignore;
|
|
44
|
+
private unsubscribe;
|
|
45
|
+
constructor(ignore?: string[]);
|
|
46
|
+
/**
|
|
47
|
+
* Begin recording. A no-op when the emitter has no `onAny` (degrades gracefully
|
|
48
|
+
* rather than throwing). Idempotent: a second call is ignored.
|
|
49
|
+
*/
|
|
50
|
+
start(emitter: unknown): void;
|
|
51
|
+
/** Detach the wildcard listener. Safe to call when never started. */
|
|
52
|
+
stop(): void;
|
|
53
|
+
private handle;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The events the watcher ignores by default. These are emitted by Adonis surfaces
|
|
57
|
+
* that already have a dedicated telescope watcher, so capturing them here would
|
|
58
|
+
* double-record. A host can override the set via the constructor.
|
|
59
|
+
*/
|
|
60
|
+
export declare const DEFAULT_IGNORED_EVENTS: string[];
|
|
61
|
+
/** Map an emitted event name + payload to a telescope {@link RecordInput}. */
|
|
62
|
+
export declare function buildEventEntry(name: string, payload: unknown): RecordInput<EventEntryContent>;
|
|
63
|
+
//# sourceMappingURL=events_watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events_watcher.d.ts","sourceRoot":"","sources":["../../../src/watchers/events_watcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1D;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,GAAG,MAAM,IAAI,CAAC;CACzE;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAMhE;AAED,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,OAAO,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAWD;;;;;;;;;;;;;GAaG;AACH,qBAAa,aAAa;IACxB,QAAQ,CAAC,IAAI,UAAmB;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,WAAW,CAA6B;gBAEpC,MAAM,GAAE,MAAM,EAA2B;IAIrD;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAM7B,qEAAqE;IACrE,IAAI,IAAI,IAAI;IAKZ,OAAO,CAAC,MAAM;CAKf;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,EAA8B,CAAC;AAE1E,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAU9F"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { currentTraceId } from '../context_accessor.js';
|
|
2
|
+
import { EntryType } from '../entry.js';
|
|
3
|
+
import { safeRecord } from './record.js';
|
|
4
|
+
/** Narrow an arbitrary resolved provider to one with a usable `onAny`. */
|
|
5
|
+
export function hasOnAny(value) {
|
|
6
|
+
return (typeof value === 'object' &&
|
|
7
|
+
value !== null &&
|
|
8
|
+
typeof value.onAny === 'function');
|
|
9
|
+
}
|
|
10
|
+
/** Coerce an Adonis event identifier (string, or a class constructor) to a name. */
|
|
11
|
+
function eventName(event) {
|
|
12
|
+
if (typeof event === 'string')
|
|
13
|
+
return event;
|
|
14
|
+
if (typeof event === 'function' && typeof event.name === 'string' && event.name) {
|
|
15
|
+
return event.name;
|
|
16
|
+
}
|
|
17
|
+
return String(event);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Captures EVERY event emitted through the core `@adonisjs/core` Emitter and
|
|
21
|
+
* records one `event` telescope entry per emit — the name and payload — correlated
|
|
22
|
+
* to the active request via the trace id. It attaches a single wildcard listener
|
|
23
|
+
* via `emitter.onAny(...)`.
|
|
24
|
+
*
|
|
25
|
+
* An ignore-list (constructor option, matched against the resolved event name)
|
|
26
|
+
* filters out noisy or already-watched events — e.g. `'db:query'` (the Lucid query
|
|
27
|
+
* watcher already records those) or `'mail:sent'`. Mirrors the filtering of the
|
|
28
|
+
* NestJS `EventsWatcher` original.
|
|
29
|
+
*
|
|
30
|
+
* Recording is fire-and-forget and fully guarded: a telescope failure can never
|
|
31
|
+
* break or block an emit.
|
|
32
|
+
*/
|
|
33
|
+
export class EventsWatcher {
|
|
34
|
+
type = EntryType.Event;
|
|
35
|
+
ignore;
|
|
36
|
+
unsubscribe = null;
|
|
37
|
+
constructor(ignore = DEFAULT_IGNORED_EVENTS) {
|
|
38
|
+
this.ignore = new Set(ignore);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Begin recording. A no-op when the emitter has no `onAny` (degrades gracefully
|
|
42
|
+
* rather than throwing). Idempotent: a second call is ignored.
|
|
43
|
+
*/
|
|
44
|
+
start(emitter) {
|
|
45
|
+
if (this.unsubscribe)
|
|
46
|
+
return;
|
|
47
|
+
if (!hasOnAny(emitter))
|
|
48
|
+
return;
|
|
49
|
+
this.unsubscribe = emitter.onAny((event, data) => this.handle(event, data));
|
|
50
|
+
}
|
|
51
|
+
/** Detach the wildcard listener. Safe to call when never started. */
|
|
52
|
+
stop() {
|
|
53
|
+
this.unsubscribe?.();
|
|
54
|
+
this.unsubscribe = null;
|
|
55
|
+
}
|
|
56
|
+
handle(event, data) {
|
|
57
|
+
const name = eventName(event);
|
|
58
|
+
if (this.ignore.has(name))
|
|
59
|
+
return;
|
|
60
|
+
safeRecord(buildEventEntry(name, data), 'EventsWatcher');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The events the watcher ignores by default. These are emitted by Adonis surfaces
|
|
65
|
+
* that already have a dedicated telescope watcher, so capturing them here would
|
|
66
|
+
* double-record. A host can override the set via the constructor.
|
|
67
|
+
*/
|
|
68
|
+
export const DEFAULT_IGNORED_EVENTS = ['db:query', 'mail:sent'];
|
|
69
|
+
/** Map an emitted event name + payload to a telescope {@link RecordInput}. */
|
|
70
|
+
export function buildEventEntry(name, payload) {
|
|
71
|
+
const traceId = currentTraceId();
|
|
72
|
+
const content = { name, payload, traceId };
|
|
73
|
+
return {
|
|
74
|
+
type: EntryType.Event,
|
|
75
|
+
familyHash: `event:${name}`,
|
|
76
|
+
content,
|
|
77
|
+
traceId,
|
|
78
|
+
tags: ['event', `event:${name}`],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=events_watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events_watcher.js","sourceRoot":"","sources":["../../../src/watchers/events_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiBzC,0EAA0E;AAC1E,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,OAAQ,KAA6B,CAAC,KAAK,KAAK,UAAU,CAC3D,CAAC;AACJ,CAAC;AAYD,oFAAoF;AACpF,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,OAAO,KAAK,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAChF,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,aAAa;IACf,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC;IACf,MAAM,CAAc;IAC7B,WAAW,GAAwB,IAAI,CAAC;IAEhD,YAAY,SAAmB,sBAAsB;QACnD,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAgB;QACpB,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO;QAC/B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,qEAAqE;IACrE,IAAI;QACF,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;IAEO,MAAM,CAAC,KAAc,EAAE,IAAa;QAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO;QAClC,UAAU,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,eAAe,CAAC,CAAC;IAC3D,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAa,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAE1E,8EAA8E;AAC9E,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,OAAgB;IAC5D,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,OAAO,GAAsB,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAC9D,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,KAAK;QACrB,UAAU,EAAE,SAAS,IAAI,EAAE;QAC3B,OAAO;QACP,OAAO;QACP,IAAI,EAAE,CAAC,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC;KACjC,CAAC;AACJ,CAAC"}
|
|
@@ -14,6 +14,12 @@ export type { HttpClientEntryContent, HttpClientWatcherOptions, } from './http_c
|
|
|
14
14
|
export { normalizeHttpTarget } from './normalize_http_target.js';
|
|
15
15
|
export { buildLogEntry, extractLog, LOG_LEVELS, LogsWatcher } from './logs_watcher.js';
|
|
16
16
|
export type { LogEntryContent, LoggerLike, LogLevel, LogsWatcherOptions, } from './logs_watcher.js';
|
|
17
|
+
export { buildJobEntry, QUEUE_EXECUTE_CHANNEL, QueueWatcher } from './queue_watcher.js';
|
|
18
|
+
export type { AcquiredJobLike, JobEntryContent, JobExecuteMessageLike, JobStatus, QueueWatcherOptions, } from './queue_watcher.js';
|
|
19
|
+
export { buildEventEntry, DEFAULT_IGNORED_EVENTS, EventsWatcher, hasOnAny, } from './events_watcher.js';
|
|
20
|
+
export type { EmitterAnyLike, EventEntryContent } from './events_watcher.js';
|
|
21
|
+
export { buildRedisEntry, RedisWatcher } from './redis_watcher.js';
|
|
22
|
+
export type { RedisClientLike, RedisCommandLike, RedisConnectionLike, RedisEntryContent, RedisManagerLike, } from './redis_watcher.js';
|
|
17
23
|
export { DEFAULT_WATCHERS, defineConfig, resolveConfig, } from './define_config.js';
|
|
18
24
|
export type { ResolvedTelescopeWatchersConfig, TelescopeWatchersConfig, WatcherName, } from './define_config.js';
|
|
19
25
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/watchers/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC9F,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACjF,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG7E,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjF,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAG5F,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGjE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACvF,YAAY,EACV,eAAe,EACf,UAAU,EACV,QAAQ,EACR,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,+BAA+B,EAC/B,uBAAuB,EACvB,WAAW,GACZ,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/watchers/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC9F,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACjF,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG7E,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjF,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAG5F,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGjE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACvF,YAAY,EACV,eAAe,EACf,UAAU,EACV,QAAQ,EACR,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxF,YAAY,EACV,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAG7E,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnE,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,+BAA+B,EAC/B,uBAAuB,EACvB,WAAW,GACZ,MAAM,oBAAoB,CAAC"}
|
|
@@ -14,6 +14,12 @@ export { buildHttpClientEntry, HttpClientWatcher, markInternalFetch, } from './h
|
|
|
14
14
|
export { normalizeHttpTarget } from './normalize_http_target.js';
|
|
15
15
|
// — logs watcher —
|
|
16
16
|
export { buildLogEntry, extractLog, LOG_LEVELS, LogsWatcher } from './logs_watcher.js';
|
|
17
|
+
// — queue/jobs watcher (optional peer: @adonisjs/queue) —
|
|
18
|
+
export { buildJobEntry, QUEUE_EXECUTE_CHANNEL, QueueWatcher } from './queue_watcher.js';
|
|
19
|
+
// — events watcher (core @adonisjs/core Emitter) —
|
|
20
|
+
export { buildEventEntry, DEFAULT_IGNORED_EVENTS, EventsWatcher, hasOnAny, } from './events_watcher.js';
|
|
21
|
+
// — redis watcher (optional peer: @adonisjs/redis) —
|
|
22
|
+
export { buildRedisEntry, RedisWatcher } from './redis_watcher.js';
|
|
17
23
|
// — config —
|
|
18
24
|
export { DEFAULT_WATCHERS, defineConfig, resolveConfig, } from './define_config.js';
|
|
19
25
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/watchers/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAK/B,mCAAmC;AACnC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvD,iDAAiD;AACjD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE9F,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,mBAAmB;AACnB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGjF,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGjF,qCAAqC;AACrC,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,mBAAmB;AACnB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQvF,aAAa;AACb,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/watchers/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAK/B,mCAAmC;AACnC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvD,iDAAiD;AACjD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE9F,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,mBAAmB;AACnB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGjF,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGjF,qCAAqC;AACrC,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,mBAAmB;AACnB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQvF,0DAA0D;AAC1D,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AASxF,mDAAmD;AACnD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAG7B,qDAAqD;AACrD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AASnE,aAAa;AACb,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type RecordInput } from '../entry.js';
|
|
2
|
+
/**
|
|
3
|
+
* The `node:diagnostics_channel` tracing channel `@boringnode/queue` (the engine
|
|
4
|
+
* behind the OPTIONAL peer `@adonisjs/queue`) publishes a job EXECUTION trace on.
|
|
5
|
+
* A tracing channel fires the sub-channels `<name>:start`, `:end`, `:asyncStart`,
|
|
6
|
+
* `:asyncEnd`, and `:error` around the traced async operation; we read the outcome
|
|
7
|
+
* off `:asyncEnd` (status/duration/error are mutated onto the same message during
|
|
8
|
+
* the trace's async lifecycle).
|
|
9
|
+
*
|
|
10
|
+
* `@adonisjs/queue` is not installed in this repo, so this channel name + payload
|
|
11
|
+
* shape are sourced from the engine's `src/tracing_channels.ts` rather than
|
|
12
|
+
* verified against installed types (the engine is pre-1.0, so this surface can
|
|
13
|
+
* drift). The watcher degrades to a pure no-op when nobody publishes on the
|
|
14
|
+
* channel — i.e. when the peer is absent.
|
|
15
|
+
*/
|
|
16
|
+
export declare const QUEUE_EXECUTE_CHANNEL = "boringqueue.job.execute";
|
|
17
|
+
/** The terminal outcome of a single job execution attempt. */
|
|
18
|
+
export type JobStatus = 'completed' | 'failed' | 'retrying';
|
|
19
|
+
/**
|
|
20
|
+
* The structural slice of a single acquired job, as `@boringnode/queue` shapes it
|
|
21
|
+
* (`AcquiredJob`). Read defensively (every field optional) — the exact runtime
|
|
22
|
+
* shape is owned by the engine and could not be verified here.
|
|
23
|
+
*/
|
|
24
|
+
export interface AcquiredJobLike {
|
|
25
|
+
id?: string;
|
|
26
|
+
name?: string;
|
|
27
|
+
payload?: unknown;
|
|
28
|
+
attempts?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The structural slice of the `boringqueue.job.execute` tracing message read at
|
|
32
|
+
* `:asyncEnd`. `status`, `duration`, and `error` are populated by the engine on the
|
|
33
|
+
* way out of the trace.
|
|
34
|
+
*/
|
|
35
|
+
export interface JobExecuteMessageLike {
|
|
36
|
+
job?: AcquiredJobLike;
|
|
37
|
+
queue?: string;
|
|
38
|
+
status?: JobStatus;
|
|
39
|
+
/** Execution duration in ms, set by the engine on completion. */
|
|
40
|
+
duration?: number;
|
|
41
|
+
error?: unknown;
|
|
42
|
+
}
|
|
43
|
+
/** The recorded body of a `job` entry. */
|
|
44
|
+
export interface JobEntryContent {
|
|
45
|
+
/** The job id, or `null` when the engine did not carry one. */
|
|
46
|
+
id: string | null;
|
|
47
|
+
/** The job class name (e.g. `'SendWelcomeEmail'`), or `null`. */
|
|
48
|
+
name: string | null;
|
|
49
|
+
/** The queue the job ran on (e.g. `'default'`), or `null`. */
|
|
50
|
+
queue: string | null;
|
|
51
|
+
/** The job payload (redaction applies downstream). `null` when absent. */
|
|
52
|
+
payload: unknown;
|
|
53
|
+
/** The execution outcome. */
|
|
54
|
+
status: JobStatus;
|
|
55
|
+
/** How many attempts the job had made, or `null`. */
|
|
56
|
+
attempts: number | null;
|
|
57
|
+
/** The failure message when `status` is `'failed'`/`'retrying'`, else `null`. */
|
|
58
|
+
failureReason: string | null;
|
|
59
|
+
/** The active trace id at execution time, or `null`. */
|
|
60
|
+
traceId: string | null;
|
|
61
|
+
}
|
|
62
|
+
/** Options for {@link QueueWatcher}. */
|
|
63
|
+
export interface QueueWatcherOptions {
|
|
64
|
+
/** Jobs whose execution time is >= this (ms) get a `slow` tag. Default 1000. */
|
|
65
|
+
slowMs?: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Records every `@adonisjs/queue` job EXECUTION as a `job` telescope entry —
|
|
69
|
+
* capturing the queue, job name, payload, outcome (completed/failed/retrying),
|
|
70
|
+
* attempts and duration, correlated to the active trace.
|
|
71
|
+
*
|
|
72
|
+
* ## How it works
|
|
73
|
+
* `@adonisjs/queue`'s engine (`@boringnode/queue`) publishes a
|
|
74
|
+
* `node:diagnostics_channel` TRACING channel per execution attempt
|
|
75
|
+
* ({@link QUEUE_EXECUTE_CHANNEL}). The watcher subscribes to its `:asyncEnd`
|
|
76
|
+
* sub-channel — fired once the execution settles, with `status`/`duration`/`error`
|
|
77
|
+
* populated — and records one entry per attempt. Subscribing is what flips the
|
|
78
|
+
* channel's `hasSubscribers` on; with no publisher (peer absent) it is a no-op.
|
|
79
|
+
*
|
|
80
|
+
* Like the other watchers, recording is fire-and-forget and fully guarded: a
|
|
81
|
+
* telescope failure can never break or block a job.
|
|
82
|
+
*/
|
|
83
|
+
export declare class QueueWatcher {
|
|
84
|
+
readonly type: "job";
|
|
85
|
+
private readonly slowMs;
|
|
86
|
+
private handler;
|
|
87
|
+
constructor(options?: QueueWatcherOptions);
|
|
88
|
+
/** Subscribe to the queue execution trace. Idempotent. */
|
|
89
|
+
start(): void;
|
|
90
|
+
/** Unsubscribe from the queue execution trace. Safe to call when never started. */
|
|
91
|
+
stop(): void;
|
|
92
|
+
private handle;
|
|
93
|
+
}
|
|
94
|
+
/** Map a queue execution message to a telescope {@link RecordInput}. Exported so
|
|
95
|
+
* the entry shape can be unit-tested without a real diagnostics publish. */
|
|
96
|
+
export declare function buildJobEntry(message: JobExecuteMessageLike, slowMs?: number): RecordInput<JobEntryContent>;
|
|
97
|
+
//# sourceMappingURL=queue_watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue_watcher.d.ts","sourceRoot":"","sources":["../../../src/watchers/queue_watcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AAK/D,8DAA8D;AAC9D,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE5D;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,eAAe,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,iEAAiE;IACjE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,MAAM,EAAE,SAAS,CAAC;IAClB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,iFAAiF;IACjF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,wDAAwD;IACxD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,wCAAwC;AACxC,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAUD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,YAAY;IACvB,QAAQ,CAAC,IAAI,QAAiB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,OAAO,CAAyC;gBAE5C,OAAO,GAAE,mBAAwB;IAI7C,0DAA0D;IAC1D,KAAK,IAAI,IAAI;IAOb,mFAAmF;IACnF,IAAI,IAAI,IAAI;IAMZ,OAAO,CAAC,MAAM;CAGf;AAED;6EAC6E;AAC7E,wBAAgB,aAAa,CAC3B,OAAO,EAAE,qBAAqB,EAC9B,MAAM,SAAkB,GACvB,WAAW,CAAC,eAAe,CAAC,CAqC9B"}
|