adonisjs-server-stats 1.3.2 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -116
- package/dist/configure.d.ts.map +1 -1
- package/dist/src/controller/debug_controller.d.ts +2 -2
- package/dist/src/controller/debug_controller.d.ts.map +1 -1
- package/dist/src/controller/server_stats_controller.d.ts +1 -1
- package/dist/src/controller/server_stats_controller.d.ts.map +1 -1
- package/dist/src/dashboard/chart_aggregator.d.ts.map +1 -1
- package/dist/src/dashboard/chart_aggregator.js +8 -8
- package/dist/src/dashboard/dashboard_controller.d.ts +12 -97
- package/dist/src/dashboard/dashboard_controller.d.ts.map +1 -1
- package/dist/src/dashboard/dashboard_controller.js +258 -489
- package/dist/src/dashboard/dashboard_routes.d.ts.map +1 -1
- package/dist/src/dashboard/dashboard_routes.js +7 -2
- package/dist/src/dashboard/dashboard_store.d.ts +39 -3
- package/dist/src/dashboard/dashboard_store.d.ts.map +1 -1
- package/dist/src/dashboard/dashboard_store.js +145 -78
- package/dist/src/dashboard/integrations/cache_inspector.d.ts.map +1 -1
- package/dist/src/dashboard/integrations/queue_inspector.d.ts.map +1 -1
- package/dist/src/dashboard/migrator.d.ts.map +1 -1
- package/dist/src/dashboard/migrator.js +3 -1
- package/dist/src/dashboard/models/stats_event.d.ts +1 -1
- package/dist/src/dashboard/models/stats_event.d.ts.map +1 -1
- package/dist/src/dashboard/models/stats_query.d.ts +1 -1
- package/dist/src/dashboard/models/stats_query.d.ts.map +1 -1
- package/dist/src/dashboard/models/stats_request.d.ts +2 -2
- package/dist/src/dashboard/models/stats_request.d.ts.map +1 -1
- package/dist/src/dashboard/models/stats_request.js +1 -1
- package/dist/src/dashboard/models/stats_trace.d.ts +1 -1
- package/dist/src/dashboard/models/stats_trace.d.ts.map +1 -1
- package/dist/src/debug/debug_store.d.ts +6 -6
- package/dist/src/debug/debug_store.d.ts.map +1 -1
- package/dist/src/debug/debug_store.js +10 -10
- package/dist/src/debug/email_collector.d.ts +0 -9
- package/dist/src/debug/email_collector.d.ts.map +1 -1
- package/dist/src/debug/email_collector.js +6 -28
- package/dist/src/debug/event_collector.d.ts +1 -1
- package/dist/src/debug/event_collector.d.ts.map +1 -1
- package/dist/src/debug/event_collector.js +17 -17
- package/dist/src/debug/query_collector.d.ts +1 -1
- package/dist/src/debug/query_collector.d.ts.map +1 -1
- package/dist/src/debug/query_collector.js +13 -14
- package/dist/src/debug/ring_buffer.d.ts.map +1 -1
- package/dist/src/debug/route_inspector.d.ts +1 -1
- package/dist/src/debug/route_inspector.d.ts.map +1 -1
- package/dist/src/debug/route_inspector.js +12 -12
- package/dist/src/debug/trace_collector.d.ts.map +1 -1
- package/dist/src/debug/trace_collector.js +6 -5
- package/dist/src/edge/client/dashboard.css +555 -165
- package/dist/src/edge/client/dashboard.js +2797 -1556
- package/dist/src/edge/client/debug-panel.css +476 -133
- package/dist/src/edge/client/debug-panel.js +1496 -1043
- package/dist/src/edge/client/stats-bar.css +64 -30
- package/dist/src/edge/client/stats-bar.js +598 -319
- package/dist/src/edge/plugin.d.ts +1 -1
- package/dist/src/edge/plugin.d.ts.map +1 -1
- package/dist/src/edge/plugin.js +41 -59
- package/dist/src/edge/views/stats-bar.edge +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/middleware/request_tracking_middleware.d.ts +4 -4
- package/dist/src/middleware/request_tracking_middleware.d.ts.map +1 -1
- package/dist/src/middleware/request_tracking_middleware.js +7 -6
- package/dist/src/prometheus/prometheus_collector.d.ts +1 -1
- package/dist/src/prometheus/prometheus_collector.d.ts.map +1 -1
- package/dist/src/provider/server_stats_provider.d.ts +1 -1
- package/dist/src/provider/server_stats_provider.d.ts.map +1 -1
- package/dist/src/provider/server_stats_provider.js +31 -31
- package/dist/src/utils/json_helpers.d.ts +8 -0
- package/dist/src/utils/json_helpers.d.ts.map +1 -0
- package/dist/src/utils/json_helpers.js +21 -0
- package/dist/src/utils/mail_helpers.d.ts +13 -0
- package/dist/src/utils/mail_helpers.d.ts.map +1 -0
- package/dist/src/utils/mail_helpers.js +26 -0
- package/dist/src/utils/math_helpers.d.ts +8 -0
- package/dist/src/utils/math_helpers.d.ts.map +1 -0
- package/dist/src/utils/math_helpers.js +11 -0
- package/dist/src/utils/time_helpers.d.ts +12 -0
- package/dist/src/utils/time_helpers.d.ts.map +1 -0
- package/dist/src/utils/time_helpers.js +32 -0
- package/dist/src/utils/transmit_client.d.ts +9 -0
- package/dist/src/utils/transmit_client.d.ts.map +1 -0
- package/dist/src/utils/transmit_client.js +20 -0
- package/package.json +35 -29
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { writeFile, readFile, rename, mkdir } from
|
|
2
|
-
import { dirname } from
|
|
3
|
-
import {
|
|
4
|
-
import { EventCollector } from
|
|
5
|
-
import {
|
|
6
|
-
import { RouteInspector } from
|
|
7
|
-
import { TraceCollector } from
|
|
1
|
+
import { writeFile, readFile, rename, mkdir } from 'node:fs/promises';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { EmailCollector } from './email_collector.js';
|
|
4
|
+
import { EventCollector } from './event_collector.js';
|
|
5
|
+
import { QueryCollector } from './query_collector.js';
|
|
6
|
+
import { RouteInspector } from './route_inspector.js';
|
|
7
|
+
import { TraceCollector } from './trace_collector.js';
|
|
8
8
|
/**
|
|
9
9
|
* Singleton store holding all debug data collectors.
|
|
10
10
|
* Bound to the AdonisJS container as `debug.store`.
|
|
@@ -56,16 +56,16 @@ export class DebugStore {
|
|
|
56
56
|
data.traces = this.traces.getTraces();
|
|
57
57
|
}
|
|
58
58
|
const json = JSON.stringify(data);
|
|
59
|
-
const tmpPath = filePath +
|
|
59
|
+
const tmpPath = filePath + '.tmp';
|
|
60
60
|
await mkdir(dirname(filePath), { recursive: true });
|
|
61
|
-
await writeFile(tmpPath, json,
|
|
61
|
+
await writeFile(tmpPath, json, 'utf-8');
|
|
62
62
|
await rename(tmpPath, filePath);
|
|
63
63
|
}
|
|
64
64
|
/** Restore collector data from a JSON file on disk. */
|
|
65
65
|
async loadFromDisk(filePath) {
|
|
66
66
|
let raw;
|
|
67
67
|
try {
|
|
68
|
-
raw = await readFile(filePath,
|
|
68
|
+
raw = await readFile(filePath, 'utf-8');
|
|
69
69
|
}
|
|
70
70
|
catch {
|
|
71
71
|
return; // file doesn't exist yet
|
|
@@ -21,18 +21,9 @@ export declare class EmailCollector {
|
|
|
21
21
|
getTotalCount(): number;
|
|
22
22
|
clear(): void;
|
|
23
23
|
private buildRecord;
|
|
24
|
-
/**
|
|
25
|
-
* Normalize various address formats to a comma-separated string.
|
|
26
|
-
*
|
|
27
|
-
* AdonisJS mail addresses can be:
|
|
28
|
-
* - A string: `"user@example.com"`
|
|
29
|
-
* - An object: `{ address: "user@example.com", name: "User" }`
|
|
30
|
-
* - An array of strings or objects
|
|
31
|
-
*/
|
|
32
24
|
/** Register a callback that fires whenever a new email is recorded. */
|
|
33
25
|
onNewItem(cb: ((item: EmailRecord) => void) | null): void;
|
|
34
26
|
/** Restore persisted records into the buffer and reset the ID counter. */
|
|
35
27
|
loadRecords(records: EmailRecord[]): void;
|
|
36
|
-
private extractAddresses;
|
|
37
28
|
}
|
|
38
29
|
//# sourceMappingURL=email_collector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email_collector.d.ts","sourceRoot":"","sources":["../../../src/debug/email_collector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"email_collector.d.ts","sourceRoot":"","sources":["../../../src/debug/email_collector.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,QAAQ,CAAmD;gBAEvD,SAAS,GAAE,MAAY;IAI7B,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAwDxC,IAAI,IAAI,IAAI;IAUZ,SAAS,IAAI,WAAW,EAAE;IAI1B,SAAS,CAAC,CAAC,GAAE,MAAY,GAAG,WAAW,EAAE;IAIzC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMvC,aAAa,IAAI,MAAM;IAIvB,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,WAAW;IAkBnB,uEAAuE;IACvE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;IAIzD,0EAA0E;IAC1E,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI;CAK1C"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { extractAddresses } from '../utils/mail_helpers.js';
|
|
1
2
|
import { RingBuffer } from './ring_buffer.js';
|
|
2
3
|
/**
|
|
3
4
|
* Listens to AdonisJS mail events and stores captured emails in a ring buffer.
|
|
@@ -26,7 +27,7 @@ export class EmailCollector {
|
|
|
26
27
|
};
|
|
27
28
|
const onSent = (data) => {
|
|
28
29
|
const msg = data?.message || data;
|
|
29
|
-
const to =
|
|
30
|
+
const to = extractAddresses(msg?.to);
|
|
30
31
|
const subject = msg?.subject || '';
|
|
31
32
|
// Try to find the matching 'sending' record and update it
|
|
32
33
|
const all = this.buffer.toArray();
|
|
@@ -92,10 +93,10 @@ export class EmailCollector {
|
|
|
92
93
|
buildRecord(msg, status, data) {
|
|
93
94
|
return {
|
|
94
95
|
id: this.buffer.getNextId(),
|
|
95
|
-
from:
|
|
96
|
-
to:
|
|
97
|
-
cc:
|
|
98
|
-
bcc:
|
|
96
|
+
from: extractAddresses(msg?.from) || 'unknown',
|
|
97
|
+
to: extractAddresses(msg?.to) || 'unknown',
|
|
98
|
+
cc: extractAddresses(msg?.cc) || null,
|
|
99
|
+
bcc: extractAddresses(msg?.bcc) || null,
|
|
99
100
|
subject: msg?.subject || '(no subject)',
|
|
100
101
|
html: msg?.html || null,
|
|
101
102
|
text: msg?.text || null,
|
|
@@ -106,14 +107,6 @@ export class EmailCollector {
|
|
|
106
107
|
timestamp: Date.now(),
|
|
107
108
|
};
|
|
108
109
|
}
|
|
109
|
-
/**
|
|
110
|
-
* Normalize various address formats to a comma-separated string.
|
|
111
|
-
*
|
|
112
|
-
* AdonisJS mail addresses can be:
|
|
113
|
-
* - A string: `"user@example.com"`
|
|
114
|
-
* - An object: `{ address: "user@example.com", name: "User" }`
|
|
115
|
-
* - An array of strings or objects
|
|
116
|
-
*/
|
|
117
110
|
/** Register a callback that fires whenever a new email is recorded. */
|
|
118
111
|
onNewItem(cb) {
|
|
119
112
|
this.buffer.onPush(cb);
|
|
@@ -124,19 +117,4 @@ export class EmailCollector {
|
|
|
124
117
|
const maxId = records.reduce((m, r) => Math.max(m, r.id), 0);
|
|
125
118
|
this.buffer.setNextId(maxId + 1);
|
|
126
119
|
}
|
|
127
|
-
extractAddresses(value) {
|
|
128
|
-
if (!value)
|
|
129
|
-
return '';
|
|
130
|
-
if (typeof value === 'string')
|
|
131
|
-
return value;
|
|
132
|
-
if (Array.isArray(value)) {
|
|
133
|
-
return value
|
|
134
|
-
.map((v) => (typeof v === 'string' ? v : v?.address || ''))
|
|
135
|
-
.filter(Boolean)
|
|
136
|
-
.join(', ');
|
|
137
|
-
}
|
|
138
|
-
if (typeof value === 'object' && value.address)
|
|
139
|
-
return value.address;
|
|
140
|
-
return '';
|
|
141
|
-
}
|
|
142
120
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event_collector.d.ts","sourceRoot":"","sources":["../../../src/debug/event_collector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"event_collector.d.ts","sourceRoot":"","sources":["../../../src/debug/event_collector.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,YAAY,CAAyC;IAC7D,OAAO,CAAC,OAAO,CAAY;gBAEf,SAAS,GAAE,MAAY;IAInC,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAmCzB,IAAI,IAAI,IAAI;IAQZ,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,YAAY;IAapB,SAAS,IAAI,WAAW,EAAE;IAI1B,SAAS,CAAC,CAAC,GAAE,MAAY,GAAG,WAAW,EAAE;IAIzC,aAAa,IAAI,MAAM;IAIvB,KAAK,IAAI,IAAI;IAIb,uEAAuE;IACvE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;IAIzD,0EAA0E;IAC1E,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI;CAK1C"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isExcludedRequest } from '../middleware/request_tracking_middleware.js';
|
|
2
|
+
import { RingBuffer } from './ring_buffer.js';
|
|
3
3
|
/**
|
|
4
4
|
* Wraps the AdonisJS emitter to log all events with timestamps.
|
|
5
5
|
* Uses monkey-patching of emitter.emit to intercept all events.
|
|
@@ -12,22 +12,22 @@ export class EventCollector {
|
|
|
12
12
|
this.buffer = new RingBuffer(maxEvents);
|
|
13
13
|
}
|
|
14
14
|
start(emitter) {
|
|
15
|
-
if (!emitter || typeof emitter.emit !==
|
|
15
|
+
if (!emitter || typeof emitter.emit !== 'function')
|
|
16
16
|
return;
|
|
17
17
|
this.emitter = emitter;
|
|
18
18
|
this.originalEmit = emitter.emit.bind(emitter);
|
|
19
19
|
const self = this;
|
|
20
20
|
emitter.emit = function (event, data) {
|
|
21
21
|
// Resolve event name: class-based events use the class name, string events are used as-is
|
|
22
|
-
const eventName = typeof event ===
|
|
22
|
+
const eventName = typeof event === 'string' ? event : event?.name || 'unknown';
|
|
23
23
|
// Skip internal/noisy events, mail events (handled by EmailCollector),
|
|
24
24
|
// HTTP lifecycle events (redundant with timeline), and events triggered
|
|
25
25
|
// by debug panel polling requests
|
|
26
|
-
if (!eventName.startsWith(
|
|
27
|
-
eventName !==
|
|
28
|
-
!eventName.startsWith(
|
|
29
|
-
eventName !==
|
|
30
|
-
eventName !==
|
|
26
|
+
if (!eventName.startsWith('__') &&
|
|
27
|
+
eventName !== 'db:query' &&
|
|
28
|
+
!eventName.startsWith('mail:') &&
|
|
29
|
+
eventName !== 'queued:mail:error' &&
|
|
30
|
+
eventName !== 'http:request_completed' &&
|
|
31
31
|
!isExcludedRequest()) {
|
|
32
32
|
const record = {
|
|
33
33
|
id: self.buffer.getNextId(),
|
|
@@ -51,14 +51,14 @@ export class EventCollector {
|
|
|
51
51
|
if (data === undefined || data === null)
|
|
52
52
|
return null;
|
|
53
53
|
try {
|
|
54
|
-
if (typeof data ===
|
|
54
|
+
if (typeof data === 'string')
|
|
55
55
|
return data;
|
|
56
56
|
const json = JSON.stringify(data, this.safeReplacer(), 2);
|
|
57
57
|
// Cap at 4KB per event to avoid memory bloat
|
|
58
|
-
return json.length > 4096 ? json.slice(0, 4096) +
|
|
58
|
+
return json.length > 4096 ? json.slice(0, 4096) + '\n...' : json;
|
|
59
59
|
}
|
|
60
60
|
catch {
|
|
61
|
-
if (typeof data ===
|
|
61
|
+
if (typeof data === 'object' && data.constructor?.name) {
|
|
62
62
|
return `[${data.constructor.name}]`;
|
|
63
63
|
}
|
|
64
64
|
return typeof data;
|
|
@@ -67,14 +67,14 @@ export class EventCollector {
|
|
|
67
67
|
safeReplacer() {
|
|
68
68
|
const seen = new WeakSet();
|
|
69
69
|
return (_key, value) => {
|
|
70
|
-
if (typeof value ===
|
|
70
|
+
if (typeof value === 'object' && value !== null) {
|
|
71
71
|
if (seen.has(value))
|
|
72
|
-
return
|
|
72
|
+
return '[Circular]';
|
|
73
73
|
seen.add(value);
|
|
74
74
|
}
|
|
75
|
-
if (typeof value ===
|
|
76
|
-
return `[Function: ${value.name ||
|
|
77
|
-
if (typeof value ===
|
|
75
|
+
if (typeof value === 'function')
|
|
76
|
+
return `[Function: ${value.name || 'anonymous'}]`;
|
|
77
|
+
if (typeof value === 'bigint')
|
|
78
78
|
return value.toString();
|
|
79
79
|
return value;
|
|
80
80
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query_collector.d.ts","sourceRoot":"","sources":["../../../src/debug/query_collector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"query_collector.d.ts","sourceRoot":"","sources":["../../../src/debug/query_collector.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,OAAO,CAAqC;gBAExC,UAAU,GAAE,MAAY,EAAE,eAAe,GAAE,MAAY;IAK7D,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCxC,IAAI,IAAI,IAAI;IAQZ,UAAU,IAAI,WAAW,EAAE;IAI3B,SAAS,CAAC,CAAC,GAAE,MAAY,GAAG,WAAW,EAAE;IAIzC,UAAU;;;;;;IAqBV,aAAa,IAAI,MAAM;IAIvB,KAAK,IAAI,IAAI;IAIb,uEAAuE;IACvE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;IAIzD,0EAA0E;IAC1E,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI;CAK1C"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isExcludedRequest } from '../middleware/request_tracking_middleware.js';
|
|
2
|
+
import { round } from '../utils/math_helpers.js';
|
|
3
|
+
import { RingBuffer } from './ring_buffer.js';
|
|
3
4
|
/**
|
|
4
5
|
* Listens to Lucid's `db:query` event and stores queries in a ring buffer.
|
|
5
6
|
*
|
|
@@ -24,33 +25,31 @@ export class QueryCollector {
|
|
|
24
25
|
// Self-exclude: skip queries triggered by debug panel polling requests
|
|
25
26
|
if (isExcludedRequest())
|
|
26
27
|
return;
|
|
27
|
-
const duration = typeof data.duration ===
|
|
28
|
+
const duration = typeof data.duration === 'number'
|
|
28
29
|
? data.duration
|
|
29
30
|
: Array.isArray(data.duration)
|
|
30
31
|
? data.duration[0] * 1e3 + data.duration[1] / 1e6
|
|
31
32
|
: 0;
|
|
32
33
|
const record = {
|
|
33
34
|
id: this.buffer.getNextId(),
|
|
34
|
-
sql: data.sql ||
|
|
35
|
+
sql: data.sql || '',
|
|
35
36
|
bindings: data.bindings || [],
|
|
36
|
-
duration:
|
|
37
|
-
method: data.method ||
|
|
37
|
+
duration: round(duration),
|
|
38
|
+
method: data.method || 'unknown',
|
|
38
39
|
model: data.model || null,
|
|
39
|
-
connection: data.connection ||
|
|
40
|
+
connection: data.connection || 'default',
|
|
40
41
|
inTransaction: data.inTransaction || false,
|
|
41
42
|
timestamp: Date.now(),
|
|
42
43
|
};
|
|
43
44
|
this.buffer.push(record);
|
|
44
45
|
};
|
|
45
|
-
if (emitter && typeof emitter.on ===
|
|
46
|
-
emitter.on(
|
|
46
|
+
if (emitter && typeof emitter.on === 'function') {
|
|
47
|
+
emitter.on('db:query', this.handler);
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
stop() {
|
|
50
|
-
if (this.emitter &&
|
|
51
|
-
this.handler
|
|
52
|
-
typeof this.emitter.off === "function") {
|
|
53
|
-
this.emitter.off("db:query", this.handler);
|
|
51
|
+
if (this.emitter && this.handler && typeof this.emitter.off === 'function') {
|
|
52
|
+
this.emitter.off('db:query', this.handler);
|
|
54
53
|
}
|
|
55
54
|
this.handler = null;
|
|
56
55
|
this.emitter = null;
|
|
@@ -75,7 +74,7 @@ export class QueryCollector {
|
|
|
75
74
|
total,
|
|
76
75
|
slow,
|
|
77
76
|
duplicates,
|
|
78
|
-
avgDuration:
|
|
77
|
+
avgDuration: round(avgDuration),
|
|
79
78
|
};
|
|
80
79
|
}
|
|
81
80
|
getTotalCount() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ring_buffer.d.ts","sourceRoot":"","sources":["../../../src/debug/ring_buffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,UAAU,CAAC,CAAC;IAOX,OAAO,CAAC,QAAQ;IAN5B,OAAO,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"ring_buffer.d.ts","sourceRoot":"","sources":["../../../src/debug/ring_buffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,UAAU,CAAC,CAAC;IAOX,OAAO,CAAC,QAAQ;IAN5B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,IAAI,CAAY;IACxB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,YAAY,CAAmC;gBAEnC,QAAQ,EAAE,MAAM;IAIpC,oEAAoE;IACpE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;IAI5C,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IASnB,2DAA2D;IAC3D,OAAO,IAAI,CAAC,EAAE;IAcd,sDAAsD;IACtD,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE;IAKtB,SAAS,IAAI,MAAM;IAInB,IAAI,IAAI,MAAM;IAId,KAAK,IAAI,IAAI;IAMb,mFAAmF;IACnF,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI;IAMtB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;CAG5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route_inspector.d.ts","sourceRoot":"","sources":["../../../src/debug/route_inspector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"route_inspector.d.ts","sourceRoot":"","sources":["../../../src/debug/route_inspector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAoB;IAElC;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI;IAoC1B,OAAO,CAAC,cAAc;IAoBtB,OAAO,CAAC,iBAAiB;IA2BzB,SAAS,IAAI,WAAW,EAAE;IAI1B,aAAa,IAAI,MAAM;CAGxB"}
|
|
@@ -20,14 +20,14 @@ export class RouteInspector {
|
|
|
20
20
|
continue;
|
|
21
21
|
for (const route of domainRoutes) {
|
|
22
22
|
const methods = Array.isArray(route.methods)
|
|
23
|
-
? route.methods.filter((m) => m !==
|
|
23
|
+
? route.methods.filter((m) => m !== 'HEAD')
|
|
24
24
|
: [];
|
|
25
25
|
const handler = this.resolveHandler(route.handler);
|
|
26
26
|
const middlewareList = this.resolveMiddleware(route.middleware);
|
|
27
27
|
for (const method of methods) {
|
|
28
28
|
this.routes.push({
|
|
29
29
|
method,
|
|
30
|
-
pattern: route.pattern ||
|
|
30
|
+
pattern: route.pattern || '/',
|
|
31
31
|
name: route.name || null,
|
|
32
32
|
handler,
|
|
33
33
|
middleware: middlewareList,
|
|
@@ -42,15 +42,15 @@ export class RouteInspector {
|
|
|
42
42
|
}
|
|
43
43
|
resolveHandler(handler) {
|
|
44
44
|
if (!handler)
|
|
45
|
-
return
|
|
46
|
-
if (typeof handler ===
|
|
45
|
+
return 'unknown';
|
|
46
|
+
if (typeof handler === 'string')
|
|
47
47
|
return handler;
|
|
48
|
-
if (typeof handler ===
|
|
49
|
-
return handler.name ||
|
|
48
|
+
if (typeof handler === 'function')
|
|
49
|
+
return handler.name || 'closure';
|
|
50
50
|
// Lazy import handler
|
|
51
51
|
if (handler.reference) {
|
|
52
52
|
const ref = handler.reference;
|
|
53
|
-
if (typeof ref ===
|
|
53
|
+
if (typeof ref === 'string')
|
|
54
54
|
return ref;
|
|
55
55
|
if (Array.isArray(ref) && ref.length >= 2) {
|
|
56
56
|
return `${ref[0]}#${ref[1]}`;
|
|
@@ -59,29 +59,29 @@ export class RouteInspector {
|
|
|
59
59
|
// Handle object with name
|
|
60
60
|
if (handler.name)
|
|
61
61
|
return handler.name;
|
|
62
|
-
return
|
|
62
|
+
return 'unknown';
|
|
63
63
|
}
|
|
64
64
|
resolveMiddleware(middleware) {
|
|
65
65
|
if (!middleware)
|
|
66
66
|
return [];
|
|
67
67
|
// AdonisJS v6 middleware is a Middleware instance from @poppinss/middleware.
|
|
68
68
|
// Call .all() to get the Set of middleware items.
|
|
69
|
-
const items = typeof middleware.all ===
|
|
69
|
+
const items = typeof middleware.all === 'function'
|
|
70
70
|
? middleware.all()
|
|
71
71
|
: Array.isArray(middleware)
|
|
72
72
|
? middleware
|
|
73
73
|
: [];
|
|
74
74
|
const result = [];
|
|
75
75
|
for (const m of items) {
|
|
76
|
-
if (typeof m ===
|
|
76
|
+
if (typeof m === 'string') {
|
|
77
77
|
result.push(m);
|
|
78
78
|
}
|
|
79
|
-
else if (typeof m ===
|
|
79
|
+
else if (typeof m === 'function') {
|
|
80
80
|
if (m.name)
|
|
81
81
|
result.push(m.name);
|
|
82
82
|
}
|
|
83
83
|
else if (m?.name) {
|
|
84
|
-
const args = m.args?.length ? `(${JSON.stringify(m.args).slice(1, -1)})` :
|
|
84
|
+
const args = m.args?.length ? `(${JSON.stringify(m.args).slice(1, -1)})` : '';
|
|
85
85
|
result.push(m.name + args);
|
|
86
86
|
}
|
|
87
87
|
// Skip unnamed global middleware (router.use lazy imports) — same for every route
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace_collector.d.ts","sourceRoot":"","sources":["../../../src/debug/trace_collector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"trace_collector.d.ts","sourceRoot":"","sources":["../../../src/debug/trace_collector.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAmBxD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAG9E;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,GAAG,CAAwC;IACnD,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,mBAAmB,CAAmC;gBAElD,SAAS,GAAE,MAAY;IAKnC,qDAAqD;IACrD,UAAU,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxD,0GAA0G;IAC1G,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAsBhF,mDAAmD;IACnD,OAAO,CACL,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,EAC/B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,IAAI;IAeP,+DAA+D;IACzD,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAyB/F,uEAAuE;IACvE,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAsCzB,uDAAuD;IACvD,IAAI,IAAI,IAAI;IAaZ,SAAS,IAAI,WAAW,EAAE;IAI1B,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE;IAInC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAI7C,aAAa,IAAI,MAAM;IAIvB,KAAK,IAAI,IAAI;IAIb,uEAAuE;IACvE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;IAIzD,0EAA0E;IAC1E,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI;CAK1C"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
2
|
import { performance } from 'node:perf_hooks';
|
|
3
|
+
import { round } from '../utils/math_helpers.js';
|
|
3
4
|
import { RingBuffer } from './ring_buffer.js';
|
|
4
5
|
/**
|
|
5
6
|
* Module-level singleton reference for the `trace()` helper.
|
|
@@ -63,7 +64,7 @@ export class TraceCollector {
|
|
|
63
64
|
method,
|
|
64
65
|
url,
|
|
65
66
|
statusCode,
|
|
66
|
-
totalDuration:
|
|
67
|
+
totalDuration: round(totalDuration),
|
|
67
68
|
spanCount: ctx.spans.length,
|
|
68
69
|
spans: ctx.spans,
|
|
69
70
|
warnings: ctx.warnings,
|
|
@@ -82,8 +83,8 @@ export class TraceCollector {
|
|
|
82
83
|
parentId: ctx.currentSpanId,
|
|
83
84
|
label,
|
|
84
85
|
category,
|
|
85
|
-
startOffset:
|
|
86
|
-
duration:
|
|
86
|
+
startOffset: round(startOffset),
|
|
87
|
+
duration: round(duration),
|
|
87
88
|
metadata,
|
|
88
89
|
});
|
|
89
90
|
}
|
|
@@ -106,8 +107,8 @@ export class TraceCollector {
|
|
|
106
107
|
parentId,
|
|
107
108
|
label,
|
|
108
109
|
category,
|
|
109
|
-
startOffset:
|
|
110
|
-
duration:
|
|
110
|
+
startOffset: round(start - ctx.requestStart),
|
|
111
|
+
duration: round(duration),
|
|
111
112
|
});
|
|
112
113
|
ctx.currentSpanId = parentId;
|
|
113
114
|
}
|