adonisjs-server-stats 1.10.0 → 1.10.3
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 +23 -14
- package/dist/core/config-utils.d.ts +8 -0
- package/dist/core/constants.d.ts +4 -0
- package/dist/core/dashboard-data-controller.d.ts +16 -0
- package/dist/core/dashboard-data-helpers.d.ts +12 -0
- package/dist/core/debug-data-controller.d.ts +4 -0
- package/dist/core/define-config-helpers.d.ts +25 -0
- package/dist/core/feature-detect-helpers.d.ts +36 -0
- package/dist/core/formatters-helpers.d.ts +23 -0
- package/dist/core/index.js +594 -509
- package/dist/core/log-utils-helpers.d.ts +13 -0
- package/dist/core/metrics.d.ts +3 -28
- package/dist/core/pagination.d.ts +0 -9
- package/dist/core/server-stats-controller.d.ts +6 -0
- package/dist/core/transmit-helpers.d.ts +7 -0
- package/dist/core/types-dashboard.d.ts +178 -0
- package/dist/core/types-diagnostics.d.ts +85 -0
- package/dist/core/types.d.ts +10 -442
- package/dist/react/{CacheSection-UCMptWyn.js → CacheSection-baMZotSn.js} +2 -2
- package/dist/react/CacheTab-2cw_rMzj.js +117 -0
- package/dist/react/{ConfigSection-DfFd-WRq.js → ConfigSection-DGgqjAal.js} +1 -1
- package/dist/react/{ConfigTab-Bdg8YMer.js → ConfigTab-H3OnYqmK.js} +1 -1
- package/dist/react/CustomPaneTab-B6r7ha0u.js +98 -0
- package/dist/react/{EmailsSection-CM7stSyh.js → EmailsSection-C-UZISG-.js} +2 -2
- package/dist/react/EmailsTab-DbK4Eobn.js +139 -0
- package/dist/react/{EventsSection-ByQ-9blq.js → EventsSection-C7RQW_LY.js} +2 -2
- package/dist/react/EventsTab-CfVr7AiM.js +57 -0
- package/dist/react/{FilterBar-DQRXpWrb.js → FilterBar-CQ7bD669.js} +15 -15
- package/dist/react/{JobsSection-DF3qEv9O.js → JobsSection-CQHNK_Ls.js} +2 -2
- package/dist/react/{JobsTab-BbrBWIOb.js → JobsTab-znzf6jzk.js} +54 -42
- package/dist/react/{LogsSection-DcFTZY7b.js → LogsSection-Dmm3rE2B.js} +9 -3
- package/dist/react/LogsTab-D8unMV5P.js +108 -0
- package/dist/react/{OverviewSection-C4T1ur51.js → OverviewSection-ABP9ueBo.js} +1 -1
- package/dist/react/{QueriesSection-PswteoF9.js → QueriesSection-CnmSkznA.js} +2 -2
- package/dist/react/{QueriesTab-osLUWd4L.js → QueriesTab-BQzcxEiW.js} +37 -40
- package/dist/react/{RelatedLogs-DFDOyUMr.js → RelatedLogs-3A8RuGKH.js} +15 -3
- package/dist/react/{RequestsSection-Nag30rEA.js → RequestsSection-kW79_M7k.js} +3 -3
- package/dist/react/{RoutesSection-BUSkM6PY.js → RoutesSection-BRhxrtjZ.js} +2 -2
- package/dist/react/RoutesTab-CpYH5lUw.js +68 -0
- package/dist/react/{TimelineTab-Covg5weo.js → TimelineTab-DjLR35Ce.js} +47 -53
- package/dist/react/index-CsImORX6.js +1121 -0
- package/dist/react/index.js +1 -1
- package/dist/react/react/components/{Dashboard/shared → shared}/FilterBar.d.ts +4 -3
- package/dist/react/react/hooks/useDashboardData.d.ts +4 -8
- package/dist/react/style.css +1 -1
- package/dist/src/collectors/app_collector.d.ts +0 -8
- package/dist/src/collectors/app_collector.js +45 -52
- package/dist/src/collectors/auto_detect.d.ts +0 -23
- package/dist/src/collectors/auto_detect.js +33 -55
- package/dist/src/collectors/db_pool_collector.d.ts +14 -16
- package/dist/src/collectors/db_pool_collector.js +72 -57
- package/dist/src/collectors/log_collector.d.ts +0 -47
- package/dist/src/collectors/log_collector.js +36 -65
- package/dist/src/collectors/queue_collector.d.ts +0 -20
- package/dist/src/collectors/queue_collector.js +60 -76
- package/dist/src/collectors/redis_collector.d.ts +10 -10
- package/dist/src/collectors/redis_collector.js +69 -66
- package/dist/src/config/deprecation_migration.d.ts +7 -0
- package/dist/src/config/deprecation_migration.js +201 -0
- package/dist/src/controller/debug_controller.d.ts +1 -1
- package/dist/src/controller/debug_controller.js +87 -81
- package/dist/src/dashboard/cache_handlers.d.ts +14 -0
- package/dist/src/dashboard/cache_handlers.js +52 -0
- package/dist/src/dashboard/chart_aggregator.d.ts +0 -7
- package/dist/src/dashboard/chart_aggregator.js +68 -50
- package/dist/src/dashboard/coalesce_cache.d.ts +25 -0
- package/dist/src/dashboard/coalesce_cache.js +47 -0
- package/dist/src/dashboard/dashboard_controller.d.ts +11 -37
- package/dist/src/dashboard/dashboard_controller.js +51 -544
- package/dist/src/dashboard/dashboard_page_assets.d.ts +17 -0
- package/dist/src/dashboard/dashboard_page_assets.js +51 -0
- package/dist/src/dashboard/dashboard_store.d.ts +19 -218
- package/dist/src/dashboard/dashboard_store.js +115 -1116
- package/dist/src/dashboard/dashboard_types.d.ts +83 -0
- package/dist/src/dashboard/dashboard_types.js +4 -0
- package/dist/src/dashboard/detail_queries.d.ts +19 -0
- package/dist/src/dashboard/detail_queries.js +98 -0
- package/dist/src/dashboard/email_event_builder.d.ts +8 -0
- package/dist/src/dashboard/email_event_builder.js +65 -0
- package/dist/src/dashboard/explain_query.d.ts +8 -0
- package/dist/src/dashboard/explain_query.js +22 -0
- package/dist/src/dashboard/filter_handlers.d.ts +23 -0
- package/dist/src/dashboard/filter_handlers.js +56 -0
- package/dist/src/dashboard/filtered_queries.d.ts +15 -0
- package/dist/src/dashboard/filtered_queries.js +155 -0
- package/dist/src/dashboard/flush_manager.d.ts +25 -0
- package/dist/src/dashboard/flush_manager.js +107 -0
- package/dist/src/dashboard/format_helpers.d.ts +126 -0
- package/dist/src/dashboard/format_helpers.js +140 -0
- package/dist/src/dashboard/inspector_manager.d.ts +36 -0
- package/dist/src/dashboard/inspector_manager.js +102 -0
- package/dist/src/dashboard/integrations/config_inspector.js +11 -13
- package/dist/src/dashboard/integrations/queue_inspector.d.ts +3 -3
- package/dist/src/dashboard/integrations/queue_inspector.js +13 -10
- package/dist/src/dashboard/jobs_handlers.d.ts +14 -0
- package/dist/src/dashboard/jobs_handlers.js +61 -0
- package/dist/src/dashboard/knex_factory.d.ts +18 -0
- package/dist/src/dashboard/knex_factory.js +91 -0
- package/dist/src/dashboard/migrator.js +30 -159
- package/dist/src/dashboard/migrator_tables.d.ts +19 -0
- package/dist/src/dashboard/migrator_tables.js +153 -0
- package/dist/src/dashboard/overview_queries.d.ts +66 -0
- package/dist/src/dashboard/overview_queries.js +155 -0
- package/dist/src/dashboard/overview_query_runners.d.ts +25 -0
- package/dist/src/dashboard/overview_query_runners.js +84 -0
- package/dist/src/dashboard/overview_store_queries.d.ts +40 -0
- package/dist/src/dashboard/overview_store_queries.js +69 -0
- package/dist/src/dashboard/paginate_helper.d.ts +12 -0
- package/dist/src/dashboard/paginate_helper.js +33 -0
- package/dist/src/dashboard/query_explain_handler.d.ts +10 -0
- package/dist/src/dashboard/query_explain_handler.js +80 -0
- package/dist/src/dashboard/read_queries.d.ts +32 -0
- package/dist/src/dashboard/read_queries.js +107 -0
- package/dist/src/dashboard/saved_filter_queries.d.ts +10 -0
- package/dist/src/dashboard/saved_filter_queries.js +24 -0
- package/dist/src/dashboard/storage_stats.d.ts +41 -0
- package/dist/src/dashboard/storage_stats.js +81 -0
- package/dist/src/dashboard/write_queue.d.ts +106 -0
- package/dist/src/dashboard/write_queue.js +225 -0
- package/dist/src/data/data_access.d.ts +2 -39
- package/dist/src/data/data_access.js +17 -193
- package/dist/src/data/data_access_helpers.d.ts +130 -0
- package/dist/src/data/data_access_helpers.js +212 -0
- package/dist/src/debug/debug_store.js +37 -32
- package/dist/src/debug/email_collector.d.ts +1 -10
- package/dist/src/debug/email_collector.js +78 -81
- package/dist/src/debug/event_collector.d.ts +0 -9
- package/dist/src/debug/event_collector.js +79 -62
- package/dist/src/debug/query_collector.js +23 -19
- package/dist/src/debug/route_inspector.d.ts +1 -5
- package/dist/src/debug/route_inspector.js +50 -51
- package/dist/src/debug/trace_collector.d.ts +9 -1
- package/dist/src/debug/trace_collector.js +21 -15
- package/dist/src/debug/types.d.ts +1 -1
- package/dist/src/define_config.d.ts +0 -65
- package/dist/src/define_config.js +93 -333
- package/dist/src/edge/client/dashboard.js +2 -2
- package/dist/src/edge/client/debug-panel-deferred.js +1 -1
- package/dist/src/edge/client/stats-bar.js +1 -1
- package/dist/src/edge/client-vue/dashboard.js +5 -5
- package/dist/src/edge/client-vue/debug-panel-deferred.js +3 -3
- package/dist/src/edge/client-vue/stats-bar.js +3 -3
- package/dist/src/edge/plugin.d.ts +0 -16
- package/dist/src/edge/plugin.js +57 -64
- package/dist/src/engine/request_metrics.d.ts +1 -0
- package/dist/src/engine/request_metrics.js +32 -42
- package/dist/src/middleware/request_tracking_middleware.d.ts +2 -8
- package/dist/src/middleware/request_tracking_middleware.js +65 -93
- package/dist/src/provider/auth_middleware_detector.d.ts +16 -0
- package/dist/src/provider/auth_middleware_detector.js +97 -0
- package/dist/src/provider/boot_helpers.d.ts +20 -0
- package/dist/src/provider/boot_helpers.js +91 -0
- package/dist/src/provider/boot_initializer.d.ts +28 -0
- package/dist/src/provider/boot_initializer.js +35 -0
- package/dist/src/provider/dashboard_init.d.ts +30 -0
- package/dist/src/provider/dashboard_init.js +138 -0
- package/dist/src/provider/dashboard_setup.d.ts +25 -0
- package/dist/src/provider/dashboard_setup.js +78 -0
- package/dist/src/provider/diagnostics.d.ts +134 -0
- package/dist/src/provider/diagnostics.js +127 -0
- package/dist/src/provider/email_bridge.d.ts +43 -0
- package/dist/src/provider/email_bridge.js +80 -0
- package/dist/src/provider/email_helpers.d.ts +13 -0
- package/dist/src/provider/email_helpers.js +68 -0
- package/dist/src/provider/pino_hook.d.ts +17 -0
- package/dist/src/provider/pino_hook.js +35 -0
- package/dist/src/provider/provider_helpers_extra.d.ts +47 -0
- package/dist/src/provider/provider_helpers_extra.js +177 -0
- package/dist/src/provider/server_stats_provider.d.ts +39 -85
- package/dist/src/provider/server_stats_provider.js +132 -951
- package/dist/src/provider/shutdown_helpers.d.ts +43 -0
- package/dist/src/provider/shutdown_helpers.js +70 -0
- package/dist/src/provider/toolbar_setup.d.ts +57 -0
- package/dist/src/provider/toolbar_setup.js +141 -0
- package/dist/src/routes/dashboard_routes.d.ts +14 -0
- package/dist/src/routes/dashboard_routes.js +197 -0
- package/dist/src/routes/debug_routes.d.ts +14 -0
- package/dist/src/routes/debug_routes.js +101 -0
- package/dist/src/routes/register_routes.d.ts +0 -78
- package/dist/src/routes/register_routes.js +22 -352
- package/dist/src/routes/stats_routes.d.ts +5 -0
- package/dist/src/routes/stats_routes.js +14 -0
- package/dist/src/styles/components.css +96 -0
- package/dist/src/styles/dashboard.css +8 -90
- package/dist/src/styles/debug-panel.css +1 -31
- package/dist/src/types.d.ts +305 -14
- package/dist/vue/{CacheSection-oFAJL3mo.js → CacheSection-ITqvpfH5.js} +1 -1
- package/dist/vue/{ConfigSection-BhfJ4KqL.js → ConfigSection-DTn3GslE.js} +1 -1
- package/dist/vue/{EmailsSection-BcNyhyHs.js → EmailsSection-DtLJ4XoS.js} +1 -1
- package/dist/vue/{EventsSection-r60Q5Lmu.js → EventsSection-BOYYz0Ty.js} +1 -1
- package/dist/vue/{JobsSection-BHL-hkQw.js → JobsSection-BazTxcJL.js} +1 -1
- package/dist/vue/{LogsSection-DRMGzJmg.js → LogsSection-D55PjTKX.js} +9 -3
- package/dist/vue/{LogsTab-Bg3o0Mm6.js → LogsTab-47zEK7jL.js} +4 -1
- package/dist/vue/{OverviewSection-CXh6Ja1B.js → OverviewSection-1uBKo-Tu.js} +1 -1
- package/dist/vue/{QueriesSection-IodIsCJ-.js → QueriesSection-rpoZ4ogd.js} +1 -1
- package/dist/vue/{RequestsSection-BPuMdmMc.js → RequestsSection-x7LvT0MC.js} +1 -1
- package/dist/vue/{RoutesSection-NKo3Rbq3.js → RoutesSection-CCD0zZqQ.js} +1 -1
- package/dist/vue/composables/useDashboardData.d.ts +12 -23
- package/dist/vue/index-C8MxnS7Q.js +1232 -0
- package/dist/vue/index.js +1 -1
- package/dist/vue/style.css +1 -1
- package/package.json +1 -1
- package/dist/react/CacheTab-CA8LB1J5.js +0 -123
- package/dist/react/CustomPaneTab-Bxtv_8Rw.js +0 -104
- package/dist/react/EmailsTab-BDhEiomM.js +0 -153
- package/dist/react/EventsTab-CMfY98Rl.js +0 -63
- package/dist/react/LogsTab-CicucmVk.js +0 -103
- package/dist/react/RoutesTab-DgVzd2PZ.js +0 -74
- package/dist/react/index-Cflz9Ebj.js +0 -1069
- package/dist/vue/index-Dtgysd26.js +0 -1229
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email bridge helpers for cross-process email capture via Redis pub/sub.
|
|
3
|
+
*/
|
|
4
|
+
/** Minimal emitter interface. */
|
|
5
|
+
interface BridgeEmitter {
|
|
6
|
+
on(event: string, handler: (...args: unknown[]) => void): void;
|
|
7
|
+
}
|
|
8
|
+
/** Minimal Redis publisher interface. */
|
|
9
|
+
interface RedisPublisher {
|
|
10
|
+
publish(channel: string, message: string): Promise<unknown>;
|
|
11
|
+
}
|
|
12
|
+
/** Minimal Redis subscriber interface. */
|
|
13
|
+
interface RedisSubscriber extends RedisPublisher {
|
|
14
|
+
subscribe(channel: string, handler: (message: string) => void): unknown;
|
|
15
|
+
}
|
|
16
|
+
/** Targets for ingesting remote emails. */
|
|
17
|
+
export interface EmailBridgeTargets {
|
|
18
|
+
debugEmails: {
|
|
19
|
+
ingest(record: Record<string, unknown>): void;
|
|
20
|
+
} | null;
|
|
21
|
+
dashboardStore: {
|
|
22
|
+
recordEmail(record: Record<string, unknown>): void;
|
|
23
|
+
} | null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Ingest a remote email message from Redis pub/sub.
|
|
27
|
+
* Skips messages from the same process.
|
|
28
|
+
*/
|
|
29
|
+
export declare function ingestRemoteEmail(message: string, processTag: string, targets: EmailBridgeTargets): void;
|
|
30
|
+
/**
|
|
31
|
+
* Register mail event listeners that publish to Redis.
|
|
32
|
+
*/
|
|
33
|
+
export declare function registerMailEventPublisher(emitter: BridgeEmitter, redis: RedisPublisher, processTag: string, channel: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Full email bridge setup: publish local events + subscribe to remote ones.
|
|
36
|
+
* Returns the Redis instance (for cleanup) or null.
|
|
37
|
+
*/
|
|
38
|
+
export declare function setupFullEmailBridge(emitter: BridgeEmitter, redis: RedisSubscriber, channel: string, targets: EmailBridgeTargets): Promise<unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Lightweight publisher-only email bridge (for non-web environments).
|
|
41
|
+
*/
|
|
42
|
+
export declare function setupPublisherOnlyBridge(emitter: BridgeEmitter, redis: RedisPublisher, channel: string): void;
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email bridge helpers for cross-process email capture via Redis pub/sub.
|
|
3
|
+
*/
|
|
4
|
+
import { log } from '../utils/logger.js';
|
|
5
|
+
import { buildEmailPayload, MAIL_STATUS_MAP } from './email_helpers.js';
|
|
6
|
+
/**
|
|
7
|
+
* Ingest a remote email message from Redis pub/sub.
|
|
8
|
+
* Skips messages from the same process.
|
|
9
|
+
*/
|
|
10
|
+
export function ingestRemoteEmail(message, processTag, targets) {
|
|
11
|
+
try {
|
|
12
|
+
const parsed = JSON.parse(message);
|
|
13
|
+
if (parsed._t === processTag)
|
|
14
|
+
return;
|
|
15
|
+
const { _t: _, ...fields } = parsed;
|
|
16
|
+
const record = {
|
|
17
|
+
...fields,
|
|
18
|
+
html: fields.html || null,
|
|
19
|
+
text: fields.text || null,
|
|
20
|
+
};
|
|
21
|
+
targets.debugEmails?.ingest(record);
|
|
22
|
+
targets.dashboardStore?.recordEmail({ id: 0, ...record });
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// Ignore malformed messages
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Register mail event listeners that publish to Redis.
|
|
30
|
+
*/
|
|
31
|
+
export function registerMailEventPublisher(emitter, redis, processTag, channel) {
|
|
32
|
+
for (const [event, status] of MAIL_STATUS_MAP) {
|
|
33
|
+
emitter.on(event, (data) => {
|
|
34
|
+
try {
|
|
35
|
+
const payload = JSON.stringify(buildEmailPayload(data, status, processTag));
|
|
36
|
+
redis.publish(channel, payload).catch(() => { });
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Silently ignore serialization errors
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Subscribe to Redis channel for cross-process email capture.
|
|
46
|
+
*/
|
|
47
|
+
async function subscribeToEmailBridge(opts) {
|
|
48
|
+
try {
|
|
49
|
+
await opts.redis.subscribe(opts.channel, (message) => {
|
|
50
|
+
ingestRemoteEmail(message, opts.processTag, opts.targets);
|
|
51
|
+
});
|
|
52
|
+
log.info('email bridge active (cross-process capture via Redis)');
|
|
53
|
+
return opts.redis;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Full email bridge setup: publish local events + subscribe to remote ones.
|
|
61
|
+
* Returns the Redis instance (for cleanup) or null.
|
|
62
|
+
*/
|
|
63
|
+
export async function setupFullEmailBridge(emitter, redis, channel, targets) {
|
|
64
|
+
const processTag = `${process.pid}-${Date.now()}`;
|
|
65
|
+
registerMailEventPublisher(emitter, redis, processTag, channel);
|
|
66
|
+
return subscribeToEmailBridge({
|
|
67
|
+
redis,
|
|
68
|
+
channel,
|
|
69
|
+
processTag,
|
|
70
|
+
targets,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Lightweight publisher-only email bridge (for non-web environments).
|
|
75
|
+
*/
|
|
76
|
+
export function setupPublisherOnlyBridge(emitter, redis, channel) {
|
|
77
|
+
const tag = `${process.pid}-${Date.now()}`;
|
|
78
|
+
registerMailEventPublisher(emitter, redis, tag, channel);
|
|
79
|
+
log.info('email bridge publisher active (queue worker → Redis)');
|
|
80
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cap an HTML/text body to a maximum size.
|
|
3
|
+
* Returns `null` for falsy or non-string inputs.
|
|
4
|
+
*/
|
|
5
|
+
export declare function capHtmlSize(v: unknown, maxSize?: number): string | null;
|
|
6
|
+
/**
|
|
7
|
+
* Mapping of AdonisJS mail events to their corresponding status strings.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MAIL_STATUS_MAP: Array<[string, string]>;
|
|
10
|
+
/**
|
|
11
|
+
* Build a serializable email payload from a mail event.
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildEmailPayload(data: unknown, status: string, processTag: string): Record<string, unknown>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { extractAddresses } from '../utils/mail_helpers.js';
|
|
2
|
+
const MAX_HTML = 50_000;
|
|
3
|
+
/**
|
|
4
|
+
* Cap an HTML/text body to a maximum size.
|
|
5
|
+
* Returns `null` for falsy or non-string inputs.
|
|
6
|
+
*/
|
|
7
|
+
export function capHtmlSize(v, maxSize = MAX_HTML) {
|
|
8
|
+
if (!v || typeof v !== 'string')
|
|
9
|
+
return null;
|
|
10
|
+
if (v.length <= maxSize)
|
|
11
|
+
return v;
|
|
12
|
+
return v.slice(0, maxSize) + '\n<!-- truncated -->';
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Mapping of AdonisJS mail events to their corresponding status strings.
|
|
16
|
+
*/
|
|
17
|
+
export const MAIL_STATUS_MAP = [
|
|
18
|
+
['mail:sending', 'sending'],
|
|
19
|
+
['mail:sent', 'sent'],
|
|
20
|
+
['mail:queueing', 'queueing'],
|
|
21
|
+
['mail:queued', 'queued'],
|
|
22
|
+
['queued:mail:error', 'failed'],
|
|
23
|
+
];
|
|
24
|
+
function extractMessage(data) {
|
|
25
|
+
return ((data?.message || data) ?? {});
|
|
26
|
+
}
|
|
27
|
+
function extractMailer(data) {
|
|
28
|
+
return data?.mailerName || data?.mailer || 'unknown';
|
|
29
|
+
}
|
|
30
|
+
function extractMessageId(data) {
|
|
31
|
+
const response = data?.response;
|
|
32
|
+
return response?.messageId || data?.messageId || null;
|
|
33
|
+
}
|
|
34
|
+
function addressOrDefault(value, fallback) {
|
|
35
|
+
return extractAddresses(value) || fallback;
|
|
36
|
+
}
|
|
37
|
+
function extractAddressFields(msg) {
|
|
38
|
+
return {
|
|
39
|
+
from: addressOrDefault(msg?.from, 'unknown'),
|
|
40
|
+
to: addressOrDefault(msg?.to, 'unknown'),
|
|
41
|
+
cc: extractAddresses(msg?.cc) || null,
|
|
42
|
+
bcc: extractAddresses(msg?.bcc) || null,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function extractContentFields(msg) {
|
|
46
|
+
return {
|
|
47
|
+
subject: msg?.subject || '(no subject)',
|
|
48
|
+
html: capHtmlSize(msg?.html),
|
|
49
|
+
text: capHtmlSize(msg?.text),
|
|
50
|
+
attachmentCount: Array.isArray(msg?.attachments) ? msg.attachments.length : 0,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build a serializable email payload from a mail event.
|
|
55
|
+
*/
|
|
56
|
+
export function buildEmailPayload(data, status, processTag) {
|
|
57
|
+
const d = (data ?? {});
|
|
58
|
+
const msg = extractMessage(d);
|
|
59
|
+
return {
|
|
60
|
+
_t: processTag,
|
|
61
|
+
...extractAddressFields(msg),
|
|
62
|
+
...extractContentFields(msg),
|
|
63
|
+
mailer: extractMailer(d),
|
|
64
|
+
status,
|
|
65
|
+
messageId: extractMessageId(d),
|
|
66
|
+
timestamp: Date.now(),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for hooking into pino's internal stream.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Find the `pino.stream` symbol on an object by description.
|
|
6
|
+
* Pino uses a local Symbol('pino.stream'), not a global registry symbol.
|
|
7
|
+
*/
|
|
8
|
+
export declare function findPinoStreamSymbol(obj: object): symbol | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Wrap a stream's `write` method to intercept JSON log entries.
|
|
11
|
+
* Calls `ingest` for each valid JSON entry that has a numeric `level`.
|
|
12
|
+
* The original write is always called to preserve normal logging.
|
|
13
|
+
*/
|
|
14
|
+
export declare function wrapWriteMethod(stream: {
|
|
15
|
+
write: Function;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}, ingest: (entry: Record<string, unknown>) => void): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for hooking into pino's internal stream.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Find the `pino.stream` symbol on an object by description.
|
|
6
|
+
* Pino uses a local Symbol('pino.stream'), not a global registry symbol.
|
|
7
|
+
*/
|
|
8
|
+
export function findPinoStreamSymbol(obj) {
|
|
9
|
+
return Object.getOwnPropertySymbols(obj).find((s) => s.description === 'pino.stream');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Wrap a stream's `write` method to intercept JSON log entries.
|
|
13
|
+
* Calls `ingest` for each valid JSON entry that has a numeric `level`.
|
|
14
|
+
* The original write is always called to preserve normal logging.
|
|
15
|
+
*/
|
|
16
|
+
export function wrapWriteMethod(stream, ingest) {
|
|
17
|
+
const originalWrite = stream.write.bind(stream);
|
|
18
|
+
stream.write = function wrappedWrite(chunk, ...args) {
|
|
19
|
+
try {
|
|
20
|
+
const str = typeof chunk === 'string'
|
|
21
|
+
? chunk
|
|
22
|
+
: chunk instanceof Uint8Array
|
|
23
|
+
? new TextDecoder().decode(chunk)
|
|
24
|
+
: String(chunk);
|
|
25
|
+
const entry = JSON.parse(str);
|
|
26
|
+
if (entry && typeof entry.level === 'number') {
|
|
27
|
+
ingest(entry);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Not valid JSON — ignore (e.g. pino-pretty output)
|
|
32
|
+
}
|
|
33
|
+
return originalWrite(chunk, ...args);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider helper functions extracted from ServerStatsProvider.
|
|
3
|
+
* Handles pino hooking, log stream broadcast, stats interval,
|
|
4
|
+
* dependency checking, edge plugin, and non-web bridge.
|
|
5
|
+
*
|
|
6
|
+
* Dashboard/toolbar setup is in ./toolbar_setup.ts and re-exported here.
|
|
7
|
+
*/
|
|
8
|
+
import { LogStreamService } from '../log_stream/log_stream_service.js';
|
|
9
|
+
import type { DevToolbarConfig } from '../debug/types.js';
|
|
10
|
+
import type { StatsEngine } from '../engine/stats_engine.js';
|
|
11
|
+
import type { ResolvedServerStatsConfig } from '../types.js';
|
|
12
|
+
import type { ToolbarCoreResult, ProviderFields } from './toolbar_setup.js';
|
|
13
|
+
import type { ApplicationService } from '@adonisjs/core/types';
|
|
14
|
+
export { initDashboardStore } from './dashboard_init.js';
|
|
15
|
+
interface SetupDevToolbarArgs {
|
|
16
|
+
tc: DevToolbarConfig;
|
|
17
|
+
config: ResolvedServerStatsConfig;
|
|
18
|
+
app: ApplicationService;
|
|
19
|
+
resolve: (binding: string) => Promise<unknown>;
|
|
20
|
+
getDiagnostics: () => unknown;
|
|
21
|
+
}
|
|
22
|
+
/** Wrapper matching the provider's call signature. */
|
|
23
|
+
export declare function setupDevToolbarCore(args: SetupDevToolbarArgs): Promise<ToolbarCoreResult | null>;
|
|
24
|
+
/** Wrapper matching the provider's 3-arg call signature. */
|
|
25
|
+
export declare function applyToolbarResult(result: ToolbarCoreResult, tc: DevToolbarConfig, provider: ProviderFields): void;
|
|
26
|
+
/** Hook the AdonisJS Pino logger into the log collector. Returns true if hooked. */
|
|
27
|
+
export declare function hookPinoToLogStream(logger: unknown): boolean;
|
|
28
|
+
/** Set up log stream broadcasting via Transmit. Returns LogStreamService if file-based fallback. */
|
|
29
|
+
export declare function setupLogStreamBroadcast(transmit: {
|
|
30
|
+
broadcast(ch: string, d: unknown): void;
|
|
31
|
+
}, channelName: string, pinoHookActive: boolean, makePath: (...parts: string[]) => string): LogStreamService | null;
|
|
32
|
+
/** Check if dashboard dependencies are available. Returns true if available, false if missing. */
|
|
33
|
+
export declare function checkDashboardDepsHelper(config: ResolvedServerStatsConfig, _app: ApplicationService): Promise<boolean>;
|
|
34
|
+
/** Register the Edge.js plugin if Edge is available. Returns true if registered. */
|
|
35
|
+
export declare function registerEdgePluginHelper(app: ApplicationService, config: ResolvedServerStatsConfig): Promise<boolean>;
|
|
36
|
+
/** Set up the publisher-only email bridge for non-web environments. */
|
|
37
|
+
export declare function setupNonWebBridgeHelper(emitter: unknown, channel: string): Promise<void>;
|
|
38
|
+
interface StatsIntervalResult {
|
|
39
|
+
intervalId: ReturnType<typeof setInterval>;
|
|
40
|
+
transmitAvailable: boolean;
|
|
41
|
+
prometheusActive: boolean;
|
|
42
|
+
channelName: string | null;
|
|
43
|
+
}
|
|
44
|
+
/** Set up the stats collection interval with transmit and prometheus integration. */
|
|
45
|
+
export declare function setupStatsIntervalHelper(engine: StatsEngine, config: ResolvedServerStatsConfig, container: {
|
|
46
|
+
make(b: string): Promise<unknown>;
|
|
47
|
+
}): Promise<StatsIntervalResult>;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider helper functions extracted from ServerStatsProvider.
|
|
3
|
+
* Handles pino hooking, log stream broadcast, stats interval,
|
|
4
|
+
* dependency checking, edge plugin, and non-web bridge.
|
|
5
|
+
*
|
|
6
|
+
* Dashboard/toolbar setup is in ./toolbar_setup.ts and re-exported here.
|
|
7
|
+
*/
|
|
8
|
+
import { getLogStreamService } from '../collectors/log_collector.js';
|
|
9
|
+
import { LogStreamService } from '../log_stream/log_stream_service.js';
|
|
10
|
+
import { log, dim, bold } from '../utils/logger.js';
|
|
11
|
+
import { setupPublisherOnlyBridge } from './email_bridge.js';
|
|
12
|
+
import { findPinoStreamSymbol, wrapWriteMethod } from './pino_hook.js';
|
|
13
|
+
// Re-export toolbar/dashboard functions with provider-compatible signatures
|
|
14
|
+
import { setupDevToolbarCore as coreSetup, applyToolbarResult as coreApply, } from './toolbar_setup.js';
|
|
15
|
+
export { initDashboardStore } from './dashboard_init.js';
|
|
16
|
+
/** Wrapper matching the provider's call signature. */
|
|
17
|
+
export async function setupDevToolbarCore(args) {
|
|
18
|
+
return coreSetup(args);
|
|
19
|
+
}
|
|
20
|
+
/** Wrapper matching the provider's 3-arg call signature. */
|
|
21
|
+
export function applyToolbarResult(result, tc, provider) {
|
|
22
|
+
coreApply(result, tc, provider);
|
|
23
|
+
}
|
|
24
|
+
// ── hookPinoToLogStream ─────────────────────────────────────────
|
|
25
|
+
/** Hook the AdonisJS Pino logger into the log collector. Returns true if hooked. */
|
|
26
|
+
export function hookPinoToLogStream(logger) {
|
|
27
|
+
const logStream = getLogStreamService();
|
|
28
|
+
if (!logStream)
|
|
29
|
+
return false;
|
|
30
|
+
const pino = logger?.pino;
|
|
31
|
+
if (!pino)
|
|
32
|
+
return false;
|
|
33
|
+
const streamSym = findPinoStreamSymbol(pino);
|
|
34
|
+
if (!streamSym)
|
|
35
|
+
return false;
|
|
36
|
+
const rawStream = pino[streamSym];
|
|
37
|
+
if (!rawStream)
|
|
38
|
+
return false;
|
|
39
|
+
if (typeof rawStream.write !== 'function')
|
|
40
|
+
return false;
|
|
41
|
+
wrapWriteMethod(rawStream, (entry) => logStream.ingest(entry));
|
|
42
|
+
log.info('log collector hooked into AdonisJS logger (zero-config)');
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
// ── setupLogStreamBroadcast ─────────────────────────────────────
|
|
46
|
+
/** Set up log stream broadcasting via Transmit. Returns LogStreamService if file-based fallback. */
|
|
47
|
+
export function setupLogStreamBroadcast(transmit, channelName, pinoHookActive, makePath) {
|
|
48
|
+
const broadcast = (entry) => {
|
|
49
|
+
try {
|
|
50
|
+
transmit.broadcast(channelName, entry);
|
|
51
|
+
}
|
|
52
|
+
catch { }
|
|
53
|
+
};
|
|
54
|
+
const existing = getLogStreamService();
|
|
55
|
+
if (pinoHookActive && existing) {
|
|
56
|
+
const internal = existing;
|
|
57
|
+
const orig = internal.onEntry;
|
|
58
|
+
internal.onEntry = (entry) => {
|
|
59
|
+
orig?.(entry);
|
|
60
|
+
broadcast(entry);
|
|
61
|
+
};
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const service = new LogStreamService(makePath('logs', 'adonisjs.log'), broadcast);
|
|
65
|
+
service.start().catch(() => { });
|
|
66
|
+
return service;
|
|
67
|
+
}
|
|
68
|
+
// ── checkDashboardDepsHelper ────────────────────────────────────
|
|
69
|
+
/** Check if dashboard dependencies are available. Returns true if available, false if missing. */
|
|
70
|
+
export async function checkDashboardDepsHelper(config, _app) {
|
|
71
|
+
if (!config.devToolbar?.enabled || !config.devToolbar.dashboard)
|
|
72
|
+
return true;
|
|
73
|
+
const { appImport } = await import('../utils/app_import.js');
|
|
74
|
+
const missing = [];
|
|
75
|
+
try {
|
|
76
|
+
await appImport('knex');
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
missing.push('knex');
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
await appImport('better-sqlite3');
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
missing.push('better-sqlite3');
|
|
86
|
+
}
|
|
87
|
+
if (missing.length === 0)
|
|
88
|
+
return true;
|
|
89
|
+
log.block(`Dashboard requires ${missing.join(' and ')}. Install with:`, [
|
|
90
|
+
'',
|
|
91
|
+
bold(`npm install ${missing.join(' ')}`),
|
|
92
|
+
'',
|
|
93
|
+
dim('Dashboard routes have been skipped for now.'),
|
|
94
|
+
dim('Everything else (stats bar, debug panel) works without it.'),
|
|
95
|
+
]);
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
// ── registerEdgePluginHelper ────────────────────────────────────
|
|
99
|
+
/** Register the Edge.js plugin if Edge is available. Returns true if registered. */
|
|
100
|
+
export async function registerEdgePluginHelper(app, config) {
|
|
101
|
+
if (!app.usingEdgeJS)
|
|
102
|
+
return false;
|
|
103
|
+
try {
|
|
104
|
+
const { appImport } = await import('../utils/app_import.js');
|
|
105
|
+
const edge = await appImport('edge.js');
|
|
106
|
+
const { edgePluginServerStats } = await import('../edge/plugin.js');
|
|
107
|
+
edge.default.use(edgePluginServerStats(config));
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
log.warn('could not register Edge plugin: ' + err?.message);
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// ── setupNonWebBridgeHelper ─────────────────────────────────────
|
|
116
|
+
/** Set up the publisher-only email bridge for non-web environments. */
|
|
117
|
+
export async function setupNonWebBridgeHelper(emitter, channel) {
|
|
118
|
+
if (!emitter)
|
|
119
|
+
return;
|
|
120
|
+
try {
|
|
121
|
+
const { appImport } = await import('../utils/app_import.js');
|
|
122
|
+
const mod = await appImport('@adonisjs/redis/services/main');
|
|
123
|
+
const redis = mod.default;
|
|
124
|
+
setupPublisherOnlyBridge(emitter, redis, channel);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Redis not available — skip bridge
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/** Set up the stats collection interval with transmit and prometheus integration. */
|
|
131
|
+
export async function setupStatsIntervalHelper(engine, config, container) {
|
|
132
|
+
const { transmit, transmitAvailable } = await resolveTransmit(config, container);
|
|
133
|
+
const { prom, prometheusActive } = await resolvePrometheus();
|
|
134
|
+
const intervalId = setInterval(async () => {
|
|
135
|
+
try {
|
|
136
|
+
const s = await engine.collect();
|
|
137
|
+
if (transmit && config.channelName)
|
|
138
|
+
transmit.broadcast(config.channelName, s);
|
|
139
|
+
if (prom)
|
|
140
|
+
prom.update(s);
|
|
141
|
+
config.onStats?.(s);
|
|
142
|
+
}
|
|
143
|
+
catch { }
|
|
144
|
+
}, config.intervalMs);
|
|
145
|
+
return {
|
|
146
|
+
intervalId,
|
|
147
|
+
transmitAvailable,
|
|
148
|
+
prometheusActive,
|
|
149
|
+
channelName: transmitAvailable ? config.channelName : null,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
async function resolveTransmit(config, container) {
|
|
153
|
+
if (config.transport !== 'transmit')
|
|
154
|
+
return { transmit: null, transmitAvailable: false };
|
|
155
|
+
try {
|
|
156
|
+
const t = await container.make('transmit');
|
|
157
|
+
return t
|
|
158
|
+
? { transmit: t, transmitAvailable: true }
|
|
159
|
+
: { transmit: null, transmitAvailable: false };
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
log.info('transmit not installed — falling back to polling');
|
|
163
|
+
return { transmit: null, transmitAvailable: false };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async function resolvePrometheus() {
|
|
167
|
+
try {
|
|
168
|
+
const m = await import('../prometheus/prometheus_collector.js');
|
|
169
|
+
const p = m.ServerStatsCollector.instance;
|
|
170
|
+
if (p) {
|
|
171
|
+
log.info('Prometheus integration active');
|
|
172
|
+
return { prom: p, prometheusActive: true };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch { }
|
|
176
|
+
return { prom: null, prometheusActive: false };
|
|
177
|
+
}
|
|
@@ -1,92 +1,46 @@
|
|
|
1
|
+
import { StatsEngine } from '../engine/stats_engine.js';
|
|
2
|
+
import type DebugController from '../controller/debug_controller.js';
|
|
3
|
+
import type DashboardController from '../dashboard/dashboard_controller.js';
|
|
4
|
+
import type { DashboardStore } from '../dashboard/dashboard_store.js';
|
|
5
|
+
import type { DebugStore } from '../debug/debug_store.js';
|
|
6
|
+
import type { LogStreamService } from '../log_stream/log_stream_service.js';
|
|
1
7
|
import type { ApplicationService } from '@adonisjs/core/types';
|
|
2
8
|
export default class ServerStatsProvider {
|
|
3
9
|
protected app: ApplicationService;
|
|
4
10
|
private intervalId;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
engine: StatsEngine | null;
|
|
12
|
+
debugStore: DebugStore | null;
|
|
13
|
+
dashboardStore: DashboardStore | null;
|
|
14
|
+
dashboardController: DashboardController | null;
|
|
15
|
+
dashboardLogStream: LogStreamService | null;
|
|
16
|
+
dashboardBroadcastTimer: ReturnType<typeof setInterval> | null;
|
|
17
|
+
debugBroadcastTimer: ReturnType<typeof setTimeout> | null;
|
|
18
|
+
persistPath: string | null;
|
|
19
|
+
flushTimer: ReturnType<typeof setInterval> | null;
|
|
14
20
|
private statsController;
|
|
15
|
-
|
|
21
|
+
debugController: DebugController | null;
|
|
16
22
|
private apiController;
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
dashboardDepsAvailable: boolean;
|
|
24
|
+
emailBridgeRedis: unknown;
|
|
19
25
|
private emailBridgeChannel;
|
|
20
26
|
private logStreamService;
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
pinoHookActive: boolean;
|
|
28
|
+
edgePluginActive: boolean;
|
|
23
29
|
private prometheusActive;
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
transmitAvailable: boolean;
|
|
31
|
+
transmitChannels: string[];
|
|
26
32
|
private resolvedConfig;
|
|
27
33
|
private resolvedCollectors;
|
|
28
34
|
constructor(app: ApplicationService);
|
|
29
35
|
boot(): Promise<void>;
|
|
30
|
-
private
|
|
31
|
-
|
|
32
|
-
* Read start/kernel.ts and detect auth-related middleware in server.use()
|
|
33
|
-
* or router.use() blocks. Returns import paths of problematic middleware.
|
|
34
|
-
*
|
|
35
|
-
* Ignores initialize_auth_middleware (no DB query — just sets up ctx.auth).
|
|
36
|
-
*/
|
|
37
|
-
private detectGlobalAuthMiddleware;
|
|
38
|
-
/**
|
|
39
|
-
* Hook into the AdonisJS logger's Pino stream to feed log entries
|
|
40
|
-
* directly into the LogStreamService — no file path needed.
|
|
41
|
-
*
|
|
42
|
-
* Uses pino's exported `symbols.streamSym` to access the underlying
|
|
43
|
-
* destination stream, then wraps its `write` method to tee entries
|
|
44
|
-
* into the log collector.
|
|
45
|
-
*/
|
|
46
|
-
private hookPinoLogger;
|
|
36
|
+
private initBoot;
|
|
37
|
+
private registerRoutes;
|
|
47
38
|
ready(): Promise<void>;
|
|
48
|
-
private
|
|
49
|
-
|
|
50
|
-
* Set up the stats collection interval, transmit broadcasting,
|
|
51
|
-
* and Prometheus integration. Extracted from initializeServerStats
|
|
52
|
-
* so the ready log fires promptly.
|
|
53
|
-
*/
|
|
54
|
-
private setupStatsInterval;
|
|
39
|
+
private initStats;
|
|
40
|
+
private resolveCollectors;
|
|
55
41
|
private setupDevToolbar;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
* log piping, and per-request data persistence.
|
|
59
|
-
*
|
|
60
|
-
* Routes are already registered in boot() with a lazy controller getter.
|
|
61
|
-
* This method creates the controller so those routes become functional.
|
|
62
|
-
*/
|
|
63
|
-
private setupDashboard;
|
|
64
|
-
/**
|
|
65
|
-
* Lightweight email bridge publisher for non-web environments
|
|
66
|
-
* (queue workers, scheduler). Listens to local AdonisJS mail events
|
|
67
|
-
* and publishes them to Redis so the web server can ingest them.
|
|
68
|
-
*/
|
|
69
|
-
private setupEmailBridgePublisher;
|
|
70
|
-
/**
|
|
71
|
-
* Set up live log streaming via Transmit (web environment only).
|
|
72
|
-
* Merged from the former standalone LogStreamProvider.
|
|
73
|
-
*/
|
|
74
|
-
private setupLogStream;
|
|
75
|
-
/**
|
|
76
|
-
* Set up a Redis pub/sub bridge for cross-process email capture.
|
|
77
|
-
*
|
|
78
|
-
* Mail events (`mail:sending`, `mail:sent`, etc.) are process-local.
|
|
79
|
-
* When emails are sent from a Bull queue worker, the web server's
|
|
80
|
-
* {@link EmailCollector} never sees them. This bridge solves that:
|
|
81
|
-
*
|
|
82
|
-
* 1. **Every process** publishes mail events to a Redis channel.
|
|
83
|
-
* 2. **Every process** subscribes and ingests events from *other*
|
|
84
|
-
* processes (identified by a unique process tag).
|
|
85
|
-
*
|
|
86
|
-
* Requires `@adonisjs/redis`. Silently skipped if not installed.
|
|
87
|
-
*/
|
|
88
|
-
private setupEmailBridge;
|
|
89
|
-
/** Return diagnostics state for the Internals endpoint. */
|
|
42
|
+
private setupLogBroadcast;
|
|
43
|
+
private resolve;
|
|
90
44
|
getDiagnostics(): {
|
|
91
45
|
timers: {
|
|
92
46
|
collectionInterval: {
|
|
@@ -137,7 +91,7 @@ export default class ServerStatsProvider {
|
|
|
137
91
|
};
|
|
138
92
|
config: {
|
|
139
93
|
intervalMs: number;
|
|
140
|
-
transport:
|
|
94
|
+
transport: string;
|
|
141
95
|
channelName: string;
|
|
142
96
|
endpoint: string | false;
|
|
143
97
|
skipInTest: boolean;
|
|
@@ -145,22 +99,22 @@ export default class ServerStatsProvider {
|
|
|
145
99
|
hasShouldShowCallback: boolean;
|
|
146
100
|
};
|
|
147
101
|
devToolbar: {
|
|
148
|
-
enabled: boolean;
|
|
149
|
-
maxQueries: number;
|
|
150
|
-
maxEvents: number;
|
|
151
|
-
maxEmails: number;
|
|
152
|
-
maxTraces: number;
|
|
153
|
-
slowQueryThresholdMs: number;
|
|
154
102
|
tracing: boolean;
|
|
155
103
|
dashboard: boolean;
|
|
156
|
-
dashboardPath: string;
|
|
157
|
-
debugEndpoint: string;
|
|
158
104
|
retentionDays: number;
|
|
159
|
-
dbPath: string;
|
|
160
105
|
persistDebugData: string | boolean;
|
|
161
|
-
renderer:
|
|
106
|
+
renderer: string;
|
|
162
107
|
excludeFromTracing: string[];
|
|
163
108
|
customPaneCount: number;
|
|
109
|
+
dashboardPath: string;
|
|
110
|
+
debugEndpoint: string;
|
|
111
|
+
dbPath: string;
|
|
112
|
+
maxQueries: number;
|
|
113
|
+
maxEvents: number;
|
|
114
|
+
maxEmails: number;
|
|
115
|
+
maxTraces: number;
|
|
116
|
+
slowQueryThresholdMs: number;
|
|
117
|
+
enabled: boolean;
|
|
164
118
|
};
|
|
165
119
|
};
|
|
166
120
|
shutdown(): Promise<void>;
|