tutorial

Monitoring Shaarli with Vigilmon

Shaarli is your self-hosted Pinboard — but its flat-file architecture and PHP stack have unique failure modes that standard uptime checks miss. Here's how to monitor Shaarli's web server, PHP-FPM, datastore integrity, search index, RSS feeds, and API with Vigilmon.

Shaarli is an open source self-hosted bookmark manager and link collection tool — a personal alternative to Delicious or Pinboard. It runs as a PHP application served through nginx or Apache (port 80/443), and unlike database-backed applications, it stores all bookmarks in a flat-file JSON datastore at data/datastore.php. That flat-file design makes Shaarli easy to deploy and backup, but it also introduces unique failure modes: file permission errors, corrupted JSON, and full-text search index drift can all make Shaarli unusable while the web server reports 200 OK. Vigilmon lets you monitor every layer of Shaarli, from PHP-FPM processes to the API endpoint.

What You'll Set Up

  • Web server availability monitor for the main Shaarli interface
  • PHP-FPM process health monitoring
  • Datastore file integrity and write-access verification
  • RSS/Atom feed generation endpoint health
  • Full-text search health via the search index
  • HTTPS/TLS certificate expiry alerts
  • API v1 endpoint response time monitoring (/api/v1/links)
  • Thumbnail generation service health

Prerequisites

  • Shaarli installed and accessible at https://links.yourdomain.com (or port 80)
  • nginx or Apache configured as the web server
  • PHP-FPM running as the FastCGI process manager
  • A free Vigilmon account

Step 1: Monitor Web Server Availability

The most basic check is whether Shaarli's main page is loading. This catches nginx crashes, PHP-FPM failures, and configuration errors.

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter your Shaarli URL: https://links.yourdomain.com.
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Under Content verification, enter Shaarli or your site's custom title to confirm the page rendered correctly.
  7. Click Save.

To also verify the login page is accessible (important if you run Shaarli in private mode):

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://links.yourdomain.com/?do=login.
  3. Expected status: 200.
  4. Content verification: password or Login (confirms the login form is present).

Step 2: Monitor PHP-FPM Health

PHP-FPM is the FastCGI Process Manager that executes all PHP code for Shaarli. If PHP-FPM stops responding, nginx returns 502 Bad Gateway errors — Shaarli appears down even though the web server itself is running.

PHP-FPM exposes a status endpoint when configured. Enable it in your PHP-FPM pool configuration:

; /etc/php/8.x/fpm/pool.d/www.conf
pm.status_path = /fpm-status

Then expose it through nginx (restrict to localhost or internal IPs):

location /fpm-status {
    access_log off;
    allow 127.0.0.1;
    deny all;
    fastcgi_pass unix:/run/php/php8.x-fpm.sock;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Reload PHP-FPM and nginx:

systemctl reload php8.x-fpm
systemctl reload nginx

Add a Vigilmon HTTP monitor:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: http://localhost/fpm-status (or via SSH tunnel if monitoring externally).
  3. Expected status: 200.
  4. Content verification: pool: or accepted conn: (confirms FPM status output).
  5. Set Check interval to 1 minute.

Step 3: Verify Datastore File Integrity

Shaarli's entire bookmark database lives in data/datastore.php. A corrupted or unreadable datastore makes Shaarli throw PHP errors or serve empty results while appearing to be running. Standard HTTP monitors won't catch this.

Create a health check script that validates the datastore:

#!/bin/bash
# /opt/shaarli/scripts/datastore-health.sh
DATASTORE="/var/www/shaarli/data/datastore.php"

# Check file exists and is readable
if [ ! -r "$DATASTORE" ]; then
  echo "error: datastore not readable"
  exit 1
fi

# Check file size is non-zero
if [ ! -s "$DATASTORE" ]; then
  echo "error: datastore empty"
  exit 1
fi

# Check PHP syntax is valid
php -l "$DATASTORE" > /dev/null 2>&1
if [ $? -ne 0 ]; then
  echo "error: datastore has invalid PHP syntax"
  exit 1
fi

# Check write permissions (Shaarli needs to write back to the datastore)
if [ ! -w "$DATASTORE" ]; then
  echo "error: datastore not writable"
  exit 1
fi

echo "ok"

Serve this via a minimal HTTP server bound to localhost and add a Vigilmon monitor:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: http://localhost:9090/datastore-health.
  3. Expected status: 200.
  4. Content verification: ok.
  5. Set Check interval to 5 minutes.

Step 4: Monitor RSS/Atom Feed Generation

Shaarli generates RSS and Atom feeds at ?do=rss and ?do=atom respectively. These feeds are often consumed by external readers and aggregators — a broken feed is a silent failure that breaks other people's workflows.

RSS feed:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://links.yourdomain.com/?do=rss.
  3. Expected status: 200.
  4. Content verification: <rss or <channel> (confirms valid RSS XML is returned).
  5. Set Check interval to 5 minutes.

Atom feed:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://links.yourdomain.com/?do=atom.
  3. Expected status: 200.
  4. Content verification: <feed or <entry> (confirms valid Atom XML is returned).

A broken feed endpoint while the main page returns 200 often signals a PHP exception in the feed generation code — usually triggered by a datastore parsing error or memory limit hit.


Step 5: Monitor Full-Text Search Health

Shaarli builds an in-memory search index from the datastore on each request (or caches it, depending on configuration). If the datastore grows large or search queries start timing out, the user-facing search box becomes unusable.

Test the search endpoint directly:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://links.yourdomain.com/?searchtags=test (or ?searchterm=monitor).
  3. Expected status: 200.
  4. Set Response time threshold to 3000ms — search queries that take more than 3 seconds indicate index regeneration is struggling with a large datastore.
  5. Content verification: links or results (confirms the search results page structure).

If search performance degrades over time (response times creeping up), it's a signal that your datastore has grown too large for in-memory index rebuilding and you may need to archive old links or migrate to a database-backed alternative.


Step 6: Monitor HTTPS/TLS Certificate Expiry

Shaarli is typically served over HTTPS via Let's Encrypt through nginx or Caddy. A lapsed certificate immediately makes Shaarli inaccessible to all users.

  1. Open the main Shaarli HTTP monitor (from Step 1).
  2. Enable Monitor SSL certificate.
  3. Set Alert when certificate expires in less than 21 days.
  4. Save.

If Shaarli is behind Cloudflare or another proxy that terminates TLS, the certificate visible to Vigilmon is the proxy's certificate. In that case, also monitor the origin server's certificate separately if it uses TLS between the proxy and origin.

Verify Let's Encrypt auto-renewal is healthy:

# Check when the certificate was last renewed
certbot certificates
# Should show Expiry Date several weeks away

# Test renewal dry-run
certbot renew --dry-run

Step 7: Monitor API v1 Endpoint Response Times

Shaarli's REST API v1 exposes bookmark operations at /api/v1/links. Apps and scripts that integrate with Shaarli use this endpoint, and slow API responses often precede outages.

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://links.yourdomain.com/api/v1/links.
  3. Add header: Authorization: Bearer your-api-token.
  4. Expected status: 200.
  5. Set Response time threshold to 2000ms.
  6. Set Check interval to 3 minutes.

To find or generate your API token, run:

# In your Shaarli directory
grep "api.secret" data/config.php

The API token is derived from the Shaarli secret. Use a read-only API call (GET /api/v1/links) for the health probe to avoid side effects.


Step 8: Monitor the Thumbnail Plugin

Shaarli's Thumbnailer plugin generates link preview thumbnails using an external service or local processing. A broken thumbnail service degrades the visual browsing experience, and if the plugin is synchronous, it can slow down bookmark saves.

If you use an external thumbnail API:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: the external thumbnail service endpoint (e.g. https://thumbnail.ws/api/abc123/thumbnail/get?url=https://example.com).
  3. Expected status: 200.
  4. Set Check interval to 10 minutes.

If thumbnailing is handled locally via a configured plugin, monitor the plugin indirectly by checking that a bookmark save returns in under your threshold. Slow saves with valid data are the primary signal of a blocking thumbnail call.


Summary

| Monitor | Target | What It Catches | |---|---|---| | Web server | https://links.yourdomain.com | nginx crash, total unavailability | | Login page | /?do=login | PHP-FPM connection broken | | PHP-FPM status | localhost/fpm-status | FPM pool exhausted or crashed | | Datastore integrity | Script probe | Corrupted or unreadable datastore | | RSS feed | /?do=rss | Feed generation exception | | Atom feed | /?do=atom | Feed encoding or parsing error | | Search endpoint | /?searchtags=test | Search index degradation | | TLS certificate | HTTPS monitor | Certificate expired | | API v1 | GET /api/v1/links | API auth or routing broken | | Thumbnail service | External thumbnail URL | Thumbnail plugin failures |

Shaarli's flat-file simplicity makes it easy to run but easy to lose visibility into — its architecture means a misconfigured file permission or a corrupted datastore line silently breaks features while the web server stays up. With Vigilmon monitoring everything from PHP-FPM health to feed generation and API response times, you get a complete picture of your Shaarli instance's health without touching a single line of Shaarli's source code.

Monitor your app with Vigilmon

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

Start free →