@adonis-agora/telescope 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +26 -0
- package/dist/configure.d.ts +16 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/configure.js +75 -0
- package/dist/configure.js.map +1 -0
- package/dist/providers/telescope_ai_provider.d.ts +20 -0
- package/dist/providers/telescope_ai_provider.d.ts.map +1 -0
- package/dist/providers/telescope_ai_provider.js +45 -0
- package/dist/providers/telescope_ai_provider.js.map +1 -0
- package/dist/providers/telescope_alerts_provider.d.ts +23 -0
- package/dist/providers/telescope_alerts_provider.d.ts.map +1 -0
- package/dist/providers/telescope_alerts_provider.js +72 -0
- package/dist/providers/telescope_alerts_provider.js.map +1 -0
- package/dist/providers/telescope_provider.d.ts +43 -0
- package/dist/providers/telescope_provider.d.ts.map +1 -0
- package/dist/providers/telescope_provider.js +103 -0
- package/dist/providers/telescope_provider.js.map +1 -0
- package/dist/providers/telescope_ui_provider.d.ts +21 -0
- package/dist/providers/telescope_ui_provider.d.ts.map +1 -0
- package/dist/providers/telescope_ui_provider.js +119 -0
- package/dist/providers/telescope_ui_provider.js.map +1 -0
- package/dist/providers/telescope_watchers_provider.d.ts +31 -0
- package/dist/providers/telescope_watchers_provider.d.ts.map +1 -0
- package/dist/providers/telescope_watchers_provider.js +116 -0
- package/dist/providers/telescope_watchers_provider.js.map +1 -0
- package/dist/src/ai/define_config.d.ts +56 -0
- package/dist/src/ai/define_config.d.ts.map +1 -0
- package/dist/src/ai/define_config.js +39 -0
- package/dist/src/ai/define_config.js.map +1 -0
- package/dist/src/ai/diagnoser.d.ts +34 -0
- package/dist/src/ai/diagnoser.d.ts.map +1 -0
- package/dist/src/ai/diagnoser.js +74 -0
- package/dist/src/ai/diagnoser.js.map +1 -0
- package/dist/src/ai/diagnosis_cache.d.ts +43 -0
- package/dist/src/ai/diagnosis_cache.d.ts.map +1 -0
- package/dist/src/ai/diagnosis_cache.js +56 -0
- package/dist/src/ai/diagnosis_cache.js.map +1 -0
- package/dist/src/ai/factory.d.ts +15 -0
- package/dist/src/ai/factory.d.ts.map +1 -0
- package/dist/src/ai/factory.js +24 -0
- package/dist/src/ai/factory.js.map +1 -0
- package/dist/src/ai/index.d.ts +14 -0
- package/dist/src/ai/index.d.ts.map +1 -0
- package/dist/src/ai/index.js +15 -0
- package/dist/src/ai/index.js.map +1 -0
- package/dist/src/ai/prompt.d.ts +31 -0
- package/dist/src/ai/prompt.d.ts.map +1 -0
- package/dist/src/ai/prompt.js +66 -0
- package/dist/src/ai/prompt.js.map +1 -0
- package/dist/src/ai/telescope_ai_diagnoser.d.ts +79 -0
- package/dist/src/ai/telescope_ai_diagnoser.d.ts.map +1 -0
- package/dist/src/ai/telescope_ai_diagnoser.js +111 -0
- package/dist/src/ai/telescope_ai_diagnoser.js.map +1 -0
- package/dist/src/alerts/alert_channel.d.ts +69 -0
- package/dist/src/alerts/alert_channel.d.ts.map +1 -0
- package/dist/src/alerts/alert_channel.js +114 -0
- package/dist/src/alerts/alert_channel.js.map +1 -0
- package/dist/src/alerts/alert_rule.d.ts +86 -0
- package/dist/src/alerts/alert_rule.d.ts.map +1 -0
- package/dist/src/alerts/alert_rule.js +2 -0
- package/dist/src/alerts/alert_rule.js.map +1 -0
- package/dist/src/alerts/alerter.d.ts +72 -0
- package/dist/src/alerts/alerter.d.ts.map +1 -0
- package/dist/src/alerts/alerter.js +248 -0
- package/dist/src/alerts/alerter.js.map +1 -0
- package/dist/src/alerts/define_config.d.ts +68 -0
- package/dist/src/alerts/define_config.d.ts.map +1 -0
- package/dist/src/alerts/define_config.js +57 -0
- package/dist/src/alerts/define_config.js.map +1 -0
- package/dist/src/alerts/exception_source.d.ts +44 -0
- package/dist/src/alerts/exception_source.d.ts.map +1 -0
- package/dist/src/alerts/exception_source.js +79 -0
- package/dist/src/alerts/exception_source.js.map +1 -0
- package/dist/src/alerts/index.d.ts +16 -0
- package/dist/src/alerts/index.d.ts.map +1 -0
- package/dist/src/alerts/index.js +17 -0
- package/dist/src/alerts/index.js.map +1 -0
- package/dist/src/alerts/new_exception_tracker.d.ts +50 -0
- package/dist/src/alerts/new_exception_tracker.d.ts.map +1 -0
- package/dist/src/alerts/new_exception_tracker.js +74 -0
- package/dist/src/alerts/new_exception_tracker.js.map +1 -0
- package/dist/src/alerts/parse_duration.d.ts +10 -0
- package/dist/src/alerts/parse_duration.d.ts.map +1 -0
- package/dist/src/alerts/parse_duration.js +27 -0
- package/dist/src/alerts/parse_duration.js.map +1 -0
- package/dist/src/alerts/slack_format.d.ts +60 -0
- package/dist/src/alerts/slack_format.d.ts.map +1 -0
- package/dist/src/alerts/slack_format.js +122 -0
- package/dist/src/alerts/slack_format.js.map +1 -0
- package/dist/src/context_accessor.d.ts +30 -0
- package/dist/src/context_accessor.d.ts.map +1 -0
- package/dist/src/context_accessor.js +20 -0
- package/dist/src/context_accessor.js.map +1 -0
- package/dist/src/define_config.d.ts +109 -0
- package/dist/src/define_config.d.ts.map +1 -0
- package/dist/src/define_config.js +38 -0
- package/dist/src/define_config.js.map +1 -0
- package/dist/src/diagnostics_registry.d.ts +46 -0
- package/dist/src/diagnostics_registry.d.ts.map +1 -0
- package/dist/src/diagnostics_registry.js +34 -0
- package/dist/src/diagnostics_registry.js.map +1 -0
- package/dist/src/diagnostics_watcher.d.ts +72 -0
- package/dist/src/diagnostics_watcher.d.ts.map +1 -0
- package/dist/src/diagnostics_watcher.js +119 -0
- package/dist/src/diagnostics_watcher.js.map +1 -0
- package/dist/src/entry.d.ts +81 -0
- package/dist/src/entry.d.ts.map +1 -0
- package/dist/src/entry.js +34 -0
- package/dist/src/entry.js.map +1 -0
- package/dist/src/exception_family_hash.d.ts +29 -0
- package/dist/src/exception_family_hash.d.ts.map +1 -0
- package/dist/src/exception_family_hash.js +30 -0
- package/dist/src/exception_family_hash.js.map +1 -0
- package/dist/src/exception_watcher.d.ts +66 -0
- package/dist/src/exception_watcher.d.ts.map +1 -0
- package/dist/src/exception_watcher.js +94 -0
- package/dist/src/exception_watcher.js.map +1 -0
- package/dist/src/extension/registry.d.ts +17 -0
- package/dist/src/extension/registry.d.ts.map +1 -0
- package/dist/src/extension/registry.js +56 -0
- package/dist/src/extension/registry.js.map +1 -0
- package/dist/src/extension/types.d.ts +158 -0
- package/dist/src/extension/types.d.ts.map +1 -0
- package/dist/src/extension/types.js +5 -0
- package/dist/src/extension/types.js.map +1 -0
- package/dist/src/index.d.ts +36 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +28 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/redaction/redact.d.ts +93 -0
- package/dist/src/redaction/redact.d.ts.map +1 -0
- package/dist/src/redaction/redact.js +184 -0
- package/dist/src/redaction/redact.js.map +1 -0
- package/dist/src/redaction/redacting_store.d.ts +28 -0
- package/dist/src/redaction/redacting_store.d.ts.map +1 -0
- package/dist/src/redaction/redacting_store.js +49 -0
- package/dist/src/redaction/redacting_store.js.map +1 -0
- package/dist/src/registry.d.ts +26 -0
- package/dist/src/registry.d.ts.map +1 -0
- package/dist/src/registry.js +28 -0
- package/dist/src/registry.js.map +1 -0
- package/dist/src/request_watcher.d.ts +44 -0
- package/dist/src/request_watcher.d.ts.map +1 -0
- package/dist/src/request_watcher.js +37 -0
- package/dist/src/request_watcher.js.map +1 -0
- package/dist/src/service.d.ts +36 -0
- package/dist/src/service.d.ts.map +1 -0
- package/dist/src/service.js +65 -0
- package/dist/src/service.js.map +1 -0
- package/dist/src/store.d.ts +56 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/store.js +2 -0
- package/dist/src/store.js.map +1 -0
- package/dist/src/stores/factory.d.ts +61 -0
- package/dist/src/stores/factory.d.ts.map +1 -0
- package/dist/src/stores/factory.js +42 -0
- package/dist/src/stores/factory.js.map +1 -0
- package/dist/src/stores/lucid.d.ts +138 -0
- package/dist/src/stores/lucid.d.ts.map +1 -0
- package/dist/src/stores/lucid.js +257 -0
- package/dist/src/stores/lucid.js.map +1 -0
- package/dist/src/stores/memory.d.ts +31 -0
- package/dist/src/stores/memory.d.ts.map +1 -0
- package/dist/src/stores/memory.js +117 -0
- package/dist/src/stores/memory.js.map +1 -0
- package/dist/src/telescope_middleware.d.ts +19 -0
- package/dist/src/telescope_middleware.d.ts.map +1 -0
- package/dist/src/telescope_middleware.js +56 -0
- package/dist/src/telescope_middleware.js.map +1 -0
- package/dist/src/ui/api.d.ts +49 -0
- package/dist/src/ui/api.d.ts.map +1 -0
- package/dist/src/ui/api.js +155 -0
- package/dist/src/ui/api.js.map +1 -0
- package/dist/src/ui/dashboard.d.ts +8 -0
- package/dist/src/ui/dashboard.d.ts.map +1 -0
- package/dist/src/ui/dashboard.html +626 -0
- package/dist/src/ui/dashboard.js +29 -0
- package/dist/src/ui/dashboard.js.map +1 -0
- package/dist/src/ui/define_config.d.ts +87 -0
- package/dist/src/ui/define_config.d.ts.map +1 -0
- package/dist/src/ui/define_config.js +104 -0
- package/dist/src/ui/define_config.js.map +1 -0
- package/dist/src/ui/extension_api.d.ts +23 -0
- package/dist/src/ui/extension_api.d.ts.map +1 -0
- package/dist/src/ui/extension_api.js +50 -0
- package/dist/src/ui/extension_api.js.map +1 -0
- package/dist/src/ui/guard.d.ts +33 -0
- package/dist/src/ui/guard.d.ts.map +1 -0
- package/dist/src/ui/guard.js +47 -0
- package/dist/src/ui/guard.js.map +1 -0
- package/dist/src/ui/http.d.ts +47 -0
- package/dist/src/ui/http.d.ts.map +1 -0
- package/dist/src/ui/http.js +43 -0
- package/dist/src/ui/http.js.map +1 -0
- package/dist/src/ui/index.d.ts +12 -0
- package/dist/src/ui/index.d.ts.map +1 -0
- package/dist/src/ui/index.js +13 -0
- package/dist/src/ui/index.js.map +1 -0
- package/dist/src/watchers/cache_watcher.d.ts +60 -0
- package/dist/src/watchers/cache_watcher.d.ts.map +1 -0
- package/dist/src/watchers/cache_watcher.js +72 -0
- package/dist/src/watchers/cache_watcher.js.map +1 -0
- package/dist/src/watchers/define_config.d.ts +38 -0
- package/dist/src/watchers/define_config.d.ts.map +1 -0
- package/dist/src/watchers/define_config.js +17 -0
- package/dist/src/watchers/define_config.js.map +1 -0
- package/dist/src/watchers/emitter.d.ts +32 -0
- package/dist/src/watchers/emitter.d.ts.map +1 -0
- package/dist/src/watchers/emitter.js +2 -0
- package/dist/src/watchers/emitter.js.map +1 -0
- package/dist/src/watchers/http_client_watcher.d.ts +74 -0
- package/dist/src/watchers/http_client_watcher.d.ts.map +1 -0
- package/dist/src/watchers/http_client_watcher.js +168 -0
- package/dist/src/watchers/http_client_watcher.js.map +1 -0
- package/dist/src/watchers/index.d.ts +19 -0
- package/dist/src/watchers/index.d.ts.map +1 -0
- package/dist/src/watchers/index.js +19 -0
- package/dist/src/watchers/index.js.map +1 -0
- package/dist/src/watchers/logs_watcher.d.ts +82 -0
- package/dist/src/watchers/logs_watcher.d.ts.map +1 -0
- package/dist/src/watchers/logs_watcher.js +145 -0
- package/dist/src/watchers/logs_watcher.js.map +1 -0
- package/dist/src/watchers/lucid_query_watcher.d.ts +64 -0
- package/dist/src/watchers/lucid_query_watcher.d.ts.map +1 -0
- package/dist/src/watchers/lucid_query_watcher.js +84 -0
- package/dist/src/watchers/lucid_query_watcher.js.map +1 -0
- package/dist/src/watchers/mail_watcher.d.ts +51 -0
- package/dist/src/watchers/mail_watcher.d.ts.map +1 -0
- package/dist/src/watchers/mail_watcher.js +93 -0
- package/dist/src/watchers/mail_watcher.js.map +1 -0
- package/dist/src/watchers/normalize_http_target.d.ts +17 -0
- package/dist/src/watchers/normalize_http_target.d.ts.map +1 -0
- package/dist/src/watchers/normalize_http_target.js +41 -0
- package/dist/src/watchers/normalize_http_target.js.map +1 -0
- package/dist/src/watchers/query_family_hash.d.ts +8 -0
- package/dist/src/watchers/query_family_hash.d.ts.map +1 -0
- package/dist/src/watchers/query_family_hash.js +31 -0
- package/dist/src/watchers/query_family_hash.js.map +1 -0
- package/dist/src/watchers/record.d.ts +22 -0
- package/dist/src/watchers/record.d.ts.map +1 -0
- package/dist/src/watchers/record.js +48 -0
- package/dist/src/watchers/record.js.map +1 -0
- package/dist/stubs/config/telescope.stub +56 -0
- package/dist/stubs/config/telescope_ai.stub +36 -0
- package/dist/stubs/config/telescope_alerts.stub +47 -0
- package/dist/stubs/config/telescope_ui.stub +40 -0
- package/dist/stubs/config/telescope_watchers.stub +30 -0
- package/dist/stubs/database/migrations/create_telescope_entries_table.stub +39 -0
- package/dist/stubs/main.d.ts +6 -0
- package/dist/stubs/main.d.ts.map +1 -0
- package/dist/stubs/main.js +7 -0
- package/dist/stubs/main.js.map +1 -0
- package/package.json +140 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { currentTraceId } from '../context_accessor.js';
|
|
2
|
+
import { EntryType } from '../entry.js';
|
|
3
|
+
import { safeRecord } from './record.js';
|
|
4
|
+
/**
|
|
5
|
+
* The `@adonisjs/cache` event names this watcher subscribes to, mapped to the
|
|
6
|
+
* cache operation recorded for each.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: `@adonisjs/cache` is not installed in this repository, so these event
|
|
9
|
+
* names and their payloads could NOT be verified against its types (see this
|
|
10
|
+
* package's README). They follow `@adonisjs/cache`'s documented `cache:*` event
|
|
11
|
+
* convention but should be treated as best-effort. The set is exported so a host
|
|
12
|
+
* can override it if a future version diverges.
|
|
13
|
+
*/
|
|
14
|
+
export const CACHE_EVENTS = {
|
|
15
|
+
'cache:hit': 'hit',
|
|
16
|
+
'cache:miss': 'miss',
|
|
17
|
+
'cache:written': 'write',
|
|
18
|
+
'cache:deleted': 'delete',
|
|
19
|
+
'cache:cleared': 'clear',
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Records `@adonisjs/cache` activity as `cache` telescope entries — one per
|
|
23
|
+
* hit/miss/write/delete/clear event — correlated to the active request via the
|
|
24
|
+
* trace id.
|
|
25
|
+
*
|
|
26
|
+
* Recording is fire-and-forget and fully guarded: a telescope failure can never
|
|
27
|
+
* break a cache operation.
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* The event-name → operation map ({@link CACHE_EVENTS}) is best-effort because
|
|
31
|
+
* `@adonisjs/cache` is not installed in this repo and its event contract could not
|
|
32
|
+
* be verified. Pass a custom map to the constructor to adapt to your version.
|
|
33
|
+
*/
|
|
34
|
+
export class CacheWatcher {
|
|
35
|
+
type = EntryType.Cache;
|
|
36
|
+
events;
|
|
37
|
+
unsubscribes = [];
|
|
38
|
+
constructor(events = CACHE_EVENTS) {
|
|
39
|
+
this.events = events;
|
|
40
|
+
}
|
|
41
|
+
start(emitter) {
|
|
42
|
+
if (this.unsubscribes.length > 0)
|
|
43
|
+
return;
|
|
44
|
+
for (const [eventName, operation] of Object.entries(this.events)) {
|
|
45
|
+
this.unsubscribes.push(emitter.on(eventName, (data) => this.handle(operation, data)));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
stop() {
|
|
49
|
+
for (const unsubscribe of this.unsubscribes)
|
|
50
|
+
unsubscribe();
|
|
51
|
+
this.unsubscribes.length = 0;
|
|
52
|
+
}
|
|
53
|
+
handle(operation, data) {
|
|
54
|
+
const event = data && typeof data === 'object' ? data : {};
|
|
55
|
+
safeRecord(buildCacheEntry(operation, event), 'CacheWatcher');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Map a cache operation + payload to a telescope {@link RecordInput}. */
|
|
59
|
+
export function buildCacheEntry(operation, event) {
|
|
60
|
+
const key = typeof event.key === 'string' ? event.key : null;
|
|
61
|
+
const store = typeof event.store === 'string' ? event.store : null;
|
|
62
|
+
const traceId = currentTraceId();
|
|
63
|
+
const content = { operation, key, store, traceId };
|
|
64
|
+
return {
|
|
65
|
+
type: EntryType.Cache,
|
|
66
|
+
familyHash: key ? `${operation}:${key}` : operation,
|
|
67
|
+
content,
|
|
68
|
+
traceId,
|
|
69
|
+
tags: [`cache:${operation}`, ...(store ? [`store:${store}`] : [])],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=cache_watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache_watcher.js","sourceRoot":"","sources":["../../../src/watchers/cache_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAAmC;IAC1D,WAAW,EAAE,KAAK;IAClB,YAAY,EAAE,MAAM;IACpB,eAAe,EAAE,OAAO;IACxB,eAAe,EAAE,QAAQ;IACzB,eAAe,EAAE,OAAO;CACzB,CAAC;AA2BF;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,YAAY;IACd,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC;IACf,MAAM,CAAiC;IACvC,YAAY,GAAsB,EAAE,CAAC;IAEtD,YAAY,SAAyC,YAAY;QAC/D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,OAAoB;QACxB,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO;QACzC,KAAK,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACjE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,IAAI;QACF,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY;YAAE,WAAW,EAAE,CAAC;QAC3D,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/B,CAAC;IAEO,MAAM,CAAC,SAAyB,EAAE,IAAa;QACrD,MAAM,KAAK,GAAmB,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAuB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/F,UAAU,CAAC,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC;IAChE,CAAC;CACF;AAED,0EAA0E;AAC1E,MAAM,UAAU,eAAe,CAC7B,SAAyB,EACzB,KAAqB;IAErB,MAAM,GAAG,GAAG,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7D,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,OAAO,GAAsB,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACtE,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,KAAK;QACrB,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;QACnD,OAAO;QACP,OAAO;QACP,IAAI,EAAE,CAAC,SAAS,SAAS,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KACnE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** The per-technology watchers this package ships. */
|
|
2
|
+
export type WatcherName = 'query' | 'mail' | 'cache' | 'http-client' | 'logs';
|
|
3
|
+
/**
|
|
4
|
+
* The shape of `config/telescope_watchers.ts`. Everything is optional: by default
|
|
5
|
+
* only the Lucid `query` watcher is enabled (it is the one whose events are
|
|
6
|
+
* verified against installed types), with the rest opt-in.
|
|
7
|
+
*/
|
|
8
|
+
export interface TelescopeWatchersConfig {
|
|
9
|
+
/**
|
|
10
|
+
* Master switch. When `false`, no per-technology watcher is started. Default
|
|
11
|
+
* `true`.
|
|
12
|
+
*/
|
|
13
|
+
enabled?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Which watchers are active. Omit a name to disable it. Default `['query']`.
|
|
16
|
+
* - `'query'` — records every Lucid SQL query (`db:query`).
|
|
17
|
+
* - `'mail'` — records every email sent (`mail:sent`).
|
|
18
|
+
* - `'cache'` — records `@adonisjs/cache` hit/miss/write/delete events.
|
|
19
|
+
* - `'http-client'` — records every outbound `fetch` call.
|
|
20
|
+
* - `'logs'` — records AdonisJS logger output as `log` entries.
|
|
21
|
+
*/
|
|
22
|
+
watchers?: WatcherName[];
|
|
23
|
+
}
|
|
24
|
+
/** The fully-resolved watchers config the provider acts on (no optionals). */
|
|
25
|
+
export interface ResolvedTelescopeWatchersConfig {
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
watchers: Set<WatcherName>;
|
|
28
|
+
}
|
|
29
|
+
/** The default set of enabled watchers — the verified Lucid query watcher only. */
|
|
30
|
+
export declare const DEFAULT_WATCHERS: WatcherName[];
|
|
31
|
+
/**
|
|
32
|
+
* Identity helper giving `config/telescope_watchers.ts` full type-checking,
|
|
33
|
+
* mirroring the AdonisJS `defineConfig` convention.
|
|
34
|
+
*/
|
|
35
|
+
export declare function defineConfig(config: TelescopeWatchersConfig): TelescopeWatchersConfig;
|
|
36
|
+
/** Apply defaults to a (possibly partial) config. */
|
|
37
|
+
export declare function resolveConfig(config?: TelescopeWatchersConfig): ResolvedTelescopeWatchersConfig;
|
|
38
|
+
//# sourceMappingURL=define_config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../../src/watchers/define_config.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,GAAG,MAAM,CAAC;AAE9E;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;OAOG;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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** The default set of enabled watchers — the verified Lucid query watcher only. */
|
|
2
|
+
export const DEFAULT_WATCHERS = ['query'];
|
|
3
|
+
/**
|
|
4
|
+
* Identity helper giving `config/telescope_watchers.ts` full type-checking,
|
|
5
|
+
* mirroring the AdonisJS `defineConfig` convention.
|
|
6
|
+
*/
|
|
7
|
+
export function defineConfig(config) {
|
|
8
|
+
return config;
|
|
9
|
+
}
|
|
10
|
+
/** Apply defaults to a (possibly partial) config. */
|
|
11
|
+
export function resolveConfig(config = {}) {
|
|
12
|
+
return {
|
|
13
|
+
enabled: config.enabled ?? true,
|
|
14
|
+
watchers: new Set(config.watchers ?? DEFAULT_WATCHERS),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=define_config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../../src/watchers/define_config.ts"],"names":[],"mappings":"AAgCA,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,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The narrow, structural slice of the AdonisJS event emitter the watchers in this
|
|
3
|
+
* package depend on. Mirroring the `@adonisjs/events` `Emitter` surface
|
|
4
|
+
* structurally — rather than importing it — keeps the watchers unit-testable with
|
|
5
|
+
* a plain double and avoids a hard build-time coupling to a specific emitter
|
|
6
|
+
* version.
|
|
7
|
+
*
|
|
8
|
+
* `on()` returns an unsubscribe function (this is exactly what the real Adonis
|
|
9
|
+
* emitter, built on `emittery`, returns), which is how every watcher tears down
|
|
10
|
+
* cleanly on {@link Watcher.stop}.
|
|
11
|
+
*/
|
|
12
|
+
export interface EmitterLike {
|
|
13
|
+
/**
|
|
14
|
+
* Subscribe `listener` to `event`. Returns a function that removes that exact
|
|
15
|
+
* subscription when called.
|
|
16
|
+
*/
|
|
17
|
+
on(event: string, listener: (data: unknown) => void): () => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The common shape every per-technology watcher implements: start subscribing on
|
|
21
|
+
* an emitter, and stop (fully unsubscribe) later. Neither method ever throws into
|
|
22
|
+
* the host application.
|
|
23
|
+
*/
|
|
24
|
+
export interface Watcher {
|
|
25
|
+
/** The telescope entry `type` this watcher records under. */
|
|
26
|
+
readonly type: string;
|
|
27
|
+
/** Begin recording by subscribing to the relevant emitter event(s). */
|
|
28
|
+
start(emitter: EmitterLike): void;
|
|
29
|
+
/** Stop recording by removing every subscription this watcher added. */
|
|
30
|
+
stop(): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../../src/watchers/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAClE;AAED;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAClC,wEAAwE;IACxE,IAAI,IAAI,IAAI,CAAC;CACd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../../src/watchers/emitter.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type RecordInput } from '../entry.js';
|
|
2
|
+
/** Options for {@link HttpClientWatcher}. */
|
|
3
|
+
export interface HttpClientWatcherOptions {
|
|
4
|
+
/** Outbound calls at/above this many ms get a `slow` tag. Default 1000. */
|
|
5
|
+
slowMs?: number;
|
|
6
|
+
/** Time source; injectable for tests. Default `Date.now`. */
|
|
7
|
+
clock?: {
|
|
8
|
+
now(): number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** The recorded body of an `http-client` entry. */
|
|
12
|
+
export interface HttpClientEntryContent {
|
|
13
|
+
/** The request method, upper-cased (e.g. `'GET'`). */
|
|
14
|
+
method: string;
|
|
15
|
+
/** The sanitized request url (userinfo stripped, sensitive query values masked). */
|
|
16
|
+
url: string;
|
|
17
|
+
/** The target host (e.g. `'api.stripe.com'`), or `null` for a relative/invalid url. */
|
|
18
|
+
host: string | null;
|
|
19
|
+
/** The response status, or `null` on a transport (network) failure. */
|
|
20
|
+
statusCode: number | null;
|
|
21
|
+
/** Wall-clock duration of the call in milliseconds. */
|
|
22
|
+
durationMs: number;
|
|
23
|
+
/** The active trace id at call time, or `null`. */
|
|
24
|
+
traceId: string | null;
|
|
25
|
+
}
|
|
26
|
+
type FetchFn = typeof globalThis.fetch;
|
|
27
|
+
type FetchInit = Parameters<FetchFn>[1];
|
|
28
|
+
/** Mark a `RequestInit` so the {@link HttpClientWatcher} skips recording the
|
|
29
|
+
* call it belongs to. Use for telescope's own outbound fetches (remote store,
|
|
30
|
+
* alert webhooks) so the watcher never records — or recurses on — itself. */
|
|
31
|
+
export declare function markInternalFetch(init: FetchInit): FetchInit;
|
|
32
|
+
/**
|
|
33
|
+
* Records every OUTBOUND HTTP call as an `http-client` telescope entry by
|
|
34
|
+
* wrapping the Node global `fetch`. Each call is timed; method, sanitized url,
|
|
35
|
+
* host, status and duration are captured and correlated to the active request
|
|
36
|
+
* via the trace id.
|
|
37
|
+
*
|
|
38
|
+
* The wrapper never alters the host's call: it awaits the real `fetch`, records
|
|
39
|
+
* fire-and-forget (a telescope failure can't break or block the request), and
|
|
40
|
+
* always re-throws a network error. Telescope's own outbound fetches — marked
|
|
41
|
+
* via {@link markInternalFetch} — are skipped, so the watcher never records or
|
|
42
|
+
* recurses on itself.
|
|
43
|
+
*
|
|
44
|
+
* Patching the global is idempotent process-wide (a `Symbol.for` marker). Unlike
|
|
45
|
+
* the emitter watchers, this implements its own lifecycle: `start()` takes no
|
|
46
|
+
* emitter; `stop()` restores the original `fetch`.
|
|
47
|
+
*/
|
|
48
|
+
export declare class HttpClientWatcher {
|
|
49
|
+
readonly type: "http-client";
|
|
50
|
+
private readonly slowMs;
|
|
51
|
+
private readonly clock;
|
|
52
|
+
/** Whether THIS instance installed the patch (so only it restores on stop). */
|
|
53
|
+
private installed;
|
|
54
|
+
constructor(options?: HttpClientWatcherOptions);
|
|
55
|
+
/** Patch `globalThis.fetch` to record outbound calls. Idempotent: a second
|
|
56
|
+
* call (or another instance / package copy) is a no-op. */
|
|
57
|
+
start(): void;
|
|
58
|
+
/** Restore the original `fetch` — but only if THIS instance installed the
|
|
59
|
+
* current wrapper (avoids clobbering a wrapper a later instance installed). */
|
|
60
|
+
stop(): void;
|
|
61
|
+
/** Build + record an entry, swallowing every failure via {@link safeRecord}. */
|
|
62
|
+
private record;
|
|
63
|
+
}
|
|
64
|
+
/** Map a captured outbound call to a telescope {@link RecordInput}. Exported so
|
|
65
|
+
* the entry shape can be unit-tested without patching the global. */
|
|
66
|
+
export declare function buildHttpClientEntry(call: {
|
|
67
|
+
method: string;
|
|
68
|
+
url: string;
|
|
69
|
+
host: string | null;
|
|
70
|
+
statusCode: number | null;
|
|
71
|
+
durationMs: number;
|
|
72
|
+
}, slowMs?: number): RecordInput<HttpClientEntryContent>;
|
|
73
|
+
export {};
|
|
74
|
+
//# sourceMappingURL=http_client_watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http_client_watcher.d.ts","sourceRoot":"","sources":["../../../src/watchers/http_client_watcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAI1D,6CAA6C;AAC7C,MAAM,WAAW,wBAAwB;IACvC,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,KAAK,CAAC,EAAE;QAAE,GAAG,IAAI,MAAM,CAAA;KAAE,CAAC;CAC3B;AAED,mDAAmD;AACnD,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAC;IACZ,uFAAuF;IACvF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,uEAAuE;IACvE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAsBD,KAAK,OAAO,GAAG,OAAO,UAAU,CAAC,KAAK,CAAC;AAEvC,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AA+CxC;;8EAE8E;AAC9E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAI5D;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,iBAAiB;IAC5B,QAAQ,CAAC,IAAI,gBAAwB;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,+EAA+E;IAC/E,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,GAAE,wBAA6B;IAKlD;gEAC4D;IAC5D,KAAK,IAAI,IAAI;IAkCb;oFACgF;IAChF,IAAI,IAAI,IAAI;IASZ,gFAAgF;IAChF,OAAO,CAAC,MAAM;CAYf;AAED;sEACsE;AACtE,wBAAgB,oBAAoB,CAClC,IAAI,EAAE;IACJ,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB,EACD,MAAM,SAAkB,GACvB,WAAW,CAAC,sBAAsB,CAAC,CAwBrC"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { currentTraceId } from '../context_accessor.js';
|
|
2
|
+
import { EntryType } from '../entry.js';
|
|
3
|
+
import { normalizeHttpTarget } from './normalize_http_target.js';
|
|
4
|
+
import { safeRecord } from './record.js';
|
|
5
|
+
/** Default slow-call threshold in milliseconds. */
|
|
6
|
+
const DEFAULT_SLOW_MS = 1000;
|
|
7
|
+
/** Query-param keys whose VALUES are masked from a captured URL. Key-based
|
|
8
|
+
* content redaction can't reach a URL string leaf, so we sanitize the URL here
|
|
9
|
+
* before it ever reaches the (separately redacted) entry content. */
|
|
10
|
+
const SENSITIVE_PARAM = /(token|secret|password|passwd|api[-_]?key|access[-_]?key|auth|credential)/i;
|
|
11
|
+
const REDACTED = '[REDACTED]';
|
|
12
|
+
/** Marks our wrapper so the global `fetch` is patched exactly once even if two
|
|
13
|
+
* copies of this package load. `Symbol.for` (the global registry) is deliberate:
|
|
14
|
+
* both copies resolve the same marker and neither double-wraps the other. */
|
|
15
|
+
const PATCHED = Symbol.for('@agora/telescope:httpClientPatched');
|
|
16
|
+
/** Marks an `init` (RequestInit) as telescope's OWN outbound call so the wrapper
|
|
17
|
+
* skips recording it — the recursion guard for any internal fetch (e.g. a
|
|
18
|
+
* future remote store / alert webhook performing a `fetch`). */
|
|
19
|
+
const INTERNAL = Symbol.for('@agora/telescope:internalFetch');
|
|
20
|
+
/**
|
|
21
|
+
* Sanitize a raw URL for storage: strip userinfo (`user:pass@`) and mask
|
|
22
|
+
* sensitive query-param VALUES, returning `{ url, host }`. A relative/invalid
|
|
23
|
+
* url is kept verbatim with `host: null`.
|
|
24
|
+
*/
|
|
25
|
+
function sanitizeUrl(rawUrl) {
|
|
26
|
+
try {
|
|
27
|
+
const parsed = new URL(rawUrl);
|
|
28
|
+
const host = parsed.host;
|
|
29
|
+
parsed.username = '';
|
|
30
|
+
parsed.password = '';
|
|
31
|
+
for (const key of [...parsed.searchParams.keys()]) {
|
|
32
|
+
if (SENSITIVE_PARAM.test(key))
|
|
33
|
+
parsed.searchParams.set(key, REDACTED);
|
|
34
|
+
}
|
|
35
|
+
return { url: parsed.toString(), host };
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return { url: rawUrl, host: null };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Pull method/url/host out of fetch's `(input, init)` without throwing. */
|
|
42
|
+
function describeRequest(input, init) {
|
|
43
|
+
let rawUrl = '';
|
|
44
|
+
let method = 'GET';
|
|
45
|
+
if (typeof input === 'string')
|
|
46
|
+
rawUrl = input;
|
|
47
|
+
else if (input instanceof URL)
|
|
48
|
+
rawUrl = input.href;
|
|
49
|
+
else if (input instanceof Request) {
|
|
50
|
+
rawUrl = input.url;
|
|
51
|
+
method = input.method;
|
|
52
|
+
}
|
|
53
|
+
if (init && typeof init.method === 'string')
|
|
54
|
+
method = init.method;
|
|
55
|
+
const { url, host } = sanitizeUrl(rawUrl);
|
|
56
|
+
return { method: method.toUpperCase(), url, host };
|
|
57
|
+
}
|
|
58
|
+
/** Mark a `RequestInit` so the {@link HttpClientWatcher} skips recording the
|
|
59
|
+
* call it belongs to. Use for telescope's own outbound fetches (remote store,
|
|
60
|
+
* alert webhooks) so the watcher never records — or recurses on — itself. */
|
|
61
|
+
export function markInternalFetch(init) {
|
|
62
|
+
const next = (init ?? {});
|
|
63
|
+
next[INTERNAL] = true;
|
|
64
|
+
return next;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Records every OUTBOUND HTTP call as an `http-client` telescope entry by
|
|
68
|
+
* wrapping the Node global `fetch`. Each call is timed; method, sanitized url,
|
|
69
|
+
* host, status and duration are captured and correlated to the active request
|
|
70
|
+
* via the trace id.
|
|
71
|
+
*
|
|
72
|
+
* The wrapper never alters the host's call: it awaits the real `fetch`, records
|
|
73
|
+
* fire-and-forget (a telescope failure can't break or block the request), and
|
|
74
|
+
* always re-throws a network error. Telescope's own outbound fetches — marked
|
|
75
|
+
* via {@link markInternalFetch} — are skipped, so the watcher never records or
|
|
76
|
+
* recurses on itself.
|
|
77
|
+
*
|
|
78
|
+
* Patching the global is idempotent process-wide (a `Symbol.for` marker). Unlike
|
|
79
|
+
* the emitter watchers, this implements its own lifecycle: `start()` takes no
|
|
80
|
+
* emitter; `stop()` restores the original `fetch`.
|
|
81
|
+
*/
|
|
82
|
+
export class HttpClientWatcher {
|
|
83
|
+
type = EntryType.HttpClient;
|
|
84
|
+
slowMs;
|
|
85
|
+
clock;
|
|
86
|
+
/** Whether THIS instance installed the patch (so only it restores on stop). */
|
|
87
|
+
installed = false;
|
|
88
|
+
constructor(options = {}) {
|
|
89
|
+
this.slowMs = options.slowMs ?? DEFAULT_SLOW_MS;
|
|
90
|
+
this.clock = options.clock ?? { now: () => Date.now() };
|
|
91
|
+
}
|
|
92
|
+
/** Patch `globalThis.fetch` to record outbound calls. Idempotent: a second
|
|
93
|
+
* call (or another instance / package copy) is a no-op. */
|
|
94
|
+
start() {
|
|
95
|
+
const current = globalThis.fetch;
|
|
96
|
+
if (typeof current !== 'function' || current[PATCHED])
|
|
97
|
+
return;
|
|
98
|
+
const original = current;
|
|
99
|
+
const watcher = this;
|
|
100
|
+
const patched = async function patchedFetch(input, init) {
|
|
101
|
+
// Skip (and don't record) telescope's own outbound calls — the recursion
|
|
102
|
+
// guard for any internal fetch.
|
|
103
|
+
if (init && init[INTERNAL]) {
|
|
104
|
+
return original(input, init);
|
|
105
|
+
}
|
|
106
|
+
const startedAt = watcher.clock.now();
|
|
107
|
+
const { method, url, host } = describeRequest(input, init);
|
|
108
|
+
try {
|
|
109
|
+
const response = await original(input, init);
|
|
110
|
+
watcher.record(method, url, host, response.status, watcher.clock.now() - startedAt);
|
|
111
|
+
return response;
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
watcher.record(method, url, host, null, watcher.clock.now() - startedAt);
|
|
115
|
+
throw error; // never swallow the host's network error
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
patched[PATCHED] = true;
|
|
119
|
+
patched.__telescopeOriginal__ = original;
|
|
120
|
+
globalThis.fetch = patched;
|
|
121
|
+
this.installed = true;
|
|
122
|
+
}
|
|
123
|
+
/** Restore the original `fetch` — but only if THIS instance installed the
|
|
124
|
+
* current wrapper (avoids clobbering a wrapper a later instance installed). */
|
|
125
|
+
stop() {
|
|
126
|
+
if (!this.installed)
|
|
127
|
+
return;
|
|
128
|
+
this.installed = false;
|
|
129
|
+
const current = globalThis.fetch;
|
|
130
|
+
if (current?.[PATCHED] && current.__telescopeOriginal__) {
|
|
131
|
+
globalThis.fetch = current.__telescopeOriginal__;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/** Build + record an entry, swallowing every failure via {@link safeRecord}. */
|
|
135
|
+
record(method, url, host, statusCode, durationMs) {
|
|
136
|
+
safeRecord(buildHttpClientEntry({ method, url, host, statusCode, durationMs }, this.slowMs), 'HttpClientWatcher');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/** Map a captured outbound call to a telescope {@link RecordInput}. Exported so
|
|
140
|
+
* the entry shape can be unit-tested without patching the global. */
|
|
141
|
+
export function buildHttpClientEntry(call, slowMs = DEFAULT_SLOW_MS) {
|
|
142
|
+
const traceId = currentTraceId();
|
|
143
|
+
const content = {
|
|
144
|
+
method: call.method,
|
|
145
|
+
url: call.url,
|
|
146
|
+
host: call.host,
|
|
147
|
+
statusCode: call.statusCode,
|
|
148
|
+
durationMs: Math.max(0, call.durationMs),
|
|
149
|
+
traceId,
|
|
150
|
+
};
|
|
151
|
+
const tags = ['http-client'];
|
|
152
|
+
if (content.host)
|
|
153
|
+
tags.push(`host:${content.host}`);
|
|
154
|
+
// A 4xx is a valid response, not a transport failure — only 5xx / network errors are 'failed'.
|
|
155
|
+
if (content.statusCode === null || content.statusCode >= 500)
|
|
156
|
+
tags.push('failed');
|
|
157
|
+
if (content.durationMs >= slowMs)
|
|
158
|
+
tags.push('slow');
|
|
159
|
+
return {
|
|
160
|
+
type: EntryType.HttpClient,
|
|
161
|
+
familyHash: normalizeHttpTarget(content.method, content.url),
|
|
162
|
+
content,
|
|
163
|
+
durationMs: content.durationMs,
|
|
164
|
+
traceId,
|
|
165
|
+
tags,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=http_client_watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http_client_watcher.js","sourceRoot":"","sources":["../../../src/watchers/http_client_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA0BzC,mDAAmD;AACnD,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B;;sEAEsE;AACtE,MAAM,eAAe,GACnB,4EAA4E,CAAC;AAC/E,MAAM,QAAQ,GAAG,YAAY,CAAC;AAE9B;;8EAE8E;AAC9E,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AAEjE;;iEAEiE;AACjE,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAY9D;;;;GAIG;AACH,SAAS,WAAW,CAAC,MAAc;IACjC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC;QACrB,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC;QACrB,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAClD,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACxE,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACrC,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,SAAS,eAAe,CACtB,KAAiB,EACjB,IAAe;IAEf,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,GAAG,KAAK,CAAC;SACzC,IAAI,KAAK,YAAY,GAAG;QAAE,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC;SAC9C,IAAI,KAAK,YAAY,OAAO,EAAE,CAAC;QAClC,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC;QACnB,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IACxB,CAAC;IACD,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;QAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAElE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACrD,CAAC;AAED;;8EAE8E;AAC9E,MAAM,UAAU,iBAAiB,CAAC,IAAe;IAC/C,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAyC,CAAC;IAClE,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACtB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,iBAAiB;IACnB,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC;IACpB,MAAM,CAAS;IACf,KAAK,CAAoB;IAC1C,+EAA+E;IACvE,SAAS,GAAG,KAAK,CAAC;IAE1B,YAAY,UAAoC,EAAE;QAChD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,eAAe,CAAC;QAChD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC1D,CAAC;IAED;gEAC4D;IAC5D,KAAK;QACH,MAAM,OAAO,GAAG,UAAU,CAAC,KAAiC,CAAC;QAC7D,IAAI,OAAO,OAAO,KAAK,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;YAAE,OAAO;QAE9D,MAAM,QAAQ,GAAG,OAAO,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC;QACrB,MAAM,OAAO,GAAG,KAAK,UAAU,YAAY,CACzC,KAAiB,EACjB,IAAgB;YAEhB,yEAAyE;YACzE,gCAAgC;YAChC,IAAI,IAAI,IAAK,IAAiC,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzD,OAAO,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC/B,CAAC;YAED,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACtC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC3D,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAC7C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;gBACpF,OAAO,QAAQ,CAAC;YAClB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;gBACzE,MAAM,KAAK,CAAC,CAAC,yCAAyC;YACxD,CAAC;QACH,CAAiB,CAAC;QAElB,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;QACxB,OAAO,CAAC,qBAAqB,GAAG,QAAQ,CAAC;QACzC,UAAU,CAAC,KAAK,GAAG,OAAO,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAED;oFACgF;IAChF,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC5B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,MAAM,OAAO,GAAG,UAAU,CAAC,KAAiC,CAAC;QAC7D,IAAI,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;YACxD,UAAU,CAAC,KAAK,GAAG,OAAO,CAAC,qBAAqB,CAAC;QACnD,CAAC;IACH,CAAC;IAED,gFAAgF;IACxE,MAAM,CACZ,MAAc,EACd,GAAW,EACX,IAAmB,EACnB,UAAyB,EACzB,UAAkB;QAElB,UAAU,CACR,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,EAChF,mBAAmB,CACpB,CAAC;IACJ,CAAC;CACF;AAED;sEACsE;AACtE,MAAM,UAAU,oBAAoB,CAClC,IAMC,EACD,MAAM,GAAG,eAAe;IAExB,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,OAAO,GAA2B;QACtC,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC;QACxC,OAAO;KACR,CAAC;IACF,MAAM,IAAI,GAAa,CAAC,aAAa,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACpD,+FAA+F;IAC/F,IAAI,OAAO,CAAC,UAAU,KAAK,IAAI,IAAI,OAAO,CAAC,UAAU,IAAI,GAAG;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClF,IAAI,OAAO,CAAC,UAAU,IAAI,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEpD,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,UAAU;QAC1B,UAAU,EAAE,mBAAmB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC;QAC5D,OAAO;QACP,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,OAAO;QACP,IAAI;KACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Keep in sync with this package's `version` in package.json. */
|
|
2
|
+
export declare const VERSION = "0.1.0";
|
|
3
|
+
export type { EmitterLike, Watcher } from './emitter.js';
|
|
4
|
+
export { resolveStore, safeRecord } from './record.js';
|
|
5
|
+
export { buildQueryEntry, DB_QUERY_EVENT, LucidQueryWatcher } from './lucid_query_watcher.js';
|
|
6
|
+
export type { DbQueryEventLike, QueryEntryContent } from './lucid_query_watcher.js';
|
|
7
|
+
export { queryFamilyHash } from './query_family_hash.js';
|
|
8
|
+
export { buildMailEntry, MAIL_SENT_EVENT, MailWatcher } from './mail_watcher.js';
|
|
9
|
+
export type { MailEntryContent, MailSentEventLike } from './mail_watcher.js';
|
|
10
|
+
export { buildCacheEntry, CACHE_EVENTS, CacheWatcher } from './cache_watcher.js';
|
|
11
|
+
export type { CacheEntryContent, CacheEventLike, CacheOperation } from './cache_watcher.js';
|
|
12
|
+
export { buildHttpClientEntry, HttpClientWatcher, markInternalFetch, } from './http_client_watcher.js';
|
|
13
|
+
export type { HttpClientEntryContent, HttpClientWatcherOptions, } from './http_client_watcher.js';
|
|
14
|
+
export { normalizeHttpTarget } from './normalize_http_target.js';
|
|
15
|
+
export { buildLogEntry, extractLog, LOG_LEVELS, LogsWatcher } from './logs_watcher.js';
|
|
16
|
+
export type { LogEntryContent, LoggerLike, LogLevel, LogsWatcherOptions, } from './logs_watcher.js';
|
|
17
|
+
export { DEFAULT_WATCHERS, defineConfig, resolveConfig, } from './define_config.js';
|
|
18
|
+
export type { ResolvedTelescopeWatchersConfig, TelescopeWatchersConfig, WatcherName, } from './define_config.js';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Keep in sync with this package's `version` in package.json. */
|
|
2
|
+
export const VERSION = '0.1.0';
|
|
3
|
+
// — runtime recording (advanced) —
|
|
4
|
+
export { resolveStore, safeRecord } from './record.js';
|
|
5
|
+
// — Lucid query watcher (the headline watcher) —
|
|
6
|
+
export { buildQueryEntry, DB_QUERY_EVENT, LucidQueryWatcher } from './lucid_query_watcher.js';
|
|
7
|
+
export { queryFamilyHash } from './query_family_hash.js';
|
|
8
|
+
// — mail watcher —
|
|
9
|
+
export { buildMailEntry, MAIL_SENT_EVENT, MailWatcher } from './mail_watcher.js';
|
|
10
|
+
// — cache watcher —
|
|
11
|
+
export { buildCacheEntry, CACHE_EVENTS, CacheWatcher } from './cache_watcher.js';
|
|
12
|
+
// — http-client (outbound) watcher —
|
|
13
|
+
export { buildHttpClientEntry, HttpClientWatcher, markInternalFetch, } from './http_client_watcher.js';
|
|
14
|
+
export { normalizeHttpTarget } from './normalize_http_target.js';
|
|
15
|
+
// — logs watcher —
|
|
16
|
+
export { buildLogEntry, extractLog, LOG_LEVELS, LogsWatcher } from './logs_watcher.js';
|
|
17
|
+
// — config —
|
|
18
|
+
export { DEFAULT_WATCHERS, defineConfig, resolveConfig, } from './define_config.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type RecordInput } from '../entry.js';
|
|
2
|
+
/** The standard pino/AdonisJS log levels this watcher tees, lowest → highest. */
|
|
3
|
+
export declare const LOG_LEVELS: readonly ["trace", "debug", "info", "warn", "error", "fatal"];
|
|
4
|
+
export type LogLevel = (typeof LOG_LEVELS)[number];
|
|
5
|
+
/** A single pino-style log method: either `(message, ...values)` or
|
|
6
|
+
* `(mergingObject, message?, ...values)`. We read only the message string and a
|
|
7
|
+
* bounded slice of the merging object. */
|
|
8
|
+
type LogMethod = (...args: unknown[]) => void;
|
|
9
|
+
/**
|
|
10
|
+
* The structural slice of the AdonisJS `Logger` (`@adonisjs/logger`) this watcher
|
|
11
|
+
* taps — the level methods. Mirrored structurally (rather than importing the
|
|
12
|
+
* class) so the watcher stays unit-testable with a plain double and has no
|
|
13
|
+
* build-time coupling to a specific logger version.
|
|
14
|
+
*/
|
|
15
|
+
export type LoggerLike = {
|
|
16
|
+
[Level in LogLevel]?: LogMethod;
|
|
17
|
+
};
|
|
18
|
+
/** The recorded body of a `log` entry. */
|
|
19
|
+
export interface LogEntryContent {
|
|
20
|
+
/** The log level (`'info'`, `'error'`, …). */
|
|
21
|
+
level: LogLevel;
|
|
22
|
+
/** The log message string, or `null` when the call carried only an object. */
|
|
23
|
+
message: string | null;
|
|
24
|
+
/** A bounded copy of the merging object's fields, or `null`. Redacted centrally. */
|
|
25
|
+
context: Record<string, unknown> | null;
|
|
26
|
+
/** The active trace id at log time, or `null`. */
|
|
27
|
+
traceId: string | null;
|
|
28
|
+
}
|
|
29
|
+
/** Options for {@link LogsWatcher}. */
|
|
30
|
+
export interface LogsWatcherOptions {
|
|
31
|
+
/** Only record at/above this level. Default `'trace'` (record everything). */
|
|
32
|
+
minLevel?: LogLevel;
|
|
33
|
+
/** Extra tags appended to every recorded log entry. */
|
|
34
|
+
tags?: readonly string[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Records AdonisJS `Logger` output as `EntryType.Log` entries, correlated to the
|
|
38
|
+
* active request via the trace id.
|
|
39
|
+
*
|
|
40
|
+
* ## How it taps the logger (non-invasive, reversible)
|
|
41
|
+
* Rather than monkey-patching a global or a prototype, `start(logger)` tees the
|
|
42
|
+
* level methods on the ONE logger instance resolved from the container. Each teed
|
|
43
|
+
* method calls the original first (host output is untouched) and then records.
|
|
44
|
+
* `stop()` restores the originals, so the tap fully unwinds on shutdown.
|
|
45
|
+
*
|
|
46
|
+
* Pino has no supported post-construction transport/hook for a live instance, so
|
|
47
|
+
* instance-scoped method-teeing is the least-invasive option that captures logs
|
|
48
|
+
* written through the app logger without owning its construction. The tee is
|
|
49
|
+
* idempotent per instance (a `Symbol.for` marker) and a reentrancy guard prevents
|
|
50
|
+
* an infinite record→log loop.
|
|
51
|
+
*
|
|
52
|
+
* Recording is fire-and-forget and fully guarded — a telescope failure can never
|
|
53
|
+
* break the host's logging.
|
|
54
|
+
*/
|
|
55
|
+
export declare class LogsWatcher {
|
|
56
|
+
readonly type: "log";
|
|
57
|
+
private readonly minLevelIndex;
|
|
58
|
+
private readonly extraTags;
|
|
59
|
+
private logger;
|
|
60
|
+
constructor(options?: LogsWatcherOptions);
|
|
61
|
+
/** Tee the level methods on `logger`. Idempotent per instance. */
|
|
62
|
+
start(logger: LoggerLike): void;
|
|
63
|
+
/** Restore the original level methods on the tapped instance. */
|
|
64
|
+
stop(): void;
|
|
65
|
+
/** Build + record a log entry from the level method's arguments. */
|
|
66
|
+
private record;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Parse a pino-style level call into `{ message, context }`, mirroring pino's own
|
|
70
|
+
* argument convention: either `(message, ...)` or `(mergingObject, message?, ...)`.
|
|
71
|
+
* The context object is shallow-copied and bounded to a handful of keys here; the
|
|
72
|
+
* central redaction layer scrubs any sensitive values before storage.
|
|
73
|
+
*/
|
|
74
|
+
export declare function extractLog(args: unknown[]): {
|
|
75
|
+
message: string | null;
|
|
76
|
+
context: Record<string, unknown> | null;
|
|
77
|
+
};
|
|
78
|
+
/** Map a level + raw method args to a telescope {@link RecordInput}. Exported so
|
|
79
|
+
* the entry shape can be unit-tested without teeing a logger. */
|
|
80
|
+
export declare function buildLogEntry(level: LogLevel, args: unknown[], extraTags?: readonly string[]): RecordInput<LogEntryContent>;
|
|
81
|
+
export {};
|
|
82
|
+
//# sourceMappingURL=logs_watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs_watcher.d.ts","sourceRoot":"","sources":["../../../src/watchers/logs_watcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1D,iFAAiF;AACjF,eAAO,MAAM,UAAU,+DAAgE,CAAC;AACxF,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD;;2CAE2C;AAC3C,KAAK,SAAS,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG;KACtB,KAAK,IAAI,QAAQ,CAAC,CAAC,EAAE,SAAS;CAChC,CAAC;AAEF,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,KAAK,EAAE,QAAQ,CAAC;IAChB,8EAA8E;IAC9E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxC,kDAAkD;IAClD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,uDAAuD;IACvD,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAkBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,WAAW;IACtB,QAAQ,CAAC,IAAI,QAAiB;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,MAAM,CAA2B;gBAE7B,OAAO,GAAE,kBAAuB;IAK5C,kEAAkE;IAClE,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAgC/B,iEAAiE;IACjE,IAAI,IAAI,IAAI;IAYZ,oEAAoE;IACpE,OAAO,CAAC,MAAM;CAGf;AAUD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG;IAC3C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACzC,CAQA;AAeD;kEACkE;AAClE,wBAAgB,aAAa,CAC3B,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,OAAO,EAAE,EACf,SAAS,GAAE,SAAS,MAAM,EAAO,GAChC,WAAW,CAAC,eAAe,CAAC,CAW9B"}
|