Axelor Open Suite is a comprehensive open source ERP platform covering accounting, sales, purchasing, inventory, manufacturing, HR, CRM, and project management — all in a single Java application running on Apache Tomcat. For the SMEs and mid-market enterprises that rely on Axelor as their core business system, a failure in the ERP isn't a minor inconvenience: it stops invoicing, order processing, inventory management, and payroll in their tracks. Vigilmon gives you visibility into every critical Axelor layer, from Tomcat application health to Quartz batch jobs and PostgreSQL query latency.
What You'll Set Up
- Axelor application (Tomcat) health monitoring
- PostgreSQL database health and latency monitoring
- Axelor REST API response time monitoring
- Active user session monitoring
- Quartz scheduler heartbeat monitoring
- BPM (Camunda) workflow process health monitoring
- Disk space monitoring for ERP attachments
- JVM heap and GC health monitoring
- Module load health verification
- PostgreSQL backup success heartbeat
Prerequisites
- Axelor Open Suite deployed on Apache Tomcat (typically 9.x or 10.x)
- PostgreSQL as the database backend
- Access to the server (SSH) to deploy health check scripts
- A free Vigilmon account
Why Monitoring Axelor Is Critical
Axelor is the operational nervous system of the businesses that run it. Unlike a consumer web app where downtime means a bad user experience, Axelor downtime means:
- Accountants can't enter invoices or close periods — financial reporting halts.
- Sales staff can't create quotations or orders — revenue pipeline freezes.
- Warehouse workers can't move stock — inventory goes untracked.
- Quartz batch jobs fail silently — automated accounting closings, inventory valuations, and payroll calculations don't run.
- BPM workflows stall — approval processes (purchase orders, leave requests, expense claims) are blocked, with no notification to users.
Vigilmon monitors each of these failure modes with checks that go deeper than "is the server running."
Step 1: Monitor Axelor Application Health
Axelor runs as a Java web application on Tomcat. The first monitor should verify that Tomcat is accepting HTTP requests and the Axelor application has started correctly.
Axelor exposes a built-in login page at the root URL. Use it as the application health signal:
- Log in to vigilmon.online and click Add Monitor.
- Set Type to
HTTP / HTTPS. - Enter your Axelor URL:
https://erp.yourcompany.com/. - Set Expected HTTP status to
200. - Set Check interval to
1 minute. - Enable Response body contains and enter
Axelor(the login page title contains this string). - Click Save.
For deeper application health, Axelor versions 6.x+ expose a management endpoint. If your deployment has it enabled:
GET https://erp.yourcompany.com/ws/public/app/info
This returns application version, module list, and server metadata. Add a Vigilmon monitor for this endpoint and check that it returns HTTP 200 — a failure here indicates Axelor has not fully initialized.
Step 2: Monitor PostgreSQL Database Health
All Axelor ERP data lives in PostgreSQL. Create a shell script health check to expose database connectivity over HTTP using a minimal Python or Node.js server:
#!/bin/bash
# /usr/local/bin/axelor-db-health.sh
# Returns 0 if PostgreSQL is healthy, 1 if not
psql -U axelor -d axelor -c "SELECT 1" -q -t 2>/dev/null | grep -q 1
Wrap this in a simple health endpoint using a lightweight HTTP responder. Here's a Python approach you can run as a systemd service:
#!/usr/bin/env python3
# /usr/local/bin/axelor-health-server.py
import subprocess, json
from http.server import HTTPServer, BaseHTTPRequestHandler
class HealthHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/health/db':
result = subprocess.run(
['psql', '-U', 'axelor', '-d', 'axelor', '-c', 'SELECT 1', '-q', '-t'],
capture_output=True, timeout=5
)
healthy = result.returncode == 0
self.send_response(200 if healthy else 503)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({'db': 'ok' if healthy else 'error'}).encode())
else:
self.send_response(404)
self.end_headers()
def log_message(self, *args):
pass # suppress access logs
HTTPServer(('127.0.0.1', 9100), HealthHandler).serve_forever()
Run this as a systemd service on port 9100 (internal only), then expose specific paths via your nginx reverse proxy with IP restrictions. In Vigilmon:
- Add a monitor for
https://erp.yourcompany.com/health/db. - Set Expected HTTP status to
200. - Set Check interval to
1 minute.
Step 3: Monitor Axelor REST API Response Time
Axelor's REST/JSON-RPC API is the interface between the AngularJS frontend and the Java backend. All ERP operations — opening a sales order, searching for a contact, computing an invoice — go through this API. Slow API responses mean a slow ERP experience for every user.
Monitor a lightweight API endpoint that exercises the full request path:
- In Vigilmon, add an
HTTP / HTTPSmonitor. - URL:
https://erp.yourcompany.com/ws/public/app/info. - Set Check interval to
2 minutes. - Set Response time alert at
3000 ms(3 seconds) — p95 API response time above 3s indicates a JVM or database problem. - Set Expected HTTP status to
200.
For authenticated API checks (to test full ERP paths), use Vigilmon's Custom Headers feature to pass a valid API token, or create a read-only API user specifically for monitoring.
Step 4: Monitor Active User Sessions
Axelor's session capacity is limited by your Tomcat heap size and the server's CPU/memory. Monitoring active session count helps you detect unusual spikes (batch imports, a stuck process holding sessions open) before they cause OOM errors.
Extend the health server to query active sessions from PostgreSQL (Axelor stores session data in the database):
# Add to axelor-health-server.py
elif self.path == '/health/sessions':
result = subprocess.run(
['psql', '-U', 'axelor', '-d', 'axelor', '-t', '-c',
"SELECT COUNT(*) FROM auth_session WHERE expiry > NOW()"],
capture_output=True, timeout=5
)
count = int(result.stdout.strip()) if result.returncode == 0 else -1
# Alert if session count exceeds configured threshold
THRESHOLD = int(os.environ.get('SESSION_ALERT_THRESHOLD', '100'))
healthy = 0 <= count < THRESHOLD
self.send_response(200 if healthy else 503)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({'active_sessions': count}).encode())
Set SESSION_ALERT_THRESHOLD to your infrastructure's comfortable limit. In Vigilmon, add a monitor for /health/sessions and alert on non-200.
Step 5: Monitor Quartz Scheduler with Heartbeat Monitors
Axelor uses Quartz Scheduler for automated batch jobs: accounting period closings, inventory valuations, payroll calculations, and automated email sequences. A failed Quartz job causes silent business logic failures that may not surface for hours or days.
The most robust approach is to monitor each critical batch job with a Vigilmon heartbeat:
- In Vigilmon, click Add Monitor → Cron / Heartbeat.
- Name it
Axelor Accounting Batch. - Set Expected interval to match your job's schedule (e.g.,
24 hoursfor a nightly accounting close). - Copy the heartbeat URL.
Wrap your Quartz job to ping Vigilmon on successful completion. In Axelor's Groovy scripting or Java custom code:
// In your custom Quartz job class
@Override
protected void executeInContext(JobExecutionContext context, ActionRequest request, ActionResponse response) {
try {
// ... your batch job logic ...
pingVigilmon(System.getenv("VIGILMON_BATCH_TOKEN"));
} catch (Exception e) {
log.error("Axelor batch job failed", e);
throw e;
}
}
private void pingVigilmon(String token) {
if (token == null || token.isEmpty()) return;
try {
new URL("https://vigilmon.online/heartbeat/" + token).openConnection().getContent();
} catch (Exception ignored) {}
}
Create a separate heartbeat monitor for each critical Quartz job. If the job fails or Quartz stops running, no ping arrives and Vigilmon alerts you.
Step 6: Monitor BPM Workflow Health
Axelor BPM (powered by Camunda) enables approval workflows: purchase order approvals, leave request chains, expense authorizations. A stuck workflow can block employees from getting approvals they need to do their work.
# Add to axelor-health-server.py — requires psql access to axelor DB
elif self.path == '/health/bpm':
# Count workflow instances that haven't progressed in > 24 hours
result = subprocess.run(
['psql', '-U', 'axelor', '-d', 'axelor', '-t', '-c', """
SELECT COUNT(*) FROM wkf_instance
WHERE status = 'started'
AND updated_on < NOW() - INTERVAL '24 hours'
"""],
capture_output=True, timeout=5
)
stuck = int(result.stdout.strip()) if result.returncode == 0 else -1
healthy = stuck == 0
self.send_response(200 if healthy else 503)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({'bpm': 'ok' if healthy else 'degraded', 'stuck_processes': stuck}).encode())
In Vigilmon, add a monitor for /health/bpm with a 30-minute check interval. Alert when stuck processes appear — this indicates the BPM engine has crashed or a workflow is waiting for a resource that no longer exists.
Step 7: Monitor Disk Space for ERP Attachments
Axelor stores file attachments (invoices, contracts, documents, payslips) on disk. A full disk causes upload failures silently — users see an error, but the audit trail and document store are incomplete.
# Add to axelor-health-server.py
elif self.path == '/health/disk':
import shutil
attach_path = os.environ.get('AXELOR_ATTACHMENTS_PATH', '/opt/axelor/attachments')
usage = shutil.disk_usage(attach_path)
used_pct = round(usage.used / usage.total * 100, 1)
healthy = used_pct < 80
self.send_response(200 if healthy else 503)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({
'disk_used_pct': used_pct,
'free_gb': round(usage.free / 1024**3, 1)
}).encode())
Alert when disk usage exceeds 80% — this gives you time to archive old attachments or expand storage before upload failures begin.
Step 8: Monitor JVM Heap and GC Health
Axelor is a Java application, and JVM heap exhaustion causes erratic behavior (GC thrashing, OOM kills) before the application actually crashes. Monitor the JVM via JMX or via Tomcat's manager API:
Enable the Tomcat Manager application (restrict to localhost only):
<!-- conf/tomcat-users.xml -->
<role rolename="manager-jmx"/>
<user username="vigilmon" password="STRONG_RANDOM_PASSWORD" roles="manager-jmx"/>
# Add to axelor-health-server.py
elif self.path == '/health/jvm':
import urllib.request, base64
auth = base64.b64encode(b'vigilmon:STRONG_RANDOM_PASSWORD').decode()
try:
req = urllib.request.Request(
'http://localhost:8080/manager/jmxproxy/?get=java.lang:type=Memory&att=HeapMemoryUsage',
headers={'Authorization': f'Basic {auth}'}
)
data = urllib.request.urlopen(req, timeout=5).read().decode()
# Parse "used" value from JMX response
import re
used = int(re.search(r'used=(\d+)', data).group(1))
committed = int(re.search(r'committed=(\d+)', data).group(1))
heap_pct = round(used / committed * 100, 1)
healthy = heap_pct < 85
self.send_response(200 if healthy else 503)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({'heap_used_pct': heap_pct}).encode())
except Exception as e:
self.send_response(503)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({'jvm': 'error', 'message': str(e)}).encode())
Alert when JVM heap usage exceeds 85% — prolonged high heap usage precedes GC thrashing and OOM errors.
Step 9: Monitor PostgreSQL Backup Success
Axelor contains your organization's financial records, customer data, and operational history. A failed backup that goes unnoticed is a disaster risk. Set up a heartbeat monitor:
- In Vigilmon, create a Cron / Heartbeat monitor named
Axelor DB Backup. - Set Expected interval to
25 hours(slightly more than daily, to absorb slight timing drift). - Copy the heartbeat URL.
Add the ping to your backup script:
#!/bin/bash
# /usr/local/bin/axelor-backup.sh
BACKUP_DIR="/backups/axelor"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/axelor_$DATE.sql.gz"
mkdir -p "$BACKUP_DIR"
if pg_dump -U axelor axelor | gzip > "$BACKUP_FILE"; then
# Verify the backup is non-empty
if [ -s "$BACKUP_FILE" ]; then
curl -fsS "https://vigilmon.online/heartbeat/YOUR_HEARTBEAT_TOKEN" > /dev/null
# Rotate backups older than 7 days
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 -delete
fi
fi
Schedule with cron:
0 2 * * * root /usr/local/bin/axelor-backup.sh
Vigilmon alerts if no ping arrives within 25 hours, meaning your backup either failed or was never triggered.
Recommended Alert Configuration
| Monitor | Alert Condition | Severity |
|---|---|---|
| Axelor application health | Non-200 or body missing Axelor | Critical |
| PostgreSQL connectivity | Non-200 | Critical |
| REST API response time | p95 > 3s | High |
| Active session count | Approaching threshold | High |
| Quartz batch heartbeat | Missed interval | Critical |
| BPM stuck processes | > 0 stuck for 24h | High |
| Disk space (attachments) | > 80% used | High |
| JVM heap usage | > 85% | High |
| PostgreSQL backup heartbeat | Missed 25h interval | Critical |
Conclusion
Axelor is mission-critical ERP software — when it fails, entire business functions stop. Vigilmon gives you proactive monitoring across the full Axelor stack: application availability, database health, API performance, Quartz batch jobs, BPM workflows, and the backup infrastructure that protects your data. With these monitors in place, you know about problems before they become business emergencies.
Start monitoring your Axelor ERP at vigilmon.online.