Skip to content

How to Connect Prometheus to Odoo: Metrics & Monitoring Guide

DeployMonkey Team · March 23, 2026 10 min read

Why Use Prometheus with Odoo?

Prometheus is the standard for infrastructure and application monitoring. It scrapes metrics from targets at regular intervals, stores time-series data efficiently, and supports powerful queries with PromQL. For Odoo deployments, Prometheus provides the metrics layer that answers: How fast are requests being served? How many database connections are in use? Are cron jobs running on schedule? Is memory leaking?

Unlike log-based monitoring, Prometheus gives you quantitative, time-series data that you can alert on, graph in Grafana, and use for capacity planning.

Architecture

Odoo Server ──── Node Exporter ────┐
     │                              │
     ├── Odoo Custom Exporter ──────├──── Prometheus ──── Grafana
     │                              │         │
PostgreSQL ── PG Exporter ──────────┘    Alertmanager
                                              │
                                    Slack / Email / PagerDuty

Step 1: Install Prometheus

# Docker (recommended)
docker run -d --name prometheus \
  -p 9090:9090 \
  -v /etc/prometheus:/etc/prometheus \
  prom/prometheus

# Or native install
wget https://github.com/prometheus/prometheus/releases/download/v2.50.0/prometheus-2.50.0.linux-amd64.tar.gz
tar xf prometheus-*.tar.gz
cd prometheus-*
./prometheus --config.file=prometheus.yml

Step 2: Install Exporters

Node Exporter (Server Metrics)

# Docker
docker run -d --name node-exporter \
  --net=host --pid=host \
  -v /:/host:ro,rslave \
  prom/node-exporter --path.rootfs=/host

# Exposes metrics on :9100/metrics

PostgreSQL Exporter

docker run -d --name pg-exporter \
  -p 9187:9187 \
  -e DATA_SOURCE_NAME="postgresql://grafana_ro:password@localhost:5432/odoo?sslmode=disable" \
  prometheuscommunity/postgres-exporter

# Exposes metrics on :9187/metrics

Step 3: Create Custom Odoo Exporter

Build a lightweight endpoint that exposes Odoo-specific metrics in Prometheus format:

from odoo import http
import time

class OdooMetrics(http.Controller):
    @http.route('/metrics', type='http', auth='none', csrf=False)
    def metrics(self, **kwargs):
        # Verify metrics access token
        token = http.request.httprequest.headers.get('Authorization')
        if token != f'Bearer {METRICS_TOKEN}':
            return http.request.make_response('Unauthorized', status=401)
        
        env = http.request.env
        lines = []
        
        # Active users
        active_sessions = env['ir.sessions'].sudo().search_count(
            [('last_activity', '>', time.strftime('%Y-%m-%d %H:%M:%S',
              time.localtime(time.time() - 900)))]
        )
        lines.append(f'odoo_active_users {active_sessions}')
        
        # CRM leads
        new_leads = env['crm.lead'].sudo().search_count(
            [('create_date', '>=', time.strftime('%Y-%m-%d'))]
        )
        lines.append(f'odoo_leads_today {new_leads}')
        
        # Sale orders
        orders_today = env['sale.order'].sudo().search_count(
            [('date_order', '>=', time.strftime('%Y-%m-%d')),
             ('state', 'in', ['sale', 'done'])]
        )
        lines.append(f'odoo_orders_today {orders_today}')
        
        # Cron jobs status
        stuck_crons = env['ir.cron'].sudo().search_count(
            [('active', '=', True), ('nextcall', '<',
              time.strftime('%Y-%m-%d %H:%M:%S',
              time.localtime(time.time() - 3600)))]
        )
        lines.append(f'odoo_stuck_crons {stuck_crons}')
        
        body = '\n'.join(lines) + '\n'
        resp = http.request.make_response(body)
        resp.headers['Content-Type'] = 'text/plain; version=0.0.4'
        return resp

Step 4: Configure Prometheus Scraping

# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']
  
  - job_name: 'postgresql'
    static_configs:
      - targets: ['localhost:9187']
  
  - job_name: 'odoo'
    bearer_token: 'your_metrics_token'
    static_configs:
      - targets: ['localhost:8069']
    metrics_path: '/metrics'
    scrape_interval: 30s

Step 5: Set Up Alerting

# alert_rules.yml
groups:
  - name: odoo
    rules:
      - alert: HighCPU
        expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "High CPU usage on Odoo server"
      
      - alert: DiskSpaceLow
        expr: node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} < 0.1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Disk space below 10% on Odoo server"
      
      - alert: PostgresConnectionsHigh
        expr: pg_stat_activity_count{datname="odoo"} > 80
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "PostgreSQL connections above 80 for Odoo database"
      
      - alert: StuckCronJobs
        expr: odoo_stuck_crons > 0
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Odoo has stuck cron jobs"

Key Metrics for Odoo

MetricSourceAlert Threshold
CPU usageNode Exporter> 85% for 5 min
Memory usageNode Exporter> 90%
Disk spaceNode Exporter< 10% free
DB connectionsPG Exporter> 80% of max
DB cache hit ratioPG Exporter< 95%
Stuck cron jobsOdoo Exporter> 0 for 10 min
Active usersOdoo ExporterInformational

DeployMonkey + Prometheus

DeployMonkey runs Prometheus monitoring for managed Odoo instances. Our AI agent can help you configure custom metrics, set up alerting rules, and build dashboards for your specific deployment.