Features
Deployments
View Deployment Logs

View Deployment Logs

Feature ID: DEP-001 Category: Deployments Required Permission: project.deployments.view API Endpoint: GET /api/v1/deployments/{deployment_id}/logs


Overview

View comprehensive logs for deployment operations including step-by-step progress, container output, application logs, and database logs. The OEC.SH platform captures and stores logs from multiple sources to help you debug issues and understand deployment behavior.

Use this feature when you need to:

  • Debug failed deployments by examining error messages
  • Monitor real-time deployment progress
  • Review Docker container output (stdout/stderr)
  • Investigate application errors in Odoo logs
  • Analyze database queries and connection issues
  • Understand which deployment step caused a failure
  • Export logs for external analysis or support tickets

Available log types:

  1. Deployment Logs - Step-by-step deployment process tracking
  2. Container Logs - Docker stdout/stderr from Odoo and PostgreSQL
  3. Odoo Application Logs - Odoo-specific logs (modules, HTTP requests, errors)
  4. PostgreSQL Database Logs - Database server logs and queries

Prerequisites

Required Access

  • Permission: project.deployments.view (Project Admin or Org Member)
  • Organization Membership: Active member of the organization

What You Need

  • At least one deployment (completed or in progress)
  • Environment must be deployed to view container logs

How to View Deployment Logs

Method 1: Real-Time Progress (During Deployment)

When you trigger a deployment, the DeploymentProgress component automatically appears:

  1. Navigate to your environment's page
  2. Trigger deployment via "Deploy" button
  3. DeploymentProgress widget appears automatically
  4. View real-time updates every 2 seconds:
    • Progress bar (0-100%)
    • Current step indicator
    • Latest message with timing
    • Expandable log entries per step

Step Status Indicators:

  • Green checkmark: Step completed successfully
  • Blue spinner: Step currently running
  • Red X: Step failed with error
  • Gray circle: Step pending

Example Progress Display:

Deployment Progress: 45%

✓ Initializing (1.2s)
✓ Connecting to server (2.3s)
✓ Creating Docker network (1.5s)
✓ Creating PostgreSQL container (4.2s)
⟳ Cloning repository (8.7s...)
  Latest: Cloning project repository from GitHub...
○ Pulling Odoo image
○ Starting container
... (17 steps total)

Method 2: Environment Logs Tab

Access historical and live logs after deployment:

Step 1: Navigate to Environment

  1. Go to DashboardEnvironments
  2. Click environment name to open details
  3. Click Edit tab
  4. Click Logs sub-tab

Step 2: Choose Log Type

Container Logs Sub-tab:

  • Toggle between Odoo or PostgreSQL logs
  • Select line count: 50, 100, 200, 500
  • Click Refresh to fetch latest logs
  • Logs displayed with line numbers in terminal style

Example Container Log View:

Line   Log Output
────────────────────────────────────────────────
  1    2024-12-11 10:30:45,123 INFO odoo: Odoo version 18.0
  2    2024-12-11 10:30:45,456 INFO odoo: Using configuration file at /etc/odoo/odoo.conf
  3    2024-12-11 10:30:47,789 INFO odoo.modules.loading: Modules loaded.
  4    2024-12-11 10:30:48,012 INFO werkzeug: 127.0.0.1 - - [11/Dec/2024 10:30:48] "GET / HTTP/1.1" 200

Deployment Logs Sub-tab:

  • Dropdown to select deployment (by version number)
  • Shows deployment metadata: version, status, git commit
  • Displays all log entries grouped by step
  • Color-coded by log level (info, warning, error)
  • Expandable details per step

Example Deployment Log View:

Deployment #3 - Failed
Git Commit: abc123def456 (main)
Started: 2024-12-11 10:25:00
Duration: 127 seconds

✓ Initializing (10%)
  [INFO] 10:25:00 - Starting deployment for environment env-123
  [INFO] 10:25:01 - Deployment ID: deploy-456

✓ Connecting (20%)
  [INFO] 10:25:02 - Connecting to server 203.0.113.100...
  [INFO] 10:25:03 - SSH connection established (1.3s)

✗ Cloning Repository (30%)
  [INFO] 10:25:04 - Cloning from github.com/org/repo
  [ERROR] 10:25:15 - Failed to clone repository
  [ERROR] 10:25:15 - Permission denied (publickey)

Method 3: API Access

Fetch logs programmatically via REST API:

Get Deployment Logs

GET /api/v1/deployments/{deployment_id}/logs
 
Query Parameters:
  level: string (optional) - Filter by log level: debug|info|warning|error
  skip: int (optional) - Pagination offset (default: 0)
  limit: int (optional) - Number of logs (default: 500, max: 500)

Example Request:

curl -X GET "https://api.oec.sh/api/v1/deployments/deploy-uuid/logs?level=error&limit=100" \
  -H "Authorization: Bearer YOUR_TOKEN"

Example Response:

{
  "deployment_id": "deploy-uuid",
  "logs": [
    {
      "id": "log-uuid-1",
      "level": "error",
      "message": "Failed to clone repository: Permission denied",
      "timestamp": "2024-12-11T10:25:15Z",
      "step": "cloning_repo",
      "data": {
        "exit_code": 128,
        "stderr": "Permission denied (publickey)"
      }
    }
  ]
}

Get Container Logs

GET /api/v1/projects/{project_id}/environments/{env_id}/logs
 
Query Parameters:
  log_type: string (required) - Type: deployment|container|odoo|postgres
  lines: int (optional) - Number of lines (10-5000, default: 100)
  deployment_id: UUID (optional) - Specific deployment (for log_type=deployment)

Example Request (Odoo Container Logs):

curl -X GET "https://api.oec.sh/api/v1/projects/proj-uuid/environments/env-uuid/logs?log_type=odoo&lines=200" \
  -H "Authorization: Bearer YOUR_TOKEN"

Example Response:

{
  "log_type": "odoo",
  "logs": [
    "2024-12-11 10:30:45 INFO odoo: Odoo version 18.0",
    "2024-12-11 10:30:47 INFO odoo.modules.loading: Modules loaded",
    "2024-12-11 10:31:00 WARNING odoo.http: Session expired"
  ],
  "lines_returned": 3
}

Understanding Log Types

1. Deployment Process Logs

Source: PostgreSQL database (DeploymentLog table) Retention: Permanent (until deployment deleted) Storage: Indexed by deployment_id and timestamp

What's Logged:

  • SSH connection status
  • Docker commands executed
  • Container creation steps
  • Git clone operations
  • Database initialization
  • DNS configuration
  • Health check results
  • Error messages with context

Log Levels:

  • DEBUG: Detailed technical information (Docker commands, file paths)
  • INFO: Normal operational messages (step completion, timing)
  • WARNING: Non-critical issues (slow operations, retries)
  • ERROR: Failures that stop deployment

Deployment Steps (17 total):

  1. Initializing
  2. Connecting
  3. Creating network
  4. Creating PostgreSQL
  5. Cloning platform repos
  6. Cloning org repos
  7. Cloning project repo
  8. Pulling Odoo image
  9. Generating config
  10. Starting container
  11. Installing dependencies
  12. Initializing database
  13. Verifying DNS
  14. Configuring Traefik
  15. Configuring DNS
  16. Health check
  17. Completed

2. Docker Container Logs

Source: docker logs {container_name} via SSH Retention: Managed by Docker daemon (not stored in OEC.SH database) Access: On-demand fetch from remote server

What's Logged:

  • Container stdout/stderr output
  • Application startup messages
  • Runtime errors and exceptions
  • HTTP request logs (if enabled)

Odoo Container Logs ({env_id}_odoo):

INFO odoo: Odoo Server 18.0
INFO odoo.modules.loading: loading 45 modules...
INFO werkzeug: 127.0.0.1 - "GET / HTTP/1.1" 200 -
WARNING odoo.addons.base.models.res_users: Login failed
ERROR odoo.sql_db: Programming error: column "field" does not exist

PostgreSQL Container Logs ({env_id}_db):

LOG: database system is ready to accept connections
LOG: checkpoint starting: time
WARNING: could not open statistics file "pg_stat_tmp/global.stat": No such file or directory
ERROR: relation "table_name" does not exist at character 15

3. Odoo Application Logs

Source: Docker container logs or /var/log/odoo/odoo.log (fallback) Configuration: logfile=False in odoo.conf (logs to stdout for Docker)

What's Logged:

  • Module installation/upgrade logs
  • Database migration logs
  • Odoo server lifecycle events
  • Python exceptions with tracebacks
  • HTTP requests (if verbose logging enabled)

Example Odoo Logs:

2024-12-11 10:30:45,123 123 INFO test-db odoo.modules.loading: loading module sale
2024-12-11 10:30:46,456 123 INFO test-db odoo.modules.registry: module sale: creating or updating database tables
2024-12-11 10:30:47,789 123 WARNING test-db odoo.addons.base.models.res_partner: Partner email validation failed
2024-12-11 10:30:48,012 123 ERROR test-db odoo.http: Exception during request handling
Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/odoo/http.py", line 1710, in _serve_db
    return service_model.dispatch(request.httprequest.path, request)
ValueError: Invalid field value

4. PostgreSQL Database Logs

Source: PostgreSQL container stdout Configuration: Configured via postgresql.conf in container

What's Logged:

  • Connection attempts (successful/failed)
  • Query execution (if log_statement enabled)
  • Slow queries (if log_min_duration_statement set)
  • Database errors (syntax, permissions, constraints)
  • Replication lag warnings (if replica deployed)

Example PostgreSQL Logs:

2024-12-11 10:30:00 UTC [1] LOG:  database system is ready to accept connections
2024-12-11 10:30:45 UTC [123] LOG:  connection received: host=172.18.0.3 port=45678
2024-12-11 10:30:45 UTC [123] LOG:  connection authorized: user=odoo database=test-db
2024-12-11 10:35:00 UTC [456] ERROR:  duplicate key value violates unique constraint "res_users_login_key"
2024-12-11 10:35:00 UTC [456] DETAIL:  Key (login)=(admin) already exists.

Real-Time Log Updates

Server-Sent Events (SSE)

OEC.SH uses SSE for real-time deployment progress updates:

How It Works:

  1. Frontend connects to /api/v1/events/stream?token={jwt}
  2. Backend publishes events via Redis pub/sub
  3. Events delivered to all connected clients
  4. Automatic reconnection on disconnect

Event Types:

  • deployment_progress - Deployment step updates
  • task.status_changed - Background task status
  • task.progress_updated - Progress percentage updates

Example SSE Event:

{
  "event": "deployment_progress",
  "data": {
    "deployment_id": "deploy-uuid",
    "status": "deploying",
    "step": "cloning_repo",
    "progress": 40,
    "message": "Cloning project repository from GitHub..."
  }
}

Frontend Integration:

import { useSSEEvent } from "@/hooks/useEventStream";
 
// Listen for deployment updates
useSSEEvent("deployment_progress", (event) => {
  if (event.data.deployment_id === currentDeploymentId) {
    setProgress(event.data.progress);
    setCurrentStep(event.data.step);
  }
});

HTTP Polling (DeploymentProgress Component)

In addition to SSE, the DeploymentProgress component polls every 2 seconds:

Why Polling?:

  • More reliable than SSE for high-frequency updates
  • Fetches complete deployment state (not just deltas)
  • Auto-stops on completion/failure
  • Handles network interruptions gracefully

Polling Endpoint:

GET /api/v1/deployments/{deployment_id}/progress

Response Includes:

  • Overall progress percentage (0-100%)
  • Current deployment status
  • All 17 steps with individual status
  • Latest log message per step
  • All log entries per step (expandable)
  • Error details if failed

Filtering and Searching Logs

Filter by Log Level

API Parameter:

GET /deployments/{id}/logs?level=error

Available Levels:

  • debug - Verbose technical details
  • info - Normal operational messages (default)
  • warning - Non-critical issues
  • error - Failures and exceptions

Use Cases:

  • Debugging: Set level=debug for maximum detail
  • Monitoring: Set level=warning to catch issues early
  • Troubleshooting: Set level=error to find root cause

Filter by Deployment Step

Logs include step field for filtering:

Available Steps:

  • initializing
  • connecting
  • creating_network
  • creating_postgres
  • cloning_repo
  • pulling_image
  • starting_container
  • (and 10 more - see full list above)

Example: Find logs only from repository cloning step:

SELECT * FROM deployment_logs
WHERE deployment_id = 'deploy-uuid'
AND step = 'cloning_repo'
ORDER BY timestamp;

Pagination

Large deployments may generate thousands of log entries:

API Parameters:

GET /deployments/{id}/logs?skip=0&limit=500

Limits:

  • Default: 500 logs per request
  • Maximum: 500 logs per request
  • Use skip for pagination (skip = page * limit)

Example (Get logs 500-1000):

GET /deployments/{id}/logs?skip=500&limit=500

Troubleshooting Common Issues

Issue 1: No Container Logs Available

Symptoms:

Container 'env-123_odoo' not found. Deploy the environment first.

Causes:

  • Environment not yet deployed
  • Container stopped or removed
  • Wrong container name

Solution:

  1. Check environment status: should be RUNNING
  2. Verify deployment succeeded: Check latest deployment status
  3. Redeploy if needed: Click "Deploy" button

Issue 2: Container Logs Are Empty

Symptoms: Container logs endpoint returns empty array

Causes:

  • Container just started (no output yet)
  • Odoo configured to log to file instead of stdout
  • Docker log driver misconfigured

Solution:

  1. Wait 10-15 seconds after container start
  2. Check Odoo is actually running: docker ps on server
  3. Verify odoo.conf has logfile = False
  4. Fallback: Read /var/log/odoo/odoo.log directly

Issue 3: Deployment Logs Missing Steps

Symptoms: Some deployment steps have no log entries

Causes:

  • Deployment interrupted mid-process
  • Database connection lost during deployment
  • ARQ worker crashed

Solution:

  1. Check deployment status: If FAILED, retry deployment
  2. Review error message in deployment record
  3. Check ARQ worker logs on backend server
  4. Contact support if issue persists

Issue 4: "Permission Denied" Error

Symptoms:

403 Forbidden: You don't have permission to view deployment logs

Causes:

  • Missing project.deployments.view permission
  • Not a member of the organization
  • Token expired

Solution:

  1. Verify you're a member of the organization
  2. Request permission from organization owner/admin
  3. Refresh your browser (token renewal)
  4. Check role assignment in SettingsMembers

Issue 5: SSH Connection Failed During Log Fetch

Symptoms:

Failed to fetch container logs: SSH connection timeout

Causes:

  • Server offline or unreachable
  • Firewall blocking SSH port (22)
  • SSH credentials invalid

Solution:

  1. Check server status: Navigate to SettingsServers
  2. Test SSH connection: Click "Test Connection" button
  3. Verify server IP and credentials
  4. Check firewall allows SSH from OEC.SH IP addresses

Log Retention and Storage

Deployment Process Logs

Storage: PostgreSQL database (deployment_logs table) Retention: Permanent (no automatic cleanup) Deletion: CASCADE delete when parent deployment deleted Size: Typically 1-5 KB per deployment (100-500 log entries)

Indexes:

  • idx_log_deployment_time (deployment_id, timestamp)
  • ix_deployment_logs_deployment_id
  • ix_deployment_logs_timestamp

Container Logs

Storage: Docker daemon on remote servers (not in OEC.SH database) Retention: Docker-managed (typically until container removed) Fetching: On-demand via SSH (not stored persistently) Size: Varies (1 MB - 100 MB+ for long-running containers)

Docker Log Driver: Uses default json-file driver with no rotation limit


Download Logs for External Analysis

Not Yet Implemented: Export functionality for logs

Workaround:

  1. Copy logs from UI (Ctrl+A, Ctrl+C)
  2. Use API to fetch logs programmatically
  3. SSH into server and access Docker logs directly:
    docker logs env-123_odoo > odoo.log
    docker logs env-123_db > postgres.log

Best Practices

1. Monitor Deployments in Real-Time

Do: Keep deployment progress widget open during deployment ✅ Do: Watch for warning messages that indicate potential issues ❌ Don't: Navigate away from deployment page during critical operations


2. Review Logs After Failed Deployments

Do: Read error messages carefully (they often contain the solution) ✅ Do: Check the specific step that failed (narrows down the issue) ✅ Do: Look for patterns in multiple failed deployments ❌ Don't: Retry blindly without understanding the failure


3. Use Appropriate Log Level

Do: Use level=error to find critical issues quickly ✅ Do: Use level=debug when reporting bugs to support ❌ Don't: Enable debug logging in production (performance impact)


4. Archive Important Logs

Do: Download logs for critical production deployments ✅ Do: Keep deployment history for compliance/audit ❌ Don't: Rely solely on container logs (they're ephemeral)


5. Check Container Logs for Runtime Issues

Do: Review Odoo logs when users report errors ✅ Do: Monitor PostgreSQL logs for slow queries ✅ Do: Set up external log aggregation (ELK, Datadog) for production ❌ Don't: Ignore warning messages (they often precede failures)


API Reference

Get Deployment Logs

Endpoint: GET /api/v1/deployments/{deployment_id}/logs

Path Parameters:

  • deployment_id (UUID, required) - Deployment ID

Query Parameters:

  • level (string, optional) - Filter by log level: debug | info | warning | error
  • skip (integer, optional) - Pagination offset (default: 0)
  • limit (integer, optional) - Number of logs (default: 500, max: 500)

Response (200 OK):

{
  "deployment_id": "uuid",
  "logs": [
    {
      "id": "uuid",
      "level": "info",
      "message": "string",
      "timestamp": "2024-12-11T10:00:00Z",
      "step": "string",
      "data": {}
    }
  ]
}

Errors:

  • 403 Forbidden - Missing permission project.deployments.view
  • 404 Not Found - Deployment not found

Get Deployment Progress

Endpoint: GET /api/v1/deployments/{deployment_id}/progress

Response (200 OK):

{
  "deployment_id": "uuid",
  "status": "deploying",
  "progress": 45,
  "current_step": "cloning_repo",
  "steps": [
    {
      "step": "initializing",
      "status": "completed",
      "message": "Initialized deployment (1.2s)",
      "logs": [
        {
          "level": "info",
          "message": "Starting deployment...",
          "timestamp": "2024-12-11T10:00:00Z"
        }
      ]
    }
  ],
  "error_message": null
}

Get Environment Logs

Endpoint: GET /api/v1/projects/{project_id}/environments/{env_id}/logs

Query Parameters:

  • log_type (string, required) - Type: deployment | container | odoo | postgres
  • lines (integer, optional) - Number of lines (10-5000, default: 100)
  • deployment_id (UUID, optional) - Specific deployment (for log_type=deployment)

Response (200 OK):

{
  "log_type": "odoo",
  "logs": ["line 1", "line 2", "..."],
  "lines_returned": 100,
  "error": null
}

Errors:

  • 400 Bad Request - Invalid log_type or lines parameter
  • 403 Forbidden - Missing permission
  • 404 Not Found - Environment not found or container not deployed

Related Documentation


Last Updated: December 11, 2025 Applies to: OEC.SH v2.0+ Related Sprint: Sprint 2E41 - Documentation System