OpenCTI brings STIX2-structured cyber threat intelligence to your analysts — but its distributed architecture means a RabbitMQ backlog, an Elasticsearch cluster going red, or a stopped connector can all silently degrade your intelligence picture without any visible error on the UI. Vigilmon gives you health monitoring for every OpenCTI service: the GraphQL API server, RabbitMQ message broker, Elasticsearch/OpenSearch cluster, connector workers, MinIO object storage, Redis cache, and API response time — so you know the moment any layer fails.
What You'll Set Up
- HTTP uptime monitor for the OpenCTI API server and React frontend (port 4000)
- RabbitMQ broker health and queue depth watchdog
- Elasticsearch/OpenSearch cluster health monitor (port 9200)
- Connector worker liveness watchdogs per connector
- MinIO object storage health check (port 9000)
- Redis connectivity and memory usage monitor (port 6379)
- GraphQL API response time monitoring
Prerequisites
- OpenCTI 5.x installed and running (API server accessible on port 4000)
- OpenCTI API token with read access
- Access to the OpenCTI host for cron job installation
- A free Vigilmon account
Step 1: Monitor the OpenCTI API Server
OpenCTI exposes a /health endpoint that confirms the Node.js GraphQL API is running. When this fails, both the React frontend and all connector ingestion stop.
- Log in to vigilmon.online and click Add Monitor.
- Set Type to
HTTP / HTTPS. - Enter
http://your-opencti-host:4000/health. - Set Check interval to
1 minute. - Set Expected HTTP status to
200. - Under Response body, set Contains to
"status":"alive". - Click Save.
If you serve OpenCTI behind a reverse proxy with TLS termination, use the HTTPS URL and enable Monitor SSL certificate with a 30-day expiry alert.
Step 2: Monitor RabbitMQ Broker Health
RabbitMQ is OpenCTI's message bus — all connector-to-platform communication flows through it. A broker outage means connectors can't deliver ingested intelligence objects to OpenCTI, even though they appear to run correctly. Monitor the management API:
- In Vigilmon, click Add Monitor → HTTP / HTTPS.
- Enter
http://your-rabbitmq-host:15672/api/healthchecks/node. - Set Check interval to
1 minute. - Set Expected HTTP status to
200. - Under Authentication, set username
guest(or your RabbitMQ admin user) and password. - Under Response body, set Contains to
"status":"ok". - Click Save.
Also add a TCP monitor for the AMQP port:
- Click Add Monitor → TCP Port.
- Enter your RabbitMQ host and port
5672. - Set Check interval to
1 minute. - Click Save.
For queue depth monitoring (detect connector backlogs):
#!/bin/bash
# /usr/local/bin/opencti-rabbitmq-queue-check.sh
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-rabbitmq-queue-heartbeat-id"
RABBITMQ_URL="http://localhost:15672"
RABBITMQ_USER="guest"
RABBITMQ_PASS="guest"
# Check all OpenCTI queues for saturation
MAX_DEPTH=$(curl -s \
-u "$RABBITMQ_USER:$RABBITMQ_PASS" \
"$RABBITMQ_URL/api/queues" | \
python3 -c "
import sys, json
queues = json.load(sys.stdin)
opencti_queues = [q for q in queues if 'opencti' in q.get('name','').lower()]
max_depth = max((q.get('messages', 0) for q in opencti_queues), default=0)
print(max_depth)
" 2>/dev/null || echo "9999")
# Alert if any queue exceeds 1000 messages (connector backlog)
if [ "$MAX_DEPTH" -lt 1000 ]; then
curl -s "$HEARTBEAT_URL" > /dev/null
fi
Schedule every 5 minutes with a 10-minute heartbeat interval.
Step 3: Monitor Elasticsearch/OpenSearch Cluster Health
OpenCTI stores all STIX2 intelligence objects in Elasticsearch or OpenSearch. A red cluster health status means data is unreadable and all intelligence queries will fail.
- In Vigilmon, click Add Monitor → HTTP / HTTPS.
- Enter
http://your-elasticsearch-host:9200/_cluster/health. - Set Check interval to
2 minutes. - Set Expected HTTP status to
200. - Under Response body, set Does not contain to
"status":"red". - Click Save.
For a more precise alert on yellow status (reduced redundancy, not yet failed):
#!/bin/bash
# /usr/local/bin/opencti-es-health-check.sh
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-es-health-heartbeat-id"
ES_URL="http://localhost:9200"
CLUSTER_STATUS=$(curl -s "$ES_URL/_cluster/health" | \
python3 -c "import sys,json; print(json.load(sys.stdin).get('status','red'))" 2>/dev/null || echo "red")
if [ "$CLUSTER_STATUS" = "green" ]; then
curl -s "$HEARTBEAT_URL" > /dev/null
fi
Schedule every 5 minutes with a 10-minute heartbeat interval. Yellow status should generate a warning (not a page); red should trigger immediate on-call escalation.
Step 4: Monitor Connector Worker Health
OpenCTI's power comes from its 100+ connector ecosystem — but connector processes fail silently. A connector in error state for >24 hours means entire data source categories (MISP events, VirusTotal enrichment, CVE data, TAXII feeds) stop ingesting.
Monitor connector health via the OpenCTI GraphQL API:
#!/bin/bash
# /usr/local/bin/opencti-connector-check.sh
OPENCTI_URL="http://localhost:4000"
OPENCTI_TOKEN="your-opencti-api-token"
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-connector-heartbeat-id"
FAILING=$(curl -s \
-H "Authorization: Bearer $OPENCTI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query": "{ connectors { id name active state } }"}' \
"$OPENCTI_URL/graphql" | \
python3 -c "
import sys, json, time
data = json.load(sys.stdin)
connectors = data.get('data', {}).get('connectors', [])
failing = [c['name'] for c in connectors
if c.get('active') and c.get('state') in ('error', None)]
print(len(failing))
" 2>/dev/null || echo "99")
if [ "$FAILING" = "0" ]; then
curl -s "$HEARTBEAT_URL" > /dev/null
fi
Schedule every 15 minutes with a 30-minute heartbeat interval. For critical connectors (your primary MISP sync, CVE feed, or threat actor database), create individual heartbeats per connector with tighter intervals.
Step 5: Monitor MinIO Object Storage
MinIO stores file attachments, PDF reports, and exported data in OpenCTI. When MinIO storage fills up or becomes unavailable, analysts can't attach files to threat reports or export intelligence packages.
- In Vigilmon, click Add Monitor → TCP Port.
- Enter your MinIO host and port
9000. - Set Check interval to
1 minute. - Click Save.
For storage utilization:
#!/bin/bash
# /usr/local/bin/opencti-minio-disk-check.sh
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-minio-disk-heartbeat-id"
MINIO_DATA_DIR="/data/minio" # adjust to your MinIO data directory
USAGE=$(df "$MINIO_DATA_DIR" | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$USAGE" -lt 80 ]; then
curl -s "$HEARTBEAT_URL" > /dev/null
fi
Schedule hourly with a 90-minute heartbeat interval.
Step 6: Monitor Redis Health
Redis serves as OpenCTI's API cache and session store. When Redis becomes unavailable or runs out of memory, API response times degrade and user sessions are dropped.
- In Vigilmon, click Add Monitor → TCP Port.
- Enter your Redis host and port
6379. - Set Check interval to
1 minute. - Click Save.
For memory pressure monitoring:
#!/bin/bash
# /usr/local/bin/opencti-redis-memory-check.sh
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-redis-memory-heartbeat-id"
REDIS_HOST="localhost"
REDIS_PORT="6379"
USED_MB=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" INFO memory 2>/dev/null | \
grep "used_memory:" | cut -d: -f2 | tr -d $'\r')
MAX_MB=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" INFO memory 2>/dev/null | \
grep "maxmemory:" | cut -d: -f2 | tr -d $'\r')
# Only check ratio if maxmemory is configured (non-zero)
if [ -n "$MAX_MB" ] && [ "$MAX_MB" != "0" ]; then
USAGE_PCT=$(( USED_MB * 100 / MAX_MB ))
if [ "$USAGE_PCT" -lt 80 ]; then
curl -s "$HEARTBEAT_URL" > /dev/null
fi
else
# No maxmemory limit configured — just check connectivity
redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" PING > /dev/null 2>&1 && \
curl -s "$HEARTBEAT_URL" > /dev/null
fi
Schedule every 5 minutes with a 10-minute heartbeat interval.
Step 7: Monitor GraphQL API Response Time
OpenCTI's knowledge graph queries can be expensive — complex relationship traversals across millions of STIX2 objects cause analyst-facing slowdowns long before they become outages. Track API response time:
- Open the HTTP monitor you created in Step 1 (port 4000 health check).
- Under Performance, enable Alert on slow response.
- Set Alert when response time exceeds
3000 ms. - Click Save.
For the GraphQL endpoint specifically, add a monitored probe:
#!/bin/bash
# /usr/local/bin/opencti-graphql-latency-check.sh
OPENCTI_URL="http://localhost:4000"
OPENCTI_TOKEN="your-opencti-api-token"
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-graphql-latency-heartbeat-id"
START=$(date +%s%N)
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $OPENCTI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query": "{ about { version } }"}' \
"$OPENCTI_URL/graphql")
END=$(date +%s%N)
LATENCY_MS=$(( (END - START) / 1000000 ))
if [ "$HTTP_CODE" = "200" ] && [ "$LATENCY_MS" -lt 3000 ]; then
curl -s "$HEARTBEAT_URL" > /dev/null
fi
Schedule every 5 minutes with a 10-minute heartbeat interval. The about { version } query is lightweight — if even this is slow, OpenCTI's API layer is under severe pressure.
Step 8: Configure Alert Channels
- Go to Alert Channels in Vigilmon and add your notification channel — email, Slack, PagerDuty, or a webhook to your threat intelligence team's ticketing system.
- For Elasticsearch red status and RabbitMQ broker failures, route to PagerDuty — these indicate complete platform failure requiring immediate action.
- For connector health and MinIO disk alerts, use Slack or email — these are operational issues that can be addressed within a business day.
Recommended Alert Thresholds
| Monitor | Alert After | Notes | |---|---|---| | API server (port 4000) | 2 failures | Node.js restart causes ~5s gap | | RabbitMQ management API | 2 failures | Brief blip during rolling restart | | RabbitMQ AMQP (port 5672) | 1 failure | AMQP failure = connector blackout | | Elasticsearch cluster | 1 failure | Red status = immediate action | | Connector worker health | 1 failure | >24h staleness already built in | | MinIO TCP (port 9000) | 2 failures | Short restart cycles are normal | | MinIO disk (>80%) | 1 failure | Upload failures are user-visible | | Redis TCP (port 6379) | 2 failures | Fast restart, transient drops | | Redis memory (>80%) | 1 failure | OOM eviction corrupts session state | | GraphQL latency | 1 failure | 3s threshold is well above baseline |
Conclusion
With these monitors in place, Vigilmon gives you full observability across OpenCTI's distributed service architecture: API server availability, RabbitMQ message routing, Elasticsearch data integrity, connector ingestion health, MinIO file storage, Redis cache performance, and GraphQL response time. Your analysts get timely intelligence from a platform you can trust is actually running.
For more self-hosted threat intelligence monitoring guides, visit vigilmon.online.