@mantiq/heartbeat 0.5.15 → 0.5.16
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/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ServiceProvider, ConfigRepository, RouterImpl, HttpKernel, CacheManager } from '@mantiq/core'
|
|
2
2
|
import type { EventDispatcher } from '@mantiq/core'
|
|
3
|
-
import {
|
|
3
|
+
import { SQLiteConnection, DatabaseManager } from '@mantiq/database'
|
|
4
|
+
import { mkdirSync } from 'node:fs'
|
|
4
5
|
import type { HeartbeatConfig } from './contracts/HeartbeatConfig.ts'
|
|
5
6
|
import { DEFAULT_CONFIG } from './contracts/HeartbeatConfig.ts'
|
|
6
7
|
import { Heartbeat } from './Heartbeat.ts'
|
|
@@ -29,11 +30,29 @@ import { SimpleEventBus } from './helpers/SimpleEventBus.ts'
|
|
|
29
30
|
export class HeartbeatServiceProvider extends ServiceProvider {
|
|
30
31
|
override register(): void {
|
|
31
32
|
this.app.singleton(Heartbeat, (c) => {
|
|
32
|
-
const
|
|
33
|
+
const userConfig = c.make(ConfigRepository).get<Partial<HeartbeatConfig>>('heartbeat', {})
|
|
34
|
+
const config: HeartbeatConfig = {
|
|
35
|
+
...DEFAULT_CONFIG,
|
|
36
|
+
...userConfig,
|
|
37
|
+
storage: { ...DEFAULT_CONFIG.storage, ...userConfig?.storage },
|
|
38
|
+
watchers: { ...DEFAULT_CONFIG.watchers, ...userConfig?.watchers },
|
|
39
|
+
dashboard: { ...DEFAULT_CONFIG.dashboard, ...userConfig?.dashboard },
|
|
40
|
+
}
|
|
33
41
|
|
|
34
|
-
// Resolve
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
// Resolve database connection
|
|
43
|
+
let connection: any
|
|
44
|
+
if (config.storage.driver === 'database' && config.storage.connection) {
|
|
45
|
+
// Use an existing app database connection
|
|
46
|
+
connection = c.make(DatabaseManager).connection(config.storage.connection)
|
|
47
|
+
} else {
|
|
48
|
+
// Default: dedicated SQLite file for heartbeat telemetry
|
|
49
|
+
const basePath = c.make(ConfigRepository).get<string>('app.basePath', process.cwd())
|
|
50
|
+
const storagePath = config.storage.path
|
|
51
|
+
const dbPath = storagePath.startsWith('/') ? storagePath : `${basePath}/${storagePath}`
|
|
52
|
+
const dir = dbPath.substring(0, dbPath.lastIndexOf('/'))
|
|
53
|
+
try { mkdirSync(dir, { recursive: true }) } catch {}
|
|
54
|
+
connection = new SQLiteConnection({ driver: 'sqlite', database: dbPath })
|
|
55
|
+
}
|
|
37
56
|
|
|
38
57
|
const heartbeat = new Heartbeat(config, connection)
|
|
39
58
|
setHeartbeat(heartbeat)
|
|
@@ -52,7 +71,7 @@ export class HeartbeatServiceProvider extends ServiceProvider {
|
|
|
52
71
|
try {
|
|
53
72
|
heartbeat = this.app.make(Heartbeat)
|
|
54
73
|
} catch (e) {
|
|
55
|
-
console.warn('[Mantiq] HeartbeatServiceProvider skipped
|
|
74
|
+
if (process.env.APP_DEBUG === 'true') console.warn('[Mantiq] HeartbeatServiceProvider skipped:', (e as Error)?.message ?? e)
|
|
56
75
|
return
|
|
57
76
|
}
|
|
58
77
|
const config = heartbeat.config
|
|
@@ -91,11 +110,15 @@ export class HeartbeatServiceProvider extends ServiceProvider {
|
|
|
91
110
|
systemMetrics.start()
|
|
92
111
|
|
|
93
112
|
// Register HeartbeatMiddleware as first global middleware
|
|
94
|
-
|
|
113
|
+
try {
|
|
114
|
+
this.registerMiddleware(heartbeat, tracer, requestWatcher, metrics)
|
|
115
|
+
} catch { /* HttpKernel not available */ }
|
|
95
116
|
|
|
96
117
|
// Register dashboard routes
|
|
97
118
|
if (config.dashboard.enabled) {
|
|
98
|
-
|
|
119
|
+
try {
|
|
120
|
+
this.registerDashboardRoutes(heartbeat, metrics, config)
|
|
121
|
+
} catch { /* Router not available */ }
|
|
99
122
|
}
|
|
100
123
|
}
|
|
101
124
|
|
|
@@ -105,7 +128,8 @@ export class HeartbeatServiceProvider extends ServiceProvider {
|
|
|
105
128
|
requestWatcher: RequestWatcher | null,
|
|
106
129
|
metrics: MetricsCollector,
|
|
107
130
|
): void {
|
|
108
|
-
|
|
131
|
+
let kernel: any
|
|
132
|
+
try { kernel = this.app.make(HttpKernel) } catch { return }
|
|
109
133
|
|
|
110
134
|
// Register the middleware instance in the container
|
|
111
135
|
const middleware = new HeartbeatMiddleware(heartbeat, tracer, requestWatcher, metrics)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export interface HeartbeatConfig {
|
|
2
2
|
enabled: boolean
|
|
3
3
|
storage: {
|
|
4
|
-
|
|
4
|
+
driver: 'sqlite' | 'database'
|
|
5
|
+
path: string // SQLite file path (used when driver is 'sqlite')
|
|
6
|
+
connection?: string | undefined // database connection name (used when driver is 'database')
|
|
5
7
|
retention: number
|
|
6
8
|
pruneInterval: number
|
|
7
9
|
}
|
|
@@ -32,7 +34,9 @@ export interface HeartbeatConfig {
|
|
|
32
34
|
export const DEFAULT_CONFIG: HeartbeatConfig = {
|
|
33
35
|
enabled: true,
|
|
34
36
|
storage: {
|
|
35
|
-
|
|
37
|
+
driver: 'sqlite',
|
|
38
|
+
path: 'storage/heartbeat/heartbeat.sqlite',
|
|
39
|
+
connection: undefined,
|
|
36
40
|
retention: 86_400, // 24 hours
|
|
37
41
|
pruneInterval: 300, // 5 minutes
|
|
38
42
|
},
|