tutorial

Monitoring Metasfresh ERP with Vigilmon

Metasfresh is a Java Spring Boot ERP with RabbitMQ, Elasticsearch, and a React WebUI — but a RabbitMQ failure silently halts EDI and printing, while an Elasticsearch lag breaks product search. Here's how to monitor every service with Vigilmon.

Metasfresh is a modern, open-source Java ERP built for mid-market manufacturing, wholesale, and distribution companies. Unlike legacy ERP monoliths, Metasfresh uses a microservices-inspired architecture: a Spring Boot app server, a React WebUI communicating via WebSocket and REST, RabbitMQ for async message passing (EDI, printing, report generation), Elasticsearch for full-text search, and PostgreSQL as the single source of truth for all financial and operational data. Each service is a potential failure point — and a RabbitMQ outage, for example, silently halts invoice printing while the app server appears healthy. Vigilmon monitors every layer continuously so you learn about failures before they affect your warehouse, accounting, or customers.

What You'll Set Up

  • HTTP uptime monitor for the Metasfresh app server (Spring Actuator)
  • HTTP uptime monitor for the Metasfresh WebUI
  • PostgreSQL connectivity and backup-age heartbeat
  • RabbitMQ connectivity heartbeat
  • Printing service health heartbeat
  • Elasticsearch cluster health monitor
  • JVM heap and GC monitoring
  • EDI processing heartbeat

Prerequisites

  • Metasfresh running via Docker Compose or Kubernetes (default app server port 8080, WebUI port 80 or 443)
  • A free Vigilmon account

Step 1: Monitor the Metasfresh App Server

Metasfresh's Spring Boot app server exposes a Spring Actuator health endpoint at /actuator/health. This endpoint aggregates the health of all Spring components and is the canonical health check for the Java backend.

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter: http://your-server-ip:8080/actuator/health.
  4. Set Expected HTTP status to 200.
  5. Enable Response body must contain and enter "status":"UP".
  6. Set Check interval to 1 minute.
  7. Click Save.

The /actuator/health endpoint returns a JSON body like:

{"status": "UP", "components": {"db": {"status": "UP"}, "diskSpace": {"status": "UP"}}}

The body assertion on "status":"UP" confirms the Spring Boot application is fully initialized and its internal health checks (database, disk space) are passing.

If Metasfresh is behind a reverse proxy or running in Docker with a different port mapping, adjust the URL accordingly:

http://your-server-ip:8080/actuator/health

Step 2: Monitor the Metasfresh WebUI

The Metasfresh WebUI is a React SPA served from a separate web server (Nginx inside Docker). Its failure blocks all ERP users from accessing any module — sales orders, purchasing, inventory, accounting — since the React frontend is the only user interface.

  1. In Vigilmon, click Add MonitorHTTP / HTTPS.
  2. Enter: http://your-server-ip:80 (or https://erp.yourdomain.com).
  3. Set Expected HTTP status to 200.
  4. Enable Response body must contain and enter </html>.
  5. Set Check interval to 1 minute.
  6. Click Save.

The body assertion distinguishes a healthy React SPA response from a proxy error page (which may also return 200 with an HTML error body).


Step 3: Monitor PostgreSQL

PostgreSQL is Metasfresh's exclusive data store for all ERP data: sales orders, purchase orders, invoices, inventory transactions, GL entries, manufacturing orders, and audit data. A PostgreSQL failure makes the entire ERP non-functional.

  1. In Vigilmon, click Add MonitorCron Heartbeat.
  2. Set the expected interval to 5 minutes.
  3. Copy the heartbeat URL.
#!/bin/bash
# /usr/local/bin/metasfresh-db-check.sh

DB_HOST="localhost"
DB_PORT="5432"
DB_NAME="metasfresh"
DB_USER="metasfresh"
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-db-heartbeat"

RESULT=$(psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" \
  -c "SELECT 1;" -t -A 2>/dev/null)

if [ "$RESULT" = "1" ]; then
    curl -s "$HEARTBEAT_URL"
else
    echo "ERROR: Metasfresh PostgreSQL connectivity check failed"
fi

Make executable and schedule every 5 minutes:

chmod +x /usr/local/bin/metasfresh-db-check.sh
crontab -e
# Add:
*/5 * * * * /usr/local/bin/metasfresh-db-check.sh

Step 4: Monitor Database Backup Age

Metasfresh stores critical financial data that must meet GoBD compliance requirements (German accounting law). A backup failure discovered during recovery is a catastrophic compliance event. Monitor backup age proactively:

  1. In Vigilmon, create a Cron Heartbeat with a 25 hour expected interval (giving 1 hour of buffer over a daily backup schedule).
  2. Copy the heartbeat URL.
#!/bin/bash
# /usr/local/bin/metasfresh-backup-check.sh

BACKUP_DIR="/var/backups/metasfresh"
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-backup-heartbeat"
MAX_AGE_HOURS=25

# Find the most recent backup file
LATEST_BACKUP=$(ls -t "$BACKUP_DIR"/*.sql.gz 2>/dev/null | head -1)

if [ -z "$LATEST_BACKUP" ]; then
    echo "ERROR: No backup files found in $BACKUP_DIR"
    exit 1
fi

BACKUP_EPOCH=$(stat -c %Y "$LATEST_BACKUP")
NOW_EPOCH=$(date +%s)
AGE_HOURS=$(( (NOW_EPOCH - BACKUP_EPOCH) / 3600 ))

if [ "$AGE_HOURS" -lt "$MAX_AGE_HOURS" ]; then
    curl -s "$HEARTBEAT_URL"
else
    echo "WARNING: Most recent backup is ${AGE_HOURS}h old (limit ${MAX_AGE_HOURS}h): $LATEST_BACKUP"
fi

Schedule at the time your backup is expected to complete daily (e.g., 6 AM):

0 6 * * * /usr/local/bin/metasfresh-backup-check.sh

Step 5: Monitor RabbitMQ

Metasfresh uses RabbitMQ for async message passing between the app server and async workers that handle: PDF document generation, EDI import/export processing, label printing, and report generation. A RabbitMQ failure causes all of these to queue up silently — the app server continues accepting requests but invoices stop printing, EDI messages stall, and reports stop generating.

TCP Port Check

  1. In Vigilmon, click Add MonitorTCP Port.
  2. Enter your RabbitMQ server hostname and port 5672.
  3. Set Check interval to 1 minute.
  4. Click Save.

RabbitMQ Management API Check

For a richer health check using the RabbitMQ management plugin (port 15672):

  1. In Vigilmon, click Add MonitorHTTP / HTTPS.
  2. Enter: http://your-server-ip:15672/api/healthchecks/node.
  3. Set Expected HTTP status to 200.
  4. Enable Response body must contain and enter "status":"ok".
  5. Set Check interval to 2 minutes.
  6. Click Save.

Queue Depth Heartbeat

Monitor queue depth to catch buildup before it becomes a backlog:

#!/bin/bash
# /usr/local/bin/metasfresh-rabbitmq-check.sh

RABBITMQ_HOST="localhost"
RABBITMQ_USER="guest"
RABBITMQ_PASS="guest"
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-rabbitmq-heartbeat"
MAX_MESSAGES=1000  # alert if any queue exceeds this

TOTAL=$(curl -s -u "$RABBITMQ_USER:$RABBITMQ_PASS" \
  "http://$RABBITMQ_HOST:15672/api/queues" 2>/dev/null \
  | python3 -c "
import json, sys
qs = json.load(sys.stdin)
total = sum(q.get('messages', 0) for q in qs)
print(total)
")

if [ -n "$TOTAL" ] && [ "$TOTAL" -le "$MAX_MESSAGES" ]; then
    curl -s "$HEARTBEAT_URL"
else
    echo "WARNING: RabbitMQ total queued messages: ${TOTAL:-unknown} (limit $MAX_MESSAGES)"
fi

Schedule every 5 minutes:

*/5 * * * * /usr/local/bin/metasfresh-rabbitmq-check.sh

Step 6: Monitor the Printing Service

Metasfresh's printing service generates PDF invoices, delivery notes, and labels. In a warehouse or distribution center, a failed printing service means operations staff cannot print picking lists or delivery documents — physical warehouse operations stop even though the ERP application appears healthy.

  1. In Vigilmon, create a Cron Heartbeat with a 10 minute expected interval.
  2. Copy the heartbeat URL.
#!/bin/bash
# /usr/local/bin/metasfresh-print-check.sh

PRINT_SERVICE_URL="http://localhost:8085/actuator/health"  # adjust port
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-print-heartbeat"

HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -m 10 \
  "$PRINT_SERVICE_URL" 2>/dev/null)

if [ "$HTTP_CODE" = "200" ]; then
    curl -s "$HEARTBEAT_URL"
else
    echo "WARNING: Metasfresh printing service returned HTTP $HTTP_CODE"
fi

Schedule every 10 minutes:

*/10 * * * * /usr/local/bin/metasfresh-print-check.sh

If the printing service uses Spring Boot actuator, you can check its specific health endpoint exactly as you do the main app server in Step 1.


Step 7: Monitor Elasticsearch

Metasfresh uses Elasticsearch for full-text search of products, business partners, and documents. An Elasticsearch outage means search returns no results, and users cannot find products or partners by name — severely degrading usability even though the ERP data remains intact in PostgreSQL.

  1. In Vigilmon, click Add MonitorHTTP / HTTPS.
  2. Enter: http://your-server-ip:9200/_cluster/health.
  3. Set Expected HTTP status to 200.
  4. Enable Response body must contain and enter "status":"green" (or "status":"yellow" if a yellow cluster is acceptable in your setup).
  5. Set Check interval to 2 minutes.
  6. Click Save.

The /_cluster/health endpoint returns cluster status including active shards, relocating shards, and unassigned shards:

{
  "cluster_name": "metasfresh",
  "status": "green",
  "number_of_nodes": 1,
  "active_shards": 10
}

A red status means primary shards are unavailable and search operations are failing. A yellow status means replicas are missing but primary shards are available — monitoring is still returning results but redundancy is gone.

For index sync lag monitoring:

#!/bin/bash
# /usr/local/bin/metasfresh-es-check.sh

ES_URL="http://localhost:9200"
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-es-heartbeat"

STATUS=$(curl -s -m 10 "$ES_URL/_cluster/health" 2>/dev/null \
  | python3 -c "import json,sys; print(json.load(sys.stdin).get('status','red'))")

if [ "$STATUS" = "green" ] || [ "$STATUS" = "yellow" ]; then
    curl -s "$HEARTBEAT_URL"
else
    echo "WARNING: Elasticsearch cluster status: $STATUS"
fi

Schedule every 5 minutes:

*/5 * * * * /usr/local/bin/metasfresh-es-check.sh

Step 8: Monitor JVM Heap Health

Metasfresh's Spring Boot app server is a Java process with significant heap requirements — processing large manufacturing orders, EDI files, or report generation can spike heap usage. Heap pressure causes GC pauses that freeze request processing before an OutOfMemoryError crash occurs.

The Spring Actuator /actuator/metrics endpoint exposes JVM heap metrics:

#!/bin/bash
# /usr/local/bin/metasfresh-jvm-check.sh

APP_URL="http://localhost:8080"
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-jvm-heartbeat"
HEAP_THRESHOLD=85  # percent

HEAP_USED=$(curl -s -m 10 \
  "$APP_URL/actuator/metrics/jvm.memory.used?tag=area:heap" 2>/dev/null \
  | python3 -c "import json,sys; print(json.load(sys.stdin)['measurements'][0]['value'])")

HEAP_MAX=$(curl -s -m 10 \
  "$APP_URL/actuator/metrics/jvm.memory.max?tag=area:heap" 2>/dev/null \
  | python3 -c "import json,sys; print(json.load(sys.stdin)['measurements'][0]['value'])")

if [ -n "$HEAP_USED" ] && [ -n "$HEAP_MAX" ]; then
    HEAP_PCT=$(python3 -c "print(int(($HEAP_USED / $HEAP_MAX) * 100))")
    if [ "$HEAP_PCT" -lt "$HEAP_THRESHOLD" ]; then
        curl -s "$HEARTBEAT_URL"
    else
        echo "WARNING: JVM heap at ${HEAP_PCT}% (threshold ${HEAP_THRESHOLD}%)"
    fi
else
    echo "ERROR: Could not read JVM heap metrics from actuator"
fi

Schedule every 5 minutes:

*/5 * * * * /usr/local/bin/metasfresh-jvm-check.sh

Step 9: Monitor EDI Processing

If your Metasfresh deployment uses EDI (Electronic Data Interchange) for supplier orders, invoices, or shipping confirmations, EDI processing failures have direct supply chain consequences: orders to suppliers are not sent, incoming invoices are not processed, and receiving confirmations are not acknowledged.

  1. In Vigilmon, create a Cron Heartbeat — set the expected interval to match your EDI schedule (e.g., 4 hours for typical EDI batch cycles).
  2. Copy the heartbeat URL.
#!/bin/bash
# /usr/local/bin/metasfresh-edi-check.sh

DB_HOST="localhost"
DB_USER="metasfresh"
DB_NAME="metasfresh"
HEARTBEAT_URL="https://vigilmon.online/heartbeat/your-edi-heartbeat"
MAX_HOURS=5  # EDI expected every 4 hours; allow 5h before alert

# Check last successful EDI import run
LAST_SUCCESS=$(psql -h "$DB_HOST" -U "$DB_USER" -d "$DB_NAME" -t -A -c "
  SELECT MAX(Updated)
  FROM EDI_Document
  WHERE Status = 'Completed'
    AND Updated > NOW() - INTERVAL '${MAX_HOURS} hours';
" 2>/dev/null)

if [ -n "$LAST_SUCCESS" ] && [ "$LAST_SUCCESS" != "" ]; then
    curl -s "$HEARTBEAT_URL"
else
    echo "WARNING: No successful EDI processing in the last ${MAX_HOURS} hours"
fi

Schedule every 30 minutes:

*/30 * * * * /usr/local/bin/metasfresh-edi-check.sh

Step 10: Configure Alert Channels

  1. Go to Alert Channels in Vigilmon and add Slack, email, or a webhook.
  2. Set Consecutive failures before alert to 2 on the app server and WebUI monitors — a brief Spring Boot restart during a rolling deployment takes 30–60 seconds.
  3. Set Consecutive failures before alert to 1 on PostgreSQL, RabbitMQ, and backup age monitors — these are immediately critical.

Route monitors to urgency channels:

  • App server down, PostgreSQL failure, RabbitMQ failure → Slack #erp-critical (immediate, wake on-call)
  • Printing service failure, Elasticsearch red → Slack #erp-ops (urgent within 30 minutes — operations impact)
  • JVM heap > 85%, EDI failure, backup age > 25h → email (investigate before next business day)

Summary

| Monitor | Target | What It Catches | |---|---|---| | App server | /actuator/health + "status":"UP" | Spring Boot crash | | WebUI | GET / + </html> | React frontend unavailable | | PostgreSQL heartbeat | SELECT 1 every 5 min | Database connectivity loss | | Backup age | Backup file age every 25h | Missing daily backup (GoBD risk) | | RabbitMQ TCP | Port 5672 every 1 min | Async processing halted | | RabbitMQ queue depth | Management API every 5 min | EDI/printing backlog building | | Printing service | Actuator health every 10 min | Invoices/labels not generating | | Elasticsearch | /_cluster/health every 2 min | Search returning no results | | JVM heap | Actuator metrics every 5 min | Memory pressure before OOM | | EDI heartbeat | DB query every 30 min | Supply chain EDI failure |

Metasfresh's microservices architecture means each service can fail independently while the rest appears healthy. Vigilmon watches every service in parallel — app server, WebUI, PostgreSQL, RabbitMQ, printing, Elasticsearch — so you know within minutes when any piece of the stack needs attention.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →