tutorial

Monitoring Apache Marmotta with Vigilmon

Apache Marmotta's Linked Data server exposes RDF triple stores, SPARQL endpoints, and LDP containers — when the triplestore backend stalls, SPARQL queries time out, or LDP resource creation fails, semantic web applications silently receive empty graphs. Here's how to monitor Apache Marmotta availability, SPARQL endpoint health, and triplestore performance with Vigilmon.

Apache Marmotta is an open platform for Linked Data — it provides a SPARQL 1.1 endpoint, an LDP (Linked Data Platform) server, a versioning backend, and a set of semantic web services built on top of a pluggable RDF triplestore (KiWi, backed by PostgreSQL or MySQL by default). Marmotta is used in semantic web applications, government open data portals, knowledge graph publishing workflows, and any system that needs to expose or consume RDF data over standard protocols. When Marmotta's database backend becomes unavailable, the SPARQL endpoint starts timing out, or the LDP container service encounters an error, the platform continues accepting HTTP requests while returning empty or malformed RDF graphs — breaking every semantic application that depends on it. Vigilmon provides external monitoring for Marmotta's HTTP API, SPARQL endpoint availability, LDP server health, and backend database connectivity so you detect service degradation before your Linked Data applications receive corrupted graph data.

What You'll Set Up

  • Marmotta HTTP API availability monitoring
  • SPARQL 1.1 endpoint health and query execution
  • LDP server availability and resource creation
  • Backend database connectivity monitoring
  • SPARQL query latency tracking

Prerequisites

  • Apache Marmotta 3.x running with the web application
  • Marmotta accessible at a known URL (e.g., http://marmotta.internal:8080/marmotta)
  • A PostgreSQL or MySQL backend configured and accessible
  • A free Vigilmon account

Step 1: Monitor the Marmotta HTTP API

Marmotta's root context and the configuration API provide immediate availability signals. When the web application fails to deploy, the backing database is unreachable during startup, or the KiWi triplestore initialization fails, the HTTP server returns errors or stops responding entirely. Set up a basic availability monitor:

  1. In Vigilmon, click Add MonitorHTTP/HTTPS.
  2. Set the URL to http://marmotta.internal:8080/marmotta/config/list.
  3. Set Check interval to 1 minute.
  4. Under Expected response, add keyword marmotta — the configuration list always includes internal Marmotta property names in a healthy response.
  5. Set Timeout to 15 seconds.

For a broader API health check including the core module status:

# Verify Marmotta's core API is responding
MARMOTTA_URL="http://marmotta.internal:8080/marmotta"

API_RESPONSE=$(curl -sf --max-time 15 \
  -H "Accept: application/json" \
  "${MARMOTTA_URL}/config/list" 2>/dev/null)

if echo "$API_RESPONSE" | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    # Marmotta config list returns key-value pairs
    sys.exit(0 if isinstance(data, dict) and len(data) > 0 else 1)
except:
    sys.exit(1)
" 2>/dev/null; then
  echo "Marmotta configuration API healthy"
  curl -s "https://vigilmon.online/heartbeat/REPLACE_WITH_YOUR_TOKEN"
else
  echo "Marmotta configuration API not responding or returning invalid data"
  exit 1
fi

Step 2: Monitor the SPARQL Endpoint

Marmotta's SPARQL 1.1 endpoint is the primary query interface for semantic applications. A healthy SPARQL endpoint executes SELECT queries within milliseconds for simple pattern matches against a well-indexed triplestore. When the KiWi backend database connection pool is exhausted, a long-running SPARQL query is holding locks, or the triplestore index becomes corrupted, queries either timeout or return incorrect result sets. Set up a synthetic SPARQL health check:

  1. In Vigilmon, click Add MonitorCron Heartbeat.
  2. Set Expected ping interval to 5 minutes.
  3. Copy the heartbeat URL (e.g., https://vigilmon.online/heartbeat/abc123).

Create the SPARQL availability check:

#!/bin/bash
# /usr/local/bin/marmotta-sparql-check.sh

HEARTBEAT_URL="https://vigilmon.online/heartbeat/abc123"
MARMOTTA_URL="http://marmotta.internal:8080/marmotta"
TIMEOUT=30

# Execute a minimal ASK query — always returns true/false, never null
# Uses Marmotta's SPARQL SELECT endpoint
SPARQL_QUERY="SELECT (COUNT(*) AS ?count) WHERE { ?s ?p ?o } LIMIT 1"

SPARQL_RESPONSE=$(curl -sf \
  --max-time "$TIMEOUT" \
  -G \
  --data-urlencode "query=${SPARQL_QUERY}" \
  -H "Accept: application/sparql-results+json" \
  "${MARMOTTA_URL}/sparql/select" 2>/dev/null)

if echo "$SPARQL_RESPONSE" | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    results = data.get('results', {}).get('bindings', [])
    # A valid SPARQL result always has at least one binding row (even if count is 0)
    sys.exit(0 if len(results) >= 0 else 1)
except:
    sys.exit(1)
" 2>/dev/null; then
  echo "Marmotta SPARQL endpoint healthy"
  curl -s "$HEARTBEAT_URL"
else
  echo "Marmotta SPARQL endpoint not returning valid SPARQL results"
  exit 1
fi

Install the cron job:

chmod +x /usr/local/bin/marmotta-sparql-check.sh
(crontab -l 2>/dev/null; echo "*/5 * * * * /usr/local/bin/marmotta-sparql-check.sh >> /var/log/marmotta-health.log 2>&1") | crontab -

A COUNT query over the triplestore that fails to return any result (as opposed to returning count=0) is a reliable indicator that the KiWi backend database connection has failed.


Step 3: Monitor LDP Server Availability

Marmotta's LDP (Linked Data Platform) implementation provides HTTP-based read/write access to RDF resources and containers. LDP is used by applications that create, update, and manage RDF resources over REST. When LDP is unavailable — due to a write lock contention in the database, a failed transaction rollback, or a missing LDP container — applications cannot create or update resources. Monitor the LDP server:

#!/bin/bash
# /usr/local/bin/marmotta-ldp-check.sh

HEARTBEAT_URL="https://vigilmon.online/heartbeat/def456"
MARMOTTA_URL="http://marmotta.internal:8080/marmotta"
TIMEOUT=20

# Check LDP root container availability via OPTIONS request
# OPTIONS should always succeed on the root LDP container
LDP_OPTIONS=$(curl -sf \
  --max-time "$TIMEOUT" \
  -X OPTIONS \
  -H "Accept: text/turtle" \
  -w "\n%{http_code}" \
  "${MARMOTTA_URL}/ldp" 2>/dev/null)

HTTP_CODE=$(echo "$LDP_OPTIONS" | tail -1)

if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "204" ]; then
  echo "Marmotta LDP server available: HTTP ${HTTP_CODE}"
  curl -s "$HEARTBEAT_URL"
else
  echo "Marmotta LDP server unavailable: HTTP ${HTTP_CODE:-timeout}"
  exit 1
fi

For a more thorough LDP check that verifies read access to the root container:

#!/bin/bash
# Full LDP read check
MARMOTTA_URL="http://marmotta.internal:8080/marmotta"
TIMEOUT=20

LDP_RESPONSE=$(curl -sf \
  --max-time "$TIMEOUT" \
  -H "Accept: text/turtle" \
  "${MARMOTTA_URL}/ldp" 2>/dev/null)

# The LDP root container should return Turtle-encoded RDF
if echo "$LDP_RESPONSE" | grep -q "@prefix\|<http://"; then
  echo "Marmotta LDP root container returning valid RDF"
  curl -s "$HEARTBEAT_URL"
else
  echo "Marmotta LDP root container returning invalid or empty response"
  exit 1
fi

Set the Vigilmon heartbeat to 5 minutes.


Step 4: Monitor Backend Database Connectivity

Marmotta's KiWi triplestore depends entirely on its relational database backend (PostgreSQL or MySQL). When the database server becomes unavailable, connection pool connections time out, or the KiWi schema migration is in an inconsistent state, Marmotta stops being able to read or write triples — which manifests as SPARQL queries returning empty results rather than explicit errors. Monitor database connectivity directly from the Marmotta host:

#!/bin/bash
# /usr/local/bin/marmotta-db-check.sh

HEARTBEAT_URL="https://vigilmon.online/heartbeat/ghi789"
DB_HOST="postgres.internal"
DB_PORT="5432"
DB_NAME="marmotta"
DB_USER="marmotta"
DB_PASS="REPLACE_WITH_DB_PASSWORD"
TIMEOUT=10

# Test database connectivity with a lightweight query
DB_RESULT=$(PGPASSWORD="$DB_PASS" psql \
  -h "$DB_HOST" \
  -p "$DB_PORT" \
  -U "$DB_USER" \
  -d "$DB_NAME" \
  -t \
  --command="SELECT COUNT(*) FROM nodes LIMIT 1;" \
  --connect-timeout="$TIMEOUT" 2>/dev/null)

if [ $? -eq 0 ] && [ -n "$DB_RESULT" ]; then
  NODE_COUNT=$(echo "$DB_RESULT" | tr -d ' ')
  echo "Marmotta KiWi database healthy: ${NODE_COUNT} nodes"
  curl -s "$HEARTBEAT_URL"
else
  echo "Marmotta KiWi database unavailable or query failed"
  exit 1
fi

For MySQL backends:

#!/bin/bash
# MySQL variant
DB_HOST="mysql.internal"
DB_PORT="3306"
DB_NAME="marmotta"
DB_USER="marmotta"
DB_PASS="REPLACE_WITH_DB_PASSWORD"

DB_RESULT=$(mysql \
  -h "$DB_HOST" \
  -P "$DB_PORT" \
  -u "$DB_USER" \
  -p"$DB_PASS" \
  -D "$DB_NAME" \
  --connect-timeout=10 \
  -e "SELECT COUNT(*) FROM nodes LIMIT 1;" \
  --skip-column-names 2>/dev/null)

if [ $? -eq 0 ] && [ -n "$DB_RESULT" ]; then
  echo "Marmotta KiWi MySQL database healthy: ${DB_RESULT} nodes"
  curl -s "$HEARTBEAT_URL"
else
  echo "Marmotta KiWi MySQL database unavailable"
  exit 1
fi

Set the Vigilmon heartbeat to 5 minutes. Database connectivity loss is the most common cause of Marmotta-serving empty SPARQL results silently.


Step 5: Monitor SPARQL Query Latency

Marmotta's SPARQL query performance depends on KiWi's B-tree indexes over the RDF store, the PostgreSQL/MySQL query planner, and the size of the triplestore. For small to medium triple stores (under 10M triples), simple property-path queries should return in well under 2 seconds. Performance degradation often appears as gradual latency increases before becoming complete timeouts, giving you a window to investigate before service impact. Monitor SPARQL latency:

#!/bin/bash
# /usr/local/bin/marmotta-sparql-latency-check.sh

HEARTBEAT_URL="https://vigilmon.online/heartbeat/jkl012"
MARMOTTA_URL="http://marmotta.internal:8080/marmotta"
MAX_LATENCY_SECONDS=5
TIMEOUT=30

# A bounded SPARQL query that should always be fast regardless of store size
SPARQL_QUERY="SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 10"

START_TIME=$(date +%s%3N)

RESPONSE=$(curl -sf \
  --max-time "$TIMEOUT" \
  -G \
  --data-urlencode "query=${SPARQL_QUERY}" \
  -H "Accept: application/sparql-results+json" \
  "${MARMOTTA_URL}/sparql/select" 2>/dev/null)

END_TIME=$(date +%s%3N)
LATENCY_MS=$(( END_TIME - START_TIME ))
LATENCY_S=$(( LATENCY_MS / 1000 ))

if [ -z "$RESPONSE" ]; then
  echo "Marmotta SPARQL query timed out after ${LATENCY_MS}ms"
  exit 1
fi

VALID=$(echo "$RESPONSE" | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    sys.exit(0 if 'results' in data else 1)
except:
    sys.exit(1)
" 2>/dev/null; echo $?)

if [ "$VALID" = "0" ] && [ "$LATENCY_S" -le "$MAX_LATENCY_SECONDS" ]; then
  echo "Marmotta SPARQL latency OK: ${LATENCY_MS}ms"
  curl -s "$HEARTBEAT_URL"
elif [ "$LATENCY_S" -gt "$MAX_LATENCY_SECONDS" ]; then
  echo "Marmotta SPARQL slow: ${LATENCY_MS}ms (threshold: ${MAX_LATENCY_SECONDS}s)"
  exit 1
else
  echo "Marmotta SPARQL returned invalid JSON after ${LATENCY_MS}ms"
  exit 1
fi

Run this every 5 minutes. A LIMIT 10 query taking over 5 seconds indicates either database index degradation or connection pool saturation — check PostgreSQL's pg_stat_activity for long-running queries blocking the KiWi connection pool.


Step 6: Set Up Alert Channels

Configure Vigilmon to route Marmotta alerts to the right teams:

  1. Go to Alert Channels in Vigilmon.
  2. Add a Slack webhook to #linked-data-ops — Marmotta failures affect all semantic web applications and RDF consumers.
  3. Add PagerDuty for the HTTP availability and database connectivity monitors — these cause complete SPARQL endpoint failure.
  4. Add email for the SPARQL latency monitor — gradual performance degradation is worth investigating before it becomes a hard failure.
  5. Set Consecutive failures before alert to 2 for the LDP monitor — LDP operations occasionally fail transiently during KiWi transaction commits.

Include SPARQL endpoint context in alerts:

TRIPLE_COUNT=$(PGPASSWORD="$DB_PASS" psql -h "$DB_HOST" -U "$DB_USER" -d "$DB_NAME" \
  -t --command="SELECT COUNT(*) FROM triples;" 2>/dev/null | tr -d ' ')

ALERT_MSG=":red_circle: Apache Marmotta SPARQL endpoint is unresponsive. Triple store contains ${TRIPLE_COUNT:-unknown} triples. Check: ${MARMOTTA_URL}/sparql/select"

curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \
  -H 'Content-type: application/json' \
  --data "{\"text\": \"$ALERT_MSG\", \"channel\": \"#linked-data-ops\"}"

Add a maintenance window during Marmotta upgrades or triplestore re-indexing:

curl -X POST https://vigilmon.online/api/maintenance \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "monitor_id": "MARMOTTA_HTTP_MONITOR_ID",
    "duration_minutes": 30,
    "reason": "Marmotta triplestore re-indexing — SPARQL unavailable during operation"
  }'

# Run the re-index operation
curl -X POST "${MARMOTTA_URL}/admin/solr/reindex" \
  -u "admin:${ADMIN_PASS}"

Summary

| Monitor | Target | What It Catches | |---|---|---| | HTTP monitor (API) | /config/list keyword check | Web app crash, database startup failure, port unavailable | | Cron heartbeat (SPARQL) | COUNT query result validity | KiWi backend failure, connection pool exhaustion, empty results | | Cron heartbeat (LDP) | Root container HTTP 200/204 | LDP write lock, transaction failure, container not found | | Cron heartbeat (database) | KiWi nodes table row count | PostgreSQL/MySQL down, connection refused, schema broken | | Cron heartbeat (latency) | SPARQL LIMIT 10 round-trip time | Index degradation, long-running query blocking pool |

Apache Marmotta's most dangerous failure mode is returning empty RDF graphs to SPARQL queries — a pattern that mimics an empty triplestore rather than a server error, causing semantic applications to silently operate on missing data. Vigilmon gives you external visibility into every layer of the Marmotta stack — from the HTTP API to the relational database backend — so you catch failures before your Linked Data applications start producing incorrect outputs based on empty graphs.

Start monitoring for free at vigilmon.online.

Monitor your app with Vigilmon

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

Start free →