oCoreoCore Docs

Monitoring

Monitor oCore with health endpoints, structured logging, and alerting to ensure reliable operation.

Monitoring ensures your oCore deployment is healthy and allows you to detect problems before they affect users. This guide covers the built-in health endpoint, log management, and alerting strategies.

Health Endpoint

oCore exposes a health check endpoint at /api/health that returns the status of core subsystems.

curl https://ocore.example.com/api/health
{
  "status": "ok",
  "database": "connected",
  "version": "1.0.0"
}

Use this endpoint for:

  • Load balancer health checks -- Route traffic only to healthy instances
  • Uptime monitoring -- External services like UptimeRobot, Pingdom, or Healthchecks.io
  • Docker health checks -- Already configured in the production Docker Compose file

Docker Health Check

The backend container includes a built-in health check. Docker automatically monitors the container and marks it as unhealthy if the check fails:

docker-compose.prod.yml (backend health check)
services:
  backend:
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s

Check the health status:

docker inspect --format='{{.State.Health.Status}}' ocore-backend-1

Log Management

Docker Logs

All oCore services write to Docker's logging system. View logs with:

# All services
docker compose -f docker-compose.prod.yml logs -f

# Backend only
docker compose -f docker-compose.prod.yml logs -f backend

# Last 100 lines
docker compose -f docker-compose.prod.yml logs --tail 100 backend

# Since a specific time
docker compose -f docker-compose.prod.yml logs --since "2026-02-26T00:00:00" backend

Log Rotation

Docker's default logging driver (json-file) does not rotate logs automatically. Configure rotation to prevent disk exhaustion:

/etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "5"
  }
}

Apply the change:

sudo systemctl restart docker

This limits each container's log to 5 files of 50 MB each (250 MB total per container).

Structured Logging

The oCore backend emits structured JSON log entries. Key fields:

FieldDescription
levelLog severity: debug, info, warn, error
msgHuman-readable message
timeISO 8601 timestamp
methodHTTP method (for request logs)
uriRequest path
statusHTTP response status code
latencyRequest duration

Forwarding Logs

To forward logs to an external aggregation service, use Docker's logging drivers:

/etc/docker/daemon.json (Loki example)
{
  "log-driver": "loki",
  "log-opts": {
    "loki-url": "http://loki:3100/loki/api/v1/push",
    "loki-batch-size": "400"
  }
}

Other supported destinations include Fluentd, syslog, AWS CloudWatch, and Google Cloud Logging. See the Docker logging drivers documentation for the full list.

Resource Monitoring

Container Resource Usage

Monitor CPU and memory consumption of each container:

# Real-time resource usage
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"

Disk Usage

Monitor disk space for Docker volumes:

# Volume sizes
docker system df -v | grep -A 100 "VOLUME NAME"

# Total Docker disk usage
docker system df

PostgreSQL Metrics

Monitor database health with built-in views:

-- Active connections
SELECT count(*) as active,
       max_conn as max,
       count(*) * 100 / max_conn as pct_used
FROM pg_stat_activity,
     (SELECT setting::int as max_conn FROM pg_settings WHERE name = 'max_connections') m
WHERE state = 'active'
GROUP BY max_conn;

-- Database size
SELECT pg_size_pretty(pg_database_size('ocore')) as db_size;

-- Table sizes
SELECT relname as table,
       pg_size_pretty(pg_total_relation_size(relid)) as size
FROM pg_stat_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 10;

Alerting

Basic Alerting with Healthchecks.io

Healthchecks.io provides free monitoring with alerts via email, Slack, or PagerDuty.

Set up a cron-based ping:

# Ping Healthchecks.io every 5 minutes if the health check passes
*/5 * * * * curl -fsS -o /dev/null https://ocore.example.com/api/health && \
  curl -fsS -o /dev/null https://hc-ping.com/your-check-uuid

If the health check fails, the ping to Healthchecks.io stops, and you receive an alert after the configured grace period.

Alerting with Uptime Kuma

Uptime Kuma is a self-hosted monitoring tool you can run alongside oCore:

docker-compose.monitoring.yml
services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    ports:
      - "3001:3001"
    volumes:
      - uptime_kuma_data:/app/data
    restart: unless-stopped

volumes:
  uptime_kuma_data:

Configure it to monitor:

  • https://ocore.example.com/api/health -- Backend API
  • https://ocore.example.com -- Frontend dashboard
  • TCP ocore.example.com:2222 -- SSH gateway

Alert Checklist

At minimum, set up alerts for:

CheckConditionAlert
Health endpointNon-200 response for 2+ minutesCritical
Disk usageAbove 85%Warning
Disk usageAbove 95%Critical
Container restartAny service restartedWarning
Backup jobDid not complete on scheduleCritical
TLS certificateExpiring within 14 daysWarning

Quick Monitoring Setup

For a minimal monitoring setup on a single server:

  1. Enable Docker log rotation (see above)
  2. Set up a health check cron with Healthchecks.io (free tier)
  3. Monitor disk usage with a simple cron alert:
/opt/ocore/check-disk.sh
#!/bin/bash
THRESHOLD=85
USAGE=$(df / | tail -1 | awk '{print $5}' | tr -d '%')

if [ "$USAGE" -gt "$THRESHOLD" ]; then
  echo "Disk usage at ${USAGE}% on $(hostname)" | \
    mail -s "oCore: Disk space warning" admin@example.com
fi
# Check every hour
0 * * * * /opt/ocore/check-disk.sh

This covers the essentials. Add more comprehensive monitoring (Prometheus, Grafana, Loki) as your deployment grows. See the Scaling guide for multi-server monitoring considerations.

Was this page helpful?