Monitoring & Performance
Section titled “Monitoring & Performance”The Monitoring & Performance API surface exposes runtime telemetry, request tracking, and lifecycle controls for the hoody-exec script runtime. Use these endpoints to power health checks, scrape Prometheus metrics, audit per-script performance, and orchestrate graceful restarts.
Health & Liveness
Section titled “Health & Liveness”GET /api/v1/exec/health
Section titled “GET /api/v1/exec/health”Returns process health, build metadata, and a snapshot of memory and file descriptor usage. Designed for load balancers, container probes, and uptime monitors.
This endpoint takes no parameters.
curl -X GET https://api.hoody.io/api/v1/exec/healthconst result = await client.exec.health.check();{ "status": "ok", "service": "hoody-exec", "built": "2025-11-14T08:21:03.000Z", "started": "2025-12-01T14:02:11.000Z", "memory": { "rss": 134217728, "heap": 62914560 }, "fds": 42, "pid": 9127, "ip": "203.0.113.45", "userAgent": "kube-probe/1.29"}{ "error": "VALIDATION_ERROR", "code": "ERROR_400", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}| Error Code | Title | Description | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Invalid input | Request parameters failed validation | Check parameter format and requirements |
{ "error": "Internal Server Error", "code": "ERROR_500", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}Runtime Stats
Section titled “Runtime Stats”GET /api/v1/exec/monitor/stats
Section titled “GET /api/v1/exec/monitor/stats”Returns aggregate runtime counters for the exec process, including uptime, memory pressure, cache occupancy, request throughput (lifetime and rolling 1/5/15 minute windows), websocket lifecycle, cron scheduler health, and the number of dropped per-script metric entries.
This endpoint takes no parameters.
curl -X GET https://api.hoody.io/api/v1/exec/monitor/statsconst stats = await client.exec.monitor.getStats();{ "uptime": 432198, "memory": { "used": 104857600, "total": 268435456, "percentage": 39.1, "rss": 134217728, "external": 8388608 }, "cache": { "scripts": 84, "vms": 12, "sharedStates": 9, "activeWsHostnames": 3 }, "requests": { "total": 1842156, "success": 1839001, "errors": 3155, "activeHttp": 7, "perSecond": 4.26, "per1m": 9.81, "per5m": 11.42, "per15m": 10.07 }, "websocket": { "opened": 1024, "closed": 1010, "active": 14, "normalCloses": 988, "abnormalCloses": 22 }, "cron": { "fires": 5402, "errors": 3, "active": 1, "wrapperActive": 1 }, "droppedScripts": 0, "sinceMs": 1764597731000}{ "error": "VALIDATION_ERROR", "code": "ERROR_400", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}| Error Code | Title | Description | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Invalid input | Request parameters failed validation | Check parameter format and requirements |
{ "error": "Internal Server Error", "code": "ERROR_500", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}Active Requests
Section titled “Active Requests”GET /api/v1/exec/monitor/active-requests
Section titled “GET /api/v1/exec/monitor/active-requests”Lists every script HTTP request currently in flight. Each entry includes the execution ID, script path, client metadata, request line, start timestamp, and elapsed milliseconds. Tokens in URLs are redacted.
This endpoint takes no parameters.
curl -X GET https://api.hoody.io/api/v1/exec/monitor/active-requestsconst active = await client.exec.monitor.getActiveRequests();{ "count": 2, "active": [ { "executionId": "exec_01HMZ7Q4N3V8F1WJ5B6RT9AKD0", "scriptPath": "/scripts/orders/checkout.ts", "hostname": "shop.example.com", "clientIp": "198.51.100.14", "method": "POST", "url": "/webhook?token=***", "startedAt": "2025-12-01T14:02:09.812Z", "duration": 1187 }, { "executionId": "exec_01HMZ7Q4N3V8F1WJ5B6RT9AKE2", "scriptPath": "/scripts/auth/session.ts", "hostname": "api.example.com", "clientIp": "203.0.113.7", "method": "GET", "url": "/v1/me", "startedAt": "2025-12-01T14:02:10.940Z", "duration": 59 } ]}{ "error": "VALIDATION_ERROR", "code": "ERROR_400", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}| Error Code | Title | Description | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Invalid input | Request parameters failed validation | Check parameter format and requirements |
{ "error": "Internal Server Error", "code": "ERROR_500", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}Per-Script Monitoring
Section titled “Per-Script Monitoring”GET /api/v1/exec/monitor/scripts
Section titled “GET /api/v1/exec/monitor/scripts”Lists tracked scripts with HTTP/websocket performance percentiles, active concurrency, VM cache state, shared-state footprint, and the eight most recent errors per script.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | No | Max number of scripts to return. Clamped to [1, 500]. Default 100. |
sort | query | string | No | Sort key. lastActivity (default) sorts by most recent activity; other keys sort descending by the matching metric. Allowed values: lastActivity, requests, errors, p95, ws_active. |
curl -X GET "https://api.hoody.io/api/v1/exec/monitor/scripts?limit=50&sort=p95"const scripts = await client.exec.monitor.listMonitorScripts({ limit: 50, sort: "p95"});{ "count": 1, "total": 84, "scripts": [ { "scriptPath": "/scripts/orders/checkout.ts", "hostname": "shop.example.com", "vmCached": true, "sharedStateBytes": 2048, "activeHttp": 1, "activeWs": 0, "concurrentRunning": 1, "http": { "total": 12890, "success": 12875, "errors": 15, "meanDurationMs": 42.7, "p50DurationMs": 31, "p95DurationMs": 118, "maxDurationMs": 412 }, "ws": { "opened": 0, "closed": 0, "normalCloses": 0, "abnormalCloses": 0, "meanSessionMs": 0, "maxSessionMs": 0 }, "recentErrors": [ { "timestamp": "2025-12-01T13:58:14.221Z", "statusCode": 504, "message": "Upstream gateway timeout", "executionId": "exec_01HMZ7KK9S5QTP4VW3YEZ2F8XA" } ], "firstSeenAt": "2025-10-04T09:11:02.000Z", "lastActivityAt": "2025-12-01T14:02:09.812Z" } ]}{ "error": "VALIDATION_ERROR", "code": "ERROR_400", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}| Error Code | Title | Description | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Invalid input | Request parameters failed validation | Check parameter format and requirements |
{ "error": "Internal Server Error", "code": "ERROR_500", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}POST /api/v1/exec/monitor/script-performance
Section titled “POST /api/v1/exec/monitor/script-performance”Returns the detailed metrics object for a single tracked script. The metrics field is an empty object {} when no script identifier can be resolved or the script is not currently tracked — this preserves backward compatibility with older clients.
This endpoint takes no parameters.
Request Body
Section titled “Request Body”The request body is an optional object payload with no defined fields.
curl -X POST https://api.hoody.io/api/v1/exec/monitor/script-performance \ -H "Content-Type: application/json" \ -d '{}'const perf = await client.exec.monitor.getScriptPerformance();{ "metrics": {}}{ "error": "VALIDATION_ERROR", "code": "ERROR_400", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}| Error Code | Title | Description | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Invalid input | Request parameters failed validation | Check parameter format and requirements |
{ "error": "Internal Server Error", "code": "ERROR_500", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}Prometheus Export
Section titled “Prometheus Export”GET /api/v1/exec/monitor/metrics
Section titled “GET /api/v1/exec/monitor/metrics”Exposes the runtime metrics registry in Prometheus 0.0.4 text exposition format. Includes HTTP request/error totals, per-script and global duration histograms (hoody_exec_http_duration_ms, hoody_exec_http_duration_ms_global), websocket connection gauges (hoody_exec_ws_connections_active), close counters (hoody_exec_ws_closes_total), metric-collection error counters, and process_start_time_seconds. Returns 404 when the server was started with --prometheus off.
This endpoint takes no parameters.
curl -X GET https://api.hoody.io/api/v1/exec/monitor/metricsconst metrics = await client.exec.monitor.prometheusExport();# HELP hoody_exec_http_requests_total Total HTTP requests handled by scripts.# TYPE hoody_exec_http_requests_total counterhoody_exec_http_requests_total{script="/scripts/orders/checkout.ts",method="POST"} 12890hoody_exec_http_requests_total{script="/scripts/auth/session.ts",method="GET"} 3924
# HELP hoody_exec_http_errors_total Total HTTP errors.# TYPE hoody_exec_http_errors_total counterhoody_exec_http_errors_total{script="/scripts/orders/checkout.ts",status="504"} 15
# HELP hoody_exec_http_duration_ms HTTP request duration in milliseconds.# TYPE hoody_exec_http_duration_ms histogramhoody_exec_http_duration_ms_bucket{script="/scripts/orders/checkout.ts",le="10"} 4821hoody_exec_http_duration_ms_bucket{script="/scripts/orders/checkout.ts",le="50"} 11420hoody_exec_http_duration_ms_bucket{script="/scripts/orders/checkout.ts",le="100"} 12560hoody_exec_http_duration_ms_bucket{script="/scripts/orders/checkout.ts",le="+Inf"} 12890hoody_exec_http_duration_ms_sum{script="/scripts/orders/checkout.ts"} 550423.7hoody_exec_http_duration_ms_count{script="/scripts/orders/checkout.ts"} 12890
# HELP hoody_exec_http_duration_ms_global Aggregate HTTP request duration in milliseconds across all scripts.# TYPE hoody_exec_http_duration_ms_global histogramhoody_exec_http_duration_ms_global_bucket{le="10"} 712340hoody_exec_http_duration_ms_global_bucket{le="50"} 1640000hoody_exec_http_duration_ms_global_bucket{le="100"} 1812000hoody_exec_http_duration_ms_global_bucket{le="+Inf"} 1842156hoody_exec_http_duration_ms_global_sum 80412301.5hoody_exec_http_duration_ms_global_count 1842156
# HELP hoody_exec_ws_connections_active Active websocket connections.# TYPE hoody_exec_ws_connections_active gaugehoody_exec_ws_connections_active 14
# HELP hoody_exec_ws_closes_total Total websocket closes.# TYPE hoody_exec_ws_closes_total counterhoody_exec_ws_closes_total{reason="normal"} 988hoody_exec_ws_closes_total{reason="abnormal"} 22
# HELP hoody_exec_metrics_errors_total Metric collection errors.# TYPE hoody_exec_metrics_errors_total counterhoody_exec_metrics_errors_total 0
# HELP process_start_time_seconds Process start time in unix epoch seconds.# TYPE process_start_time_seconds gaugeprocess_start_time_seconds 1764597731{ "error": "VALIDATION_ERROR", "code": "ERROR_400", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}| Error Code | Title | Description | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Invalid input | Request parameters failed validation | Check parameter format and requirements |
# prometheus exporter disabled (--prometheus off){ "error": "Internal Server Error", "code": "ERROR_500", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}System Lifecycle
Section titled “System Lifecycle”GET /api/v1/exec/system/restart-status
Section titled “GET /api/v1/exec/system/restart-status”Reports whether the exec server is currently in a state where a restart can be safely initiated. Includes uptime, the count and identities of in-flight requests, and a restartReady flag that summarizes readiness.
This endpoint takes no parameters.
curl -X GET https://api.hoody.io/api/v1/exec/system/restart-statusconst status = await client.exec.system.getRestartStatus();{ "canRestart": true, "uptime": 432198, "uptimeFormatted": "5d 0h 3m 18s", "activeRequests": 7, "active": [ { "executionId": "exec_01HMZ7Q4N3V8F1WJ5B6RT9AKD0", "scriptPath": "/scripts/orders/checkout.ts" } ], "restartReady": true}{ "error": "VALIDATION_ERROR", "code": "ERROR_400", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}| Error Code | Title | Description | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Invalid input | Request parameters failed validation | Check parameter format and requirements |
{ "error": "Internal Server Error", "code": "ERROR_500", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}POST /api/v1/exec/system/restart
Section titled “POST /api/v1/exec/system/restart”Triggers a graceful restart of the exec server. When graceful is enabled, in-flight requests are drained up to drainTimeoutMs before the process is recycled.
This endpoint takes no parameters.
Request Body
Section titled “Request Body”| Name | Type | Required | Default | Description |
|---|---|---|---|---|
graceful | boolean | No | true | Graceful |
drainTimeoutMs | integer | No | 5000 | Drain Timeout Ms |
reason | string | No | "API restart request" | Reason |
curl -X POST https://api.hoody.io/api/v1/exec/system/restart \ -H "Content-Type: application/json" \ -d '{ "graceful": true, "drainTimeoutMs": 10000, "reason": "Deploying v1.42.0" }'await client.exec.system.restartServer({ graceful: true, drainTimeoutMs: 10000, reason: "Deploying v1.42.0"});{ "error": "VALIDATION_ERROR", "code": "ERROR_400", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}| Error Code | Title | Description | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Invalid input | Request parameters failed validation | Check parameter format and requirements |
{ "error": "Internal Server Error", "code": "ERROR_500", "timestamp": "2025-12-01T14:02:11.000Z", "details": {}}