Agent
Lightweight monitoring agent installed on managed servers for real-time metrics and container log streaming.
The oCore Agent is a lightweight Go binary that runs as a Docker container on each managed server. It replaces SSH-based polling with an outbound push model, delivering real-time system metrics, container health data, and log streaming to the oCore backend.
Server Detail Page
View agent status, metrics, and connection health for a server.
What is the oCore Agent
The oCore Agent (ocore-agent) is a single-purpose process that collects server and Docker container metrics and pushes them to the oCore backend over HTTPS. It also opens a WebSocket connection to stream container logs in real time.
Unlike SSH polling -- where the oCore backend periodically connects to each server to run commands -- the agent initiates all connections outbound. This means:
- No inbound ports need to be opened beyond SSH (used only for initial provisioning)
- Metrics arrive continuously rather than at poll intervals
- Container logs are streamed live for real-time monitoring and error detection
The agent is packaged as a Docker image (yuikotegawa/ocore-agent) and runs alongside your Odoo containers on each managed server.
Benefits
| Feature | Without Agent (SSH Polling) | With Agent |
|---|---|---|
| System metrics | Collected every 60s via SSH commands | Pushed every 30s natively |
| Container health | Requires SSH + docker inspect | Direct Docker API access, included in every metrics push |
| Log streaming | Tail via SSH session (one container at a time) | WebSocket stream for all containers simultaneously |
| Network I/O | Parsed from /proc/net/dev via SSH | Read directly from /proc with nanosecond precision |
| SSH overhead | One SSH session per poll cycle per server | Zero SSH sessions for monitoring (SSH used only for provisioning and deployments) |
| Error detection | Requires separate log collection job | Integrated -- agent log stream feeds the error fingerprinting pipeline |
Installation
The agent is automatically deployed during server provisioning. When you add a server to oCore, the provisioning pipeline includes an Agent Install step that:
- Generates a unique agent token (SHA-256 hashed, stored in the database)
- Pulls the
yuikotegawa/ocore-agentDocker image on the server - Starts the agent container with the required environment variables
- Verifies the agent connects back to the oCore backend
You do not need to install the agent manually. If the agent needs to be redeployed (for example, after a version update or if the container was removed), you can trigger it from the server detail page or via the API.
Manual Redeployment
curl -X POST https://ocore.example.com/api/servers/{serverId}/agent/deploy \
-H "Authorization: Bearer $TOKEN"ocore server deploy-agent <server-id>This enqueues a background job that SSH-es into the server, provisions a new token (rotating the old one), and starts the agent container.
Docker Container Details
The agent runs as a Docker container with the following configuration:
- Image:
yuikotegawa/ocore-agent - User: Non-root (UID 1000), with Docker group access via
--group-add - Volumes:
/procmounted as/host/proc(read-only) for system metrics - Restart policy:
unless-stopped
How It Works
Metrics Collection
The agent collects system and container metrics on a configurable interval (default: 30 seconds) and pushes them to the oCore backend via HTTPS POST.
System metrics collected:
- CPU usage percentage
- Memory: total, used, and available bytes
- Disk: total and used bytes for the root filesystem
- Network: total RX and TX bytes
- Load averages (1m, 5m, 15m)
- System uptime
Per-container metrics collected:
- Container state and health status
- Restart count
- CPU usage percentage
- Memory usage and limit
The agent authenticates each request using a Bearer token in the Authorization header, along with the server UUID in the X-Server-ID header. The backend validates the token against the stored SHA-256 hash using constant-time comparison.
Log Streaming
When log streaming is enabled (the default), the agent opens a WebSocket connection to the oCore backend and streams Docker container logs in real time. The agent monitors all running containers and sends log batches as they are produced.
The WebSocket connection uses ping/pong keepalive (30-second ping interval, 90-second read deadline) to detect dead connections. If the connection drops, the agent reconnects automatically.
Backoff and Resilience
If the backend is unreachable, the agent uses exponential backoff to avoid flooding the network:
- Backoff formula:
min(60s, 1s * 2^failures) - After 6 consecutive failures, the agent waits 60 seconds between retries
- A single successful push resets the backoff counter to zero
The agent handles Docker unavailability gracefully -- if the Docker daemon is not running, the agent continues collecting system metrics without container data.
Agent Status
The server detail page displays the agent's connection status, including:
| Field | Description |
|---|---|
| Status | connected (actively reporting) or disconnected (no recent heartbeat) |
| Version | The agent binary version, parsed from the User-Agent header (ocore-agent/X.Y.Z) |
| Last seen | Timestamp of the most recent metrics push |
Freshness Threshold
The agent is considered active if it has reported within the last 120 seconds. With a 30-second push interval, this means the agent must miss 4 consecutive reports before it is marked as disconnected. This conservative threshold avoids false positives from transient network delays.
curl https://ocore.example.com/api/servers/{serverId}/agent-status \
-H "Authorization: Bearer $TOKEN"ocore server agent-status <server-id>Monitoring with the Agent
When the agent is active on a server, oCore automatically uses agent-reported data instead of SSH polling for:
- Server metrics -- CPU, memory, disk, and network charts on the server detail page
- Container health -- Container state, health status, and restart counts
- Capacity estimates -- Real-time resource availability for instance planning
Workers in the oCore backend check IsAgentActive() before each polling cycle. If the agent has reported within the freshness threshold, the SSH-based collection job is skipped entirely, reducing SSH session overhead to zero for monitoring purposes.
Fallback to SSH
If the agent disconnects or stops reporting, oCore automatically falls back to SSH-based polling. No manual intervention is required -- the transition is seamless and happens within 120 seconds of the agent going silent.
Error Detection
When the agent streams container logs via WebSocket, the oCore backend feeds those log lines into the error fingerprinting pipeline. This means agent-connected instances get continuous error detection without any additional configuration.
The pipeline:
- Agent streams container logs to the backend in real time
- Backend routes log batches to the
LogStreamServicefor processing - Odoo container logs are parsed and analyzed for error patterns (tracebacks, warnings, critical errors)
- Detected errors are fingerprinted and grouped into the error tracking system
For more details on error fingerprinting, see the Monitoring page.
Agent Token Management
Each server has a unique agent token that authenticates the agent with the oCore backend. Tokens are generated during provisioning and can be rotated or revoked at any time.
Provisioning a New Token
curl -X POST https://ocore.example.com/api/servers/{serverId}/agent-token \
-H "Authorization: Bearer $TOKEN"This generates a new token and returns it in the response. The previous token is immediately invalidated.
Token Shown Once
The plain agent token is returned only once during provisioning. oCore stores only the SHA-256 hash. If the token is lost, provision a new one -- the agent container must be restarted with the new token.
Revoking a Token
curl -X DELETE https://ocore.example.com/api/servers/{serverId}/agent-token \
-H "Authorization: Bearer $TOKEN"Revoking a token disconnects the agent immediately. The agent status resets to disconnected and the version and last-seen fields are cleared.
Environment Variables
The agent is configured entirely through environment variables. These are set automatically during provisioning.
| Variable | Required | Default | Description |
|---|---|---|---|
OCORE_ENDPOINT | Yes | -- | oCore backend URL (e.g., https://api.ocore.example.com) |
OCORE_AGENT_TOKEN | Yes | -- | Pre-shared authentication token |
OCORE_SERVER_ID | Yes | -- | Server UUID assigned by oCore |
OCORE_PUSH_INTERVAL | No | 30 | Metrics push interval in seconds (min: 10, max: 300) |
OCORE_LOG_LEVEL | No | info | Log verbosity: debug, info, warn, error |
OCORE_LOG_STREAM_ENABLED | No | true | Set to false to disable container log streaming |
OCORE_PROC_PATH | No | /proc | Path to procfs (set to /host/proc when containerized) |
OCORE_DISK_PATH | No | / | Path for disk usage statistics |
Required Permissions
- Deploying the agent requires
manage:serverspermission - Provisioning or revoking tokens requires
manage:serverspermission - Viewing agent status requires
view:serverspermission (any authenticated role)
Troubleshooting
Agent shows "disconnected" after provisioning
- Verify the agent container is running on the server:
docker ps | grep ocore-agent - Check agent logs:
docker logs ocore-agent - Ensure the server can reach the oCore backend URL (outbound HTTPS)
- Verify the
OCORE_ENDPOINTdoes not have a trailing slash
Agent container keeps restarting
- Check Docker logs for the error message:
docker logs --tail 50 ocore-agent - Common cause: invalid
OCORE_AGENT_TOKEN(token was rotated but container was not restarted) - Redeploy the agent from the server detail page to provision a fresh token
Metrics not appearing on the dashboard
- Confirm agent status is
connectedvia the API or server detail page - Check that the agent version is compatible with your oCore backend version
- Verify no firewall is blocking outbound HTTPS from the server to the oCore backend
Log streaming not working
- Verify
OCORE_LOG_STREAM_ENABLEDis not set tofalse - Check that the Docker socket is accessible from the agent container
- Look for WebSocket connection errors in the agent logs:
docker logs ocore-agent | grep -i websocket - Ensure the backend URL supports WebSocket upgrade (some reverse proxies need explicit configuration)