4runr-os 2.10.0 → 2.10.2

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.
Files changed (36) hide show
  1. package/apps/gateway/dist/apps/gateway/src/db/init.d.ts.map +1 -1
  2. package/apps/gateway/dist/apps/gateway/src/db/init.js +8 -1
  3. package/apps/gateway/dist/apps/gateway/src/db/init.js.map +1 -1
  4. package/apps/gateway/dist/apps/gateway/src/db/redis.d.ts.map +1 -1
  5. package/apps/gateway/dist/apps/gateway/src/db/redis.js +3 -2
  6. package/apps/gateway/dist/apps/gateway/src/db/redis.js.map +1 -1
  7. package/apps/gateway/dist/apps/gateway/src/health/index.d.ts.map +1 -1
  8. package/apps/gateway/dist/apps/gateway/src/health/index.js +9 -8
  9. package/apps/gateway/dist/apps/gateway/src/health/index.js.map +1 -1
  10. package/apps/gateway/dist/apps/gateway/src/index.js +30 -0
  11. package/apps/gateway/dist/apps/gateway/src/index.js.map +1 -1
  12. package/apps/gateway/dist/apps/gateway/src/metrics/index.d.ts +9 -0
  13. package/apps/gateway/dist/apps/gateway/src/metrics/index.d.ts.map +1 -1
  14. package/apps/gateway/dist/apps/gateway/src/metrics/index.js +94 -0
  15. package/apps/gateway/dist/apps/gateway/src/metrics/index.js.map +1 -1
  16. package/apps/gateway/package-lock.json +220 -207
  17. package/apps/gateway/src/db/init.ts +14 -2
  18. package/apps/gateway/src/db/redis.ts +4 -2
  19. package/apps/gateway/src/health/index.ts +16 -14
  20. package/apps/gateway/src/index.ts +39 -0
  21. package/apps/gateway/src/metrics/index.ts +121 -0
  22. package/dist/gateway-client.d.ts +9 -0
  23. package/dist/gateway-client.d.ts.map +1 -1
  24. package/dist/gateway-client.js +32 -1
  25. package/dist/gateway-client.js.map +1 -1
  26. package/dist/gateway-observability.d.ts +4 -0
  27. package/dist/gateway-observability.d.ts.map +1 -1
  28. package/dist/gateway-observability.js +13 -1
  29. package/dist/gateway-observability.js.map +1 -1
  30. package/dist/tui-handlers.js +50 -5
  31. package/dist/tui-handlers.js.map +1 -1
  32. package/mk3-tui/src/app.rs +55 -1
  33. package/mk3-tui/src/main.rs +52 -6
  34. package/mk3-tui/src/ui/connection_portal.rs +12 -1
  35. package/mk3-tui/src/ui/portal_monitoring.rs +170 -36
  36. package/package.json +2 -2
@@ -85,8 +85,13 @@ export async function initializeDatabase(logger: any): Promise<DatabaseInitResul
85
85
  await waitForHealthy('4runr-redis', 15000);
86
86
  logger.info('✓ Database containers healthy');
87
87
 
88
- // Build DATABASE_URL for local Docker setup (localhost not 'postgres' hostname)
88
+ // Build DATABASE_URL and REDIS_URL for local Docker setup (localhost not 'postgres' hostname)
89
89
  const databaseUrl = 'postgresql://4runr:4runr_dev_pass@localhost:5432/4runr_local';
90
+ const redisUrl = 'redis://localhost:6379';
91
+
92
+ // Set environment variables so Redis client can connect when first requested
93
+ process.env['DATABASE_URL'] = databaseUrl;
94
+ process.env['REDIS_URL'] = redisUrl;
90
95
 
91
96
  // Run migrations
92
97
  logger.info('Running database migrations...');
@@ -239,7 +244,14 @@ async function runMigrations(databaseUrl: string, logger: any): Promise<void> {
239
244
  }
240
245
 
241
246
  try {
242
- execSync(`npx prisma migrate deploy`, {
247
+ // For local Docker Postgres, use db push to avoid migration compatibility
248
+ // (migrations were created for SQLite, need Postgres-native approach)
249
+ const isLocalDocker = databaseUrl.includes('localhost:5432');
250
+ const command = isLocalDocker
251
+ ? `npx prisma db push --skip-generate --accept-data-loss`
252
+ : `npx prisma migrate deploy`;
253
+
254
+ execSync(command, {
243
255
  env: {
244
256
  ...process.env,
245
257
  DATABASE_URL: databaseUrl
@@ -25,12 +25,14 @@ export async function getRedisClient(): Promise<IORedis | null> {
25
25
  }
26
26
 
27
27
  redisPromise = (async () => {
28
- if (!env.REDIS_URL) {
28
+ // Check both env object (parsed at startup) and process.env (set at runtime by Docker init)
29
+ const redisUrl = env.REDIS_URL || process.env['REDIS_URL'];
30
+ if (!redisUrl) {
29
31
  return null;
30
32
  }
31
33
 
32
34
  try {
33
- const client = new IORedis(env.REDIS_URL, {
35
+ const client = new IORedis(redisUrl, {
34
36
  maxRetriesPerRequest: 3,
35
37
  lazyConnect: true,
36
38
  retryStrategy: (times) => {
@@ -212,15 +212,19 @@ export async function performHealthChecks(): Promise<HealthCheckResult> {
212
212
  };
213
213
  }
214
214
 
215
- // Determine overall status
216
- const allChecks = Object.values(checks);
217
- const hasDown = allChecks.some(check => check.status === 'down');
218
- const hasDegraded = allChecks.some(check => check.status === 'degraded');
215
+ // Overall status: **database** is critical for readiness; Redis/queue are optional (local dev often has no Redis).
216
+ const db = checks.database;
217
+ const databaseDown = db?.status === 'down';
218
+ const hasDegraded = Object.values(checks).some(
219
+ (check) => check.status === 'degraded'
220
+ );
221
+ const optionalDown =
222
+ checks.redis?.status === 'down' || checks.queue?.status === 'down';
219
223
 
220
224
  let status: HealthCheckResult['status'] = 'healthy';
221
- if (hasDown) {
225
+ if (databaseDown) {
222
226
  status = 'unhealthy';
223
- } else if (hasDegraded) {
227
+ } else if (hasDegraded || optionalDown) {
224
228
  status = 'degraded';
225
229
  }
226
230
 
@@ -232,18 +236,16 @@ export async function performHealthChecks(): Promise<HealthCheckResult> {
232
236
  }
233
237
 
234
238
  /**
235
- * Check if service is ready to accept traffic
236
- * Ready means critical dependencies are up
239
+ * Check if service is ready to accept traffic.
240
+ * Critical: Postgres when persistence uses the DB. Redis and queue are optional for readiness.
237
241
  */
238
242
  export async function isReady(): Promise<boolean> {
239
243
  const health = await performHealthChecks();
240
-
241
- // For readiness, we need at least database (if configured)
242
- // Redis and Queue are optional
243
- const databaseOk = !health.checks.database || health.checks.database.status === 'up';
244
- const criticalDependencyOk = databaseOk;
245
244
 
246
- return criticalDependencyOk && health.status !== 'unhealthy';
245
+ const db = health.checks.database;
246
+ const databaseOk = !db || db.status === 'up';
247
+
248
+ return databaseOk;
247
249
  }
248
250
 
249
251
  /**
@@ -274,11 +274,22 @@ if (dbResult.client && persistenceMode !== 'memory') {
274
274
  // Health endpoint (liveness probe - no auth required)
275
275
  fastify.get('/health', async (request, reply) => {
276
276
  const alive = isAlive();
277
+ const { getMetricsSummary } = await import('./metrics/index.js');
278
+ const summary = await getMetricsSummary();
279
+
277
280
  return {
278
281
  ok: alive,
279
282
  status: alive ? 'alive' : 'dead',
280
283
  time: new Date().toISOString(),
284
+ uptime: summary.uptime,
285
+ memory: summary.memory,
286
+ cpu: summary.cpu,
281
287
  persistence: persistenceMode,
288
+ /** 4Runr platform DB: docker = Postgres via Docker; memory = no DB */
289
+ fourRunrDb: {
290
+ mode: dbResult.mode,
291
+ prismaConnected: !!dbClient,
292
+ },
282
293
  auth: {
283
294
  enabled: env.AUTH_ENABLED,
284
295
  mode: env.AUTH_MODE
@@ -357,6 +368,34 @@ fastify.get('/metrics', async (request, reply) => {
357
368
  return prometheusMetrics;
358
369
  });
359
370
 
371
+ // Enhanced monitoring endpoint for dashboards
372
+ fastify.get('/api/monitoring/summary', async (request, reply) => {
373
+ const { getMetricsSummary } = await import('./metrics/index.js');
374
+ const summary = await getMetricsSummary();
375
+
376
+ // Add health and ready status
377
+ const healthStatus = isAlive() ? 'healthy' : 'unhealthy';
378
+ const readyStatus = await isReady();
379
+
380
+ // Add dependency checks
381
+ const dependencies = await performHealthChecks();
382
+
383
+ return {
384
+ status: healthStatus,
385
+ ready: readyStatus,
386
+ uptime: summary.uptime,
387
+ memory: summary.memory,
388
+ cpu: summary.cpu,
389
+ dependencies,
390
+ timestamp: summary.timestamp,
391
+ persistence: persistenceMode,
392
+ database: {
393
+ mode: dbResult.mode,
394
+ connected: !!dbClient
395
+ }
396
+ };
397
+ });
398
+
360
399
  // Apply DDoS protection globally (before other middleware)
361
400
  fastify.addHook('onRequest', ddosProtection);
362
401
 
@@ -199,6 +199,68 @@ export const dbQueryErrors = new Counter({
199
199
  registers: [register],
200
200
  });
201
201
 
202
+ // Health Check Metrics
203
+ export const healthCheckTotal = new Counter({
204
+ name: 'health_check_total',
205
+ help: 'Total number of health check requests',
206
+ labelNames: ['endpoint', 'status'],
207
+ registers: [register],
208
+ });
209
+
210
+ // Uptime
211
+ export const processStartTime = new Gauge({
212
+ name: 'process_start_time_seconds',
213
+ help: 'Start time of the process since unix epoch in seconds',
214
+ registers: [register],
215
+ });
216
+
217
+ // Set process start time
218
+ processStartTime.set(Date.now() / 1000);
219
+
220
+ // Connection Pool Metrics
221
+ export const dbConnectionsActive = new Gauge({
222
+ name: 'db_connections_active',
223
+ help: 'Number of active database connections',
224
+ registers: [register],
225
+ });
226
+
227
+ export const dbConnectionsIdle = new Gauge({
228
+ name: 'db_connections_idle',
229
+ help: 'Number of idle database connections in pool',
230
+ registers: [register],
231
+ });
232
+
233
+ // Redis Metrics
234
+ export const redisConnectionsActive = new Gauge({
235
+ name: 'redis_connections_active',
236
+ help: 'Number of active Redis connections',
237
+ registers: [register],
238
+ });
239
+
240
+ export const redisCommandDuration = new Histogram({
241
+ name: 'redis_command_duration_seconds',
242
+ help: 'Duration of Redis commands in seconds',
243
+ labelNames: ['command'],
244
+ buckets: [0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1],
245
+ registers: [register],
246
+ });
247
+
248
+ // Memory Metrics
249
+ export const memoryUsage = new Gauge({
250
+ name: 'process_memory_usage_bytes',
251
+ help: 'Process memory usage in bytes',
252
+ labelNames: ['type'],
253
+ registers: [register],
254
+ });
255
+
256
+ // CPU Metrics
257
+ export const cpuUsage = new Gauge({
258
+ name: 'process_cpu_usage_seconds',
259
+ help: 'Process CPU usage in seconds',
260
+ labelNames: ['type'],
261
+ registers: [register],
262
+ });
263
+
202
264
  // Export the registry for metrics endpoint
203
265
  export { register };
204
266
 
@@ -206,9 +268,68 @@ export { register };
206
268
  * Get metrics in Prometheus format
207
269
  */
208
270
  export async function getMetrics(): Promise<string> {
271
+ // Update memory metrics before export
272
+ const mem = process.memoryUsage();
273
+ memoryUsage.set({ type: 'rss' }, mem.rss);
274
+ memoryUsage.set({ type: 'heapTotal' }, mem.heapTotal);
275
+ memoryUsage.set({ type: 'heapUsed' }, mem.heapUsed);
276
+ memoryUsage.set({ type: 'external' }, mem.external);
277
+
278
+ // Update CPU metrics
279
+ const cpuUsageData = process.cpuUsage();
280
+ cpuUsage.set({ type: 'user' }, cpuUsageData.user / 1000000); // Convert to seconds
281
+ cpuUsage.set({ type: 'system' }, cpuUsageData.system / 1000000);
282
+
209
283
  return await register.metrics();
210
284
  }
211
285
 
286
+ /**
287
+ * Get metrics summary for monitoring dashboard
288
+ */
289
+ export async function getMetricsSummary(): Promise<any> {
290
+ const metrics = await getMetrics();
291
+ const mem = process.memoryUsage();
292
+ const cpuData = process.cpuUsage();
293
+ const uptime = process.uptime();
294
+
295
+ return {
296
+ uptime: {
297
+ seconds: uptime,
298
+ formatted: formatUptime(uptime)
299
+ },
300
+ memory: {
301
+ rss: mem.rss,
302
+ heapTotal: mem.heapTotal,
303
+ heapUsed: mem.heapUsed,
304
+ heapUsedPercent: ((mem.heapUsed / mem.heapTotal) * 100).toFixed(1),
305
+ external: mem.external
306
+ },
307
+ cpu: {
308
+ user: (cpuData.user / 1000000).toFixed(2), // seconds
309
+ system: (cpuData.system / 1000000).toFixed(2)
310
+ },
311
+ timestamp: new Date().toISOString()
312
+ };
313
+ }
314
+
315
+ /**
316
+ * Format uptime in human-readable format
317
+ */
318
+ function formatUptime(seconds: number): string {
319
+ const days = Math.floor(seconds / 86400);
320
+ const hours = Math.floor((seconds % 86400) / 3600);
321
+ const minutes = Math.floor((seconds % 3600) / 60);
322
+ const secs = Math.floor(seconds % 60);
323
+
324
+ const parts: string[] = [];
325
+ if (days > 0) parts.push(`${days}d`);
326
+ if (hours > 0) parts.push(`${hours}h`);
327
+ if (minutes > 0) parts.push(`${minutes}m`);
328
+ if (secs > 0 || parts.length === 0) parts.push(`${secs}s`);
329
+
330
+ return parts.join(' ');
331
+ }
332
+
212
333
  /**
213
334
  * Reset all metrics (useful for testing)
214
335
  */
@@ -9,6 +9,13 @@
9
9
  */
10
10
  /** True if JSON body is from 4Runr Gateway GET /health (not another app on the port). */
11
11
  export declare function isGatewayHealthPayload(data: unknown): boolean;
12
+ /** Subset of GET /ready JSON for Portal Monitoring lines. */
13
+ export interface GatewayReadyDependencyLine {
14
+ name: 'database' | 'redis' | 'queue';
15
+ status: string;
16
+ message?: string;
17
+ error?: string;
18
+ }
12
19
  export interface GatewayVerifyResult {
13
20
  ok: boolean;
14
21
  gatewayUrl: string;
@@ -20,6 +27,8 @@ export interface GatewayVerifyResult {
20
27
  httpStatus: number;
21
28
  statusText?: string;
22
29
  };
30
+ /** Parsed dependency checks from /ready when present (for UI). */
31
+ readyChecks?: GatewayReadyDependencyLine[];
23
32
  readyLatencyMs?: number;
24
33
  error?: string;
25
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-client.d.ts","sourceRoot":"","sources":["../src/gateway-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gateway-client.d.ts","sourceRoot":"","sources":["../src/gateway-client.ts"],"names":[],"mappings":"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"}
@@ -154,6 +154,7 @@ export class GatewayClient {
154
154
  const readyLatencyMs = Date.now() - t1;
155
155
  const data = readyRes.data;
156
156
  let ready;
157
+ let readyChecks;
157
158
  if (data && typeof data === 'object' && 'ready' in data) {
158
159
  const o = data;
159
160
  ready = {
@@ -161,11 +162,41 @@ export class GatewayClient {
161
162
  httpStatus: readyRes.status,
162
163
  statusText: typeof o.status === 'string' ? o.status : undefined,
163
164
  };
165
+ const checks = o.checks;
166
+ if (checks && typeof checks === 'object') {
167
+ const lines = [];
168
+ const pick = (name, raw) => {
169
+ if (!raw || typeof raw !== 'object')
170
+ return;
171
+ const c = raw;
172
+ const st = typeof c.status === 'string' ? c.status : String(c.status ?? '');
173
+ lines.push({
174
+ name,
175
+ status: st,
176
+ message: typeof c.message === 'string' ? c.message : undefined,
177
+ error: typeof c.error === 'string' ? c.error : undefined,
178
+ });
179
+ };
180
+ const ch = checks;
181
+ pick('database', ch.database);
182
+ pick('redis', ch.redis);
183
+ pick('queue', ch.queue);
184
+ if (lines.length > 0)
185
+ readyChecks = lines;
186
+ }
164
187
  }
165
188
  else {
166
189
  ready = { ready: false, httpStatus: readyRes.status };
167
190
  }
168
- return { ok: true, gatewayUrl, healthLatencyMs, health, ready, readyLatencyMs };
191
+ return {
192
+ ok: true,
193
+ gatewayUrl,
194
+ healthLatencyMs,
195
+ health,
196
+ ready,
197
+ readyChecks,
198
+ readyLatencyMs,
199
+ };
169
200
  }
170
201
  catch (e) {
171
202
  const msg = e && typeof e === 'object' && 'message' in e ? String(e.message) : String(e);
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-client.js","sourceRoot":"","sources":["../src/gateway-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAwB,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE;;;;GAIG;AACH,yFAAyF;AACzF,MAAM,UAAU,sBAAsB,CAAC,IAAa;IAClD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpD,MAAM,CAAC,GAAG,IAA+B,CAAC;IAC1C,IAAI,CAAC,CAAC,EAAE,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACnB,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3B,OAAO,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,OAAO,CAAC;IAC3D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAaD,MAAM,UAAU,4BAA4B,CAAC,GAAW;IACtD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC/B,CAAC,CAAC,QAAQ,GAAG,WAAW,CAAC;QAC3B,CAAC;QACD,IAAI,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjC,CAAC;AACH,CAAC;AAiCD,MAAM,OAAO,aAAa;IAChB,IAAI,CAAgB;IACpB,UAAU,CAAS;IAEX,IAAI,CAMlB;IAEF,YAAY,MAAqF;QAC/F,iDAAiD;QACjD,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAEzD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,wBAAwB,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACpC,MAAM,YAAY,GAAG,4BAA4B,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAErE,mCAAmC;QACnC,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;SACnC,CAAC;QAEF,0BAA0B;QAC1B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,OAAO,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QACvC,CAAC;QAED,+BAA+B;QAC/B,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,CAAC,SAAS,EAAE,CAAC;QAC1D,CAAC;QAED,wCAAwC;QACxC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACxC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;YAErE,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;YACnC,CAAC;iBAAM,IAAI,QAAQ,EAAE,CAAC;gBACpB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,QAAQ,EAAE,CAAC;YAClD,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,YAAY;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,KAAK,EAAE,qCAAqC;YACvE,OAAO;SACR,CAAC,CAAC;QAEH,0DAA0D;QAC1D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC;YACxC,sBAAsB;YACtB,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAChC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAClB,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CACjC,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CACjC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EACtB,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CACjC,CAAC;QACJ,CAAC;QAED,kBAAkB;QAClB,IAAI,CAAC,IAAI,GAAG;YACV,MAAM,EAAE,KAAK,EAAE,IAAuC,EAAE,EAAE;gBACxD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;gBACzD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAA2D,CAAC;gBAClF,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;oBAClE,OAAO,IAAI,CAAC,GAAG,CAAC;gBAClB,CAAC;gBACD,OAAO,IAAW,CAAC;YACrB,CAAC;YACD,KAAK,EAAE,KAAK,EAAE,EAAU,EAAE,EAAE;gBAC1B,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YAChD,CAAC;YACD,MAAM,EAAE,KAAK,EAAE,EAAU,EAAE,EAAE;gBAC3B,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,GAAG,EAAE,KAAK,EAAE,EAAU,EAAE,EAAE;gBACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;gBACxD,OAAO,QAAQ,CAAC,IAAI,CAAC;YACvB,CAAC;YACD,IAAI,EAAE,KAAK,EAAE,OAA6C,EAAE,EAAE;gBAC5D,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;gBACrC,IAAI,OAAO,EAAE,KAAK;oBAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACrE,IAAI,OAAO,EAAE,MAAM;oBAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC7D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBAEvE,qDAAqD;gBACrD,uDAAuD;gBACvD,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjC,OAAO,QAAQ,CAAC,IAAI,CAAC;gBACvB,CAAC;gBACD,IAAI,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACvD,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC5B,CAAC;gBAED,uDAAuD;gBACvD,OAAO,CAAC,IAAI,CAAC,4DAA4D,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC1F,OAAO,EAAE,CAAC;YACZ,CAAC;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAChD,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,OAAqC;QAChD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;YACxC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpC,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,UAAU;oBACV,eAAe;oBACf,MAAM;oBACN,KAAK,EAAE,kEAAkE;iBAC1E,CAAC;YACJ,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,OAAO,EAAE,cAAc,IAAI,KAAK,CAAC;YACjD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YACxF,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;YAC3B,IAAI,KAAmC,CAAC;YACxC,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;gBACxD,MAAM,CAAC,GAAG,IAA+B,CAAC;gBAC1C,KAAK,GAAG;oBACN,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;oBACvB,UAAU,EAAE,QAAQ,CAAC,MAAM;oBAC3B,UAAU,EAAE,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;iBAChE,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,KAAK,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;YACxD,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;QAClF,CAAC;QAAC,OAAO,CAAU,EAAE,CAAC;YACpB,MAAM,GAAG,GACP,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC1F,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,UAAU;gBACV,eAAe,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE;gBAChC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,GAAG;aACX,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB;QACrB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE;YAC/C,YAAY,EAAE,MAAM;YACpB,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI;YAC1B,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC3B,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC;CACF"}
1
+ {"version":3,"file":"gateway-client.js","sourceRoot":"","sources":["../src/gateway-client.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ export declare function summarizeGatewayPrometheusMetrics(metricsText: string):
9
9
  totals: {
10
10
  httpRequests: number;
11
11
  httpRequestErrors: number;
12
+ httpErrorRate: number;
12
13
  runsCreated: number;
13
14
  runsStarted: number;
14
15
  runsCompleted: number;
@@ -17,6 +18,9 @@ export declare function summarizeGatewayPrometheusMetrics(metricsText: string):
17
18
  sseMessages: number;
18
19
  idempotencyStoreSize: number;
19
20
  httpLatencyAvgMs: number | null;
21
+ queueJobsWaiting: number;
22
+ queueJobsActive: number;
23
+ queueJobsFailed: number;
20
24
  };
21
25
  topRoutes: Array<{
22
26
  key: string;
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-observability.d.ts","sourceRoot":"","sources":["../src/gateway-observability.ts"],"names":[],"mappings":"AAAA;;GAEG;AAwDH;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,WAAW,EAAE,MAAM,GAAG;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;IACF,SAAS,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAuEA"}
1
+ {"version":3,"file":"gateway-observability.d.ts","sourceRoot":"","sources":["../src/gateway-observability.ts"],"names":[],"mappings":"AAAA;;GAEG;AAwDH;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,WAAW,EAAE,MAAM,GAAG;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,SAAS,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAqFA"}
@@ -66,6 +66,7 @@ export function summarizeGatewayPrometheusMetrics(metricsText) {
66
66
  const m = collectByName(metricsText);
67
67
  const httpRequests = sumNamed(m, 'http_requests_total');
68
68
  const httpRequestErrors = sumNamed(m, 'http_request_errors_total');
69
+ const httpErrorRate = httpRequests > 0 ? (httpRequestErrors / httpRequests * 100) : 0;
69
70
  const runsCreated = sumNamed(m, 'runs_created_total');
70
71
  const runsStarted = sumNamed(m, 'runs_started_total');
71
72
  const runsCompleted = sumNamed(m, 'runs_completed_total');
@@ -73,6 +74,10 @@ export function summarizeGatewayPrometheusMetrics(metricsText) {
73
74
  const sseActive = firstGauge(m, 'sse_active_connections');
74
75
  const sseMessages = sumNamed(m, 'sse_messages_total');
75
76
  const idempotencyStoreSize = firstGauge(m, 'idempotency_store_size');
77
+ // Queue metrics
78
+ const queueJobsWaiting = firstGauge(m, 'queue_jobs_waiting');
79
+ const queueJobsActive = firstGauge(m, 'queue_jobs_active');
80
+ const queueJobsFailed = sumNamed(m, 'queue_jobs_failed_total');
76
81
  const durSum = sumNamed(m, 'http_request_duration_seconds_sum');
77
82
  const durCount = sumNamed(m, 'http_request_duration_seconds_count');
78
83
  let httpLatencyAvgMs = null;
@@ -93,6 +98,7 @@ export function summarizeGatewayPrometheusMetrics(metricsText) {
93
98
  const totals = {
94
99
  httpRequests,
95
100
  httpRequestErrors,
101
+ httpErrorRate,
96
102
  runsCreated,
97
103
  runsStarted,
98
104
  runsCompleted,
@@ -101,16 +107,22 @@ export function summarizeGatewayPrometheusMetrics(metricsText) {
101
107
  sseMessages,
102
108
  idempotencyStoreSize,
103
109
  httpLatencyAvgMs,
110
+ queueJobsWaiting,
111
+ queueJobsActive,
112
+ queueJobsFailed,
104
113
  };
105
114
  const statsLines = [
106
115
  `HTTP requests total ${httpRequests.toLocaleString()}`,
107
- `HTTP request errors ${httpRequestErrors.toLocaleString()}`,
116
+ `HTTP request errors ${httpRequestErrors.toLocaleString()} (${httpErrorRate.toFixed(2)}%)`,
108
117
  `Avg HTTP latency ${httpLatencyAvgMs === null ? '—' : `${httpLatencyAvgMs.toLocaleString()} ms`}`,
109
118
  `Runs created / started ${runsCreated.toLocaleString()} / ${runsStarted.toLocaleString()}`,
110
119
  `Runs completed ${runsCompleted.toLocaleString()}`,
111
120
  `Runs active (gauge) ${runsActive.toLocaleString()}`,
112
121
  `SSE active connections ${sseActive.toLocaleString()}`,
113
122
  `SSE messages total ${sseMessages.toLocaleString()}`,
123
+ `Queue jobs waiting ${queueJobsWaiting.toLocaleString()}`,
124
+ `Queue jobs active ${queueJobsActive.toLocaleString()}`,
125
+ `Queue jobs failed ${queueJobsFailed.toLocaleString()}`,
114
126
  `Idempotency keys (store) ${idempotencyStoreSize.toLocaleString()}`,
115
127
  ];
116
128
  const routeLines = topRoutes.map((r) => {
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-observability.js","sourceRoot":"","sources":["../src/gateway-observability.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gateway-observability.js","sourceRoot":"","sources":["../src/gateway-observability.ts"],"names":[],"mappings":"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"}
@@ -671,18 +671,63 @@ function observabilityHealthLines(v) {
671
671
  lines.push(`Verify failed: ${v.error ?? 'unknown'} (${v.healthLatencyMs} ms)`);
672
672
  return lines;
673
673
  }
674
- lines.push(`/health OK — Gateway payload verified (${v.healthLatencyMs} ms)`);
674
+ lines.push(`✓ /health OK — Gateway alive (${v.healthLatencyMs} ms)`);
675
+ const h = v.health;
676
+ if (h && typeof h === 'object') {
677
+ const o = h;
678
+ // Uptime display
679
+ if (typeof o.uptime === 'object' && o.uptime) {
680
+ const uptime = o.uptime;
681
+ if (typeof uptime.formatted === 'string') {
682
+ lines.push(`Uptime: ${uptime.formatted}`);
683
+ }
684
+ }
685
+ const persistence = o.persistence;
686
+ if (typeof persistence === 'string') {
687
+ lines.push(`Persistence: ${persistence}`);
688
+ }
689
+ const fr = o.fourRunrDb;
690
+ if (fr && typeof fr === 'object') {
691
+ const db = fr;
692
+ const mode = typeof db.mode === 'string' ? db.mode : '?';
693
+ const pc = db.prismaConnected === true;
694
+ lines.push(`4Runr DB: mode=${mode}, connected=${pc ? 'yes' : 'no'}`);
695
+ }
696
+ // Memory usage
697
+ if (typeof o.memory === 'object' && o.memory) {
698
+ const mem = o.memory;
699
+ if (typeof mem.heapUsedPercent === 'string') {
700
+ lines.push(`Memory: ${mem.heapUsedPercent}% heap used`);
701
+ }
702
+ }
703
+ }
675
704
  if (v.ready) {
676
705
  const st = v.ready.statusText ? ` — ${v.ready.statusText}` : '';
677
706
  lines.push(v.ready.ready
678
- ? `/ready: dependencies ready (HTTP ${v.ready.httpStatus})${st}`
679
- : `/ready: dependencies degraded (HTTP ${v.ready.httpStatus})${st}`);
707
+ ? `✓ /ready: all critical dependencies OK (HTTP ${v.ready.httpStatus})${st}`
708
+ : `⚠ /ready: not ready (HTTP ${v.ready.httpStatus})${st}`);
680
709
  if (typeof v.readyLatencyMs === 'number') {
681
- lines.push(`/ready round-trip: ${v.readyLatencyMs} ms`);
710
+ lines.push(` Round-trip: ${v.readyLatencyMs} ms`);
682
711
  }
683
712
  }
684
713
  else {
685
- lines.push('/ready: no response body');
714
+ lines.push('/ready: no response body');
715
+ }
716
+ if (v.readyChecks?.length) {
717
+ lines.push('');
718
+ lines.push('Dependency checks (from /ready):');
719
+ for (const c of v.readyChecks) {
720
+ const label = c.name === 'database'
721
+ ? 'PostgreSQL (4Runr DB)'
722
+ : c.name === 'redis'
723
+ ? 'Redis (cache + creds)'
724
+ : c.name === 'queue'
725
+ ? 'Queue (BullMQ)'
726
+ : c.name;
727
+ const detail = c.error || c.message || '';
728
+ const statusIcon = c.status === 'up' ? '✓' : c.status === 'down' ? '✗' : '⚠';
729
+ lines.push(` • ${statusIcon} ${label}: ${c.status}${detail ? ` — ${detail}` : ''}`);
730
+ }
686
731
  }
687
732
  return lines;
688
733
  }