tutorial

Monitoring OpenVSX with Vigilmon

OpenVSX is the open-source VS Code extension registry — but extension publish failures, download throughput drops, API latency spikes, namespace validation gaps, and upstream sync delays silently degrade your extension registry. Here's how to monitor OpenVSX publish throughput, registry API latency, namespace health, and upstream sync status with Vigilmon.

OpenVSX is the open-source alternative to the Visual Studio Marketplace, used by VS Code forks like VSCodium, Code-OSS, Eclipse Theia, and Gitpod to serve extensions without dependency on Microsoft's proprietary marketplace. It exposes a REST API for extension publishing, searching, and downloading, a namespace system for publisher identity management, and an upstream sync mechanism that mirrors extensions from the VS Code Marketplace. When extension publish requests fail because namespace validation is misconfigured, when download throughput drops because your object storage backend is throttled, when the API latency spikes because a search index rebuild is running, or when upstream sync stalls and your registry falls behind the Marketplace by days, developers working in your environment get stale or missing extensions — silent degradation that looks like "the extension doesn't exist" rather than "the registry is having problems." Vigilmon gives you external monitoring for OpenVSX API availability, extension publish throughput, download performance, namespace validation health, and upstream sync status so you catch registry problems before developers notice missing extensions.

What You'll Set Up

  • OpenVSX API health via HTTP monitors
  • Extension publish throughput monitoring
  • Download endpoint performance tracking
  • Namespace validation health
  • Upstream sync status alerting

Prerequisites

  • OpenVSX self-hosted deployment or access to an OpenVSX instance (e.g., open-vsx.org for the public registry)
  • Admin access to your OpenVSX deployment for publishing test extensions
  • A free Vigilmon account

Step 1: Monitor OpenVSX API Availability

OpenVSX exposes a REST API at /api/ that powers everything — extension search, version listing, publish, download. When the API goes down, all extension operations fail. Extension installs during IDE startup fail silently (the IDE falls back to cached versions), so users don't see obvious errors — they just don't get updates, and new extension installs fail with "not found."

Set up an HTTP monitor for the OpenVSX API health endpoint:

  1. In Vigilmon, click Add MonitorHTTP / HTTPS.
  2. Enter your OpenVSX URL: https://your-openvsx-instance.example.com/api/.
  3. Set check interval to 1 minute.
  4. Set alert after 2 failures.
  5. Add a Keyword check for "namespaces" or "extensions" — a valid API response contains these fields.

For the public registry or a self-hosted instance that doesn't have a dedicated /health endpoint, the namespace listing API (GET /api/) is a reliable liveness probe. It's lightweight and returns quickly unless the database or storage backend is unavailable.

For a more specific health check that exercises the full read path:

#!/bin/bash
# /usr/local/bin/openvsx-api-check.sh

HEARTBEAT_URL="https://vigilmon.online/heartbeat/abc123"
OPENVSX_BASE="https://your-openvsx-instance.example.com"
KNOWN_EXTENSION_ID="redhat.java"   # A known extension in your registry

HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
  "$OPENVSX_BASE/api/$KNOWN_EXTENSION_ID" \
  --max-time 10)

if [ "$HTTP_CODE" != "200" ]; then
  echo "OpenVSX API returned $HTTP_CODE for known extension"
  exit 1
fi

echo "OpenVSX API OK: HTTP $HTTP_CODE"
curl -s "$HEARTBEAT_URL"

Schedule this as a Vigilmon cron heartbeat with a 2-minute interval as a backup to the HTTP monitor. The HTTP monitor catches total unavailability; the heartbeat catches cases where the API returns 200 but the response body indicates a degraded state.


Step 2: Track Extension Publish Throughput

Extension publishing is the write path of OpenVSX — publishers send .vsix files to the registry, which validates them, stores them in object storage, indexes them for search, and makes them available for download. Publish failures are particularly high-impact because they block extension authors from releasing updates, and the failure mode is often non-obvious: the publish API may return a 202 Accepted but then fail asynchronously during storage or indexing.

Monitor publish success with a dedicated test publisher:

#!/bin/bash
# /usr/local/bin/openvsx-publish-check.sh

HEARTBEAT_URL="https://vigilmon.online/heartbeat/def456"
OPENVSX_BASE="https://your-openvsx-instance.example.com"
PUBLISH_TOKEN="your-test-publisher-token"
CANARY_VSIX="/opt/openvsx-canary/health-check-1.0.0.vsix"
CANARY_NAMESPACE="your-test-namespace"
CANARY_EXT="health-check"

# Publish the canary extension
PUBLISH_RESPONSE=$(curl -s -w "\n%{http_code}" \
  -X POST "$OPENVSX_BASE/api/$CANARY_NAMESPACE/$CANARY_EXT" \
  -H "Authorization: Bearer $PUBLISH_TOKEN" \
  -H "Content-Type: application/octet-stream" \
  --data-binary "@$CANARY_VSIX" \
  --max-time 60)

HTTP_CODE=$(echo "$PUBLISH_RESPONSE" | tail -1)
RESPONSE_BODY=$(echo "$PUBLISH_RESPONSE" | head -1)

if [ "$HTTP_CODE" != "201" ] && [ "$HTTP_CODE" != "202" ]; then
  echo "Publish failed: HTTP $HTTP_CODE — $RESPONSE_BODY"
  exit 1
fi

# Wait for asynchronous indexing (if 202 Accepted)
if [ "$HTTP_CODE" = "202" ]; then
  sleep 30  # Allow time for async processing
  # Verify the published version is now accessible
  VERSION=$(echo "$RESPONSE_BODY" | python3 -c "import sys,json; print(json.load(sys.stdin).get('version',''))" 2>/dev/null)
  if [ -n "$VERSION" ]; then
    CHECK_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
      "$OPENVSX_BASE/api/$CANARY_NAMESPACE/$CANARY_EXT/$VERSION")
    if [ "$CHECK_CODE" != "200" ]; then
      echo "Published version not accessible after async processing: HTTP $CHECK_CODE"
      exit 1
    fi
  fi
fi

echo "Publish OK: HTTP $HTTP_CODE"
curl -s "$HEARTBEAT_URL"

Run this check every 30 minutes. Keep the canary .vsix file small (under 50KB) and increment the version number in the package manifest each run to avoid version conflict errors. A simple approach is to use the current timestamp as the patch version: 1.0.${YYYYMMDDHHMM}.


Step 3: Monitor Download Endpoint Performance

Extension downloads are the highest-traffic operation in OpenVSX — every IDE startup triggers download checks for installed extensions. Downloads go through the registry API to object storage (typically S3-compatible or a local filesystem). When object storage is throttled, when the CDN fronting your registry has cache misses, or when the registry server is CPU-bound from processing too many concurrent downloads, download throughput drops and IDE users see slow extension loads or timeout errors.

Monitor download latency for a known extension:

#!/bin/bash
# /usr/local/bin/openvsx-download-check.sh

HEARTBEAT_URL="https://vigilmon.online/heartbeat/ghi789"
OPENVSX_BASE="https://your-openvsx-instance.example.com"
KNOWN_NAMESPACE="redhat"
KNOWN_EXT="java"
KNOWN_VERSION="1.28.1"   # Pin a specific version for consistent measurement
LATENCY_THRESHOLD_MS=3000

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

# Download the extension file (use -o /dev/null to avoid saving)
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
  "$OPENVSX_BASE/api/$KNOWN_NAMESPACE/$KNOWN_EXT/$KNOWN_VERSION/file/$KNOWN_NAMESPACE.$KNOWN_EXT-$KNOWN_VERSION.vsix" \
  --max-time 30 \
  -L)  # Follow redirects to object storage

END_MS=$(date +%s%3N)
LATENCY_MS=$((END_MS - START_MS))

if [ "$HTTP_CODE" != "200" ]; then
  echo "Download failed: HTTP $HTTP_CODE"
  exit 1
fi

if [ "$LATENCY_MS" -gt "$LATENCY_THRESHOLD_MS" ]; then
  echo "Download too slow: ${LATENCY_MS}ms > threshold ${LATENCY_THRESHOLD_MS}ms"
  exit 1
fi

echo "Download OK: ${LATENCY_MS}ms for $KNOWN_NAMESPACE.$KNOWN_EXT-$KNOWN_VERSION.vsix"
curl -s "$HEARTBEAT_URL"

Run this every 5 minutes. The 3-second threshold is generous — production-grade registries with object storage should deliver extension files in under 500ms for cached responses. Use the higher threshold to catch severe degradation; tune it down as you understand your baseline.

Add a complementary HTTP monitor in Vigilmon for the download redirect URL directly:

  1. Click Add MonitorHTTP / HTTPS.
  2. Enter the direct download URL for your canary extension file.
  3. Set check interval to 5 minutes.
  4. Enable Follow redirects and set a response time alert at 2 seconds.

Step 4: Validate Namespace Health

OpenVSX uses a namespace system for publisher identity. Each extension belongs to a namespace (publisher.extension), and publishers must verify ownership of their namespace before publishing. Namespace validation failures are a common source of publish errors — either the namespace doesn't exist, the publisher token doesn't have access, or the namespace is in an unverified state that blocks publishing. Monitor namespace health:

#!/bin/bash
# /usr/local/bin/openvsx-namespace-check.sh

HEARTBEAT_URL="https://vigilmon.online/heartbeat/jkl012"
OPENVSX_BASE="https://your-openvsx-instance.example.com"
PUBLISH_TOKEN="your-test-publisher-token"

# List namespaces accessible to the current token
NAMESPACE_RESPONSE=$(curl -s -w "\n%{http_code}" \
  "$OPENVSX_BASE/api/user/namespaces" \
  -H "Authorization: Bearer $PUBLISH_TOKEN" \
  --max-time 10)

HTTP_CODE=$(echo "$NAMESPACE_RESPONSE" | tail -1)
RESPONSE_BODY=$(echo "$NAMESPACE_RESPONSE" | head -1)

if [ "$HTTP_CODE" != "200" ]; then
  echo "Namespace listing failed: HTTP $HTTP_CODE"
  exit 1
fi

# Check that expected namespaces are present
NAMESPACE_COUNT=$(echo "$RESPONSE_BODY" | python3 -c "
import sys, json
data = json.load(sys.stdin)
namespaces = data if isinstance(data, list) else data.get('namespaces', [])
print(len(namespaces))
" 2>/dev/null)

if [ -z "$NAMESPACE_COUNT" ] || [ "$NAMESPACE_COUNT" -eq 0 ]; then
  echo "No namespaces returned — auth token may have expired or namespace access revoked"
  exit 1
fi

# Verify namespace verification status
UNVERIFIED=$(echo "$RESPONSE_BODY" | python3 -c "
import sys, json
data = json.load(sys.stdin)
namespaces = data if isinstance(data, list) else data.get('namespaces', [])
unverified = [n.get('name', '') for n in namespaces if not n.get('verified', True)]
print(','.join(unverified))
" 2>/dev/null)

if [ -n "$UNVERIFIED" ]; then
  echo "Unverified namespaces found: $UNVERIFIED (publish will fail)"
  exit 1
fi

echo "Namespace health OK: $NAMESPACE_COUNT namespaces, all verified"
curl -s "$HEARTBEAT_URL"

Run this check every 30 minutes. Publisher tokens in OpenVSX can expire or be revoked by admin action, and namespace verification status can change after a registry migration or admin operation. Catching this proactively means you know before extension authors try to publish.


Step 5: Monitor Upstream Sync Status

OpenVSX can be configured to mirror extensions from the VS Code Marketplace via an upstream sync process. When this sync stalls — because the Marketplace API is rate-limiting you, because a network route between your registry and the Marketplace is degraded, or because a large extension batch is stuck in processing — your registry falls behind and users can't install extensions that are available on the Marketplace. Monitor sync freshness:

#!/bin/bash
# /usr/local/bin/openvsx-sync-check.sh

HEARTBEAT_URL="https://vigilmon.online/heartbeat/mno345"
OPENVSX_BASE="https://your-openvsx-instance.example.com"
ADMIN_TOKEN="your-admin-token"
MAX_SYNC_AGE_MINUTES=120   # Alert if last sync was more than 2 hours ago

# Query the admin API for last sync timestamp
SYNC_RESPONSE=$(curl -s \
  "$OPENVSX_BASE/admin/report" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  --max-time 15)

if [ -z "$SYNC_RESPONSE" ]; then
  echo "No response from admin sync endpoint"
  exit 1
fi

# Extract last sync timestamp
LAST_SYNC=$(echo "$SYNC_RESPONSE" | python3 -c "
import sys, json
from datetime import datetime
data = json.load(sys.stdin)
# Adjust field name to match your OpenVSX version's admin API
last_sync = data.get('lastSyncedAt') or data.get('last_sync_at') or ''
print(last_sync)
" 2>/dev/null)

if [ -z "$LAST_SYNC" ]; then
  echo "Could not determine last sync time from admin report"
  # Don't fail — admin API format may differ; use extension freshness instead
else
  SYNC_AGE_MINUTES=$(python3 -c "
from datetime import datetime, timezone
import sys
try:
    last = datetime.fromisoformat('$LAST_SYNC'.replace('Z', '+00:00'))
    now = datetime.now(timezone.utc)
    print(int((now - last).total_seconds() / 60))
except Exception as e:
    print(9999)
")
  if [ "$SYNC_AGE_MINUTES" -gt "$MAX_SYNC_AGE_MINUTES" ]; then
    echo "Upstream sync stale: last sync ${SYNC_AGE_MINUTES}m ago (threshold: ${MAX_SYNC_AGE_MINUTES}m)"
    exit 1
  fi
  echo "Sync OK: last sync ${SYNC_AGE_MINUTES}m ago"
fi

# Cross-check: verify a recently-published Marketplace extension is present
RECENT_EXT="ms-python.python"
CHECK_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
  "$OPENVSX_BASE/api/$RECENT_EXT" --max-time 10)

if [ "$CHECK_CODE" != "200" ]; then
  echo "Marker extension $RECENT_EXT not found in registry (sync may have stalled)"
  exit 1
fi

echo "Upstream sync health OK"
curl -s "$HEARTBEAT_URL"

Set the heartbeat interval to 30 minutes. Sync staleness of 2 hours is a reasonable threshold for most registries — Marketplace updates are continuous, but not every update is critical. For high-freshness requirements (e.g., an enterprise environment where security teams expect same-day vulnerability patches in extension updates), tighten the threshold to 30 minutes.


Putting It All Together

With these five monitors in place, your Vigilmon dashboard gives you complete OpenVSX registry visibility:

| Monitor | Type | Check Interval | Alert On | |---------|------|----------------|----------| | API availability | HTTP + Cron heartbeat | 1–2 min | HTTP non-200 or missing ping | | Extension publish throughput | Cron heartbeat | 30 min | Publish failure or async processing error | | Download endpoint performance | HTTP + Cron heartbeat | 5 min | HTTP non-200 or latency > 3s | | Namespace validation health | Cron heartbeat | 30 min | Auth failure or unverified namespaces | | Upstream sync status | Cron heartbeat | 30 min | Sync age > 2 hours |

The most critical monitor is API availability — when OpenVSX is down, all extension operations fail for every developer and IDE in your environment. The second priority is download performance, because slow downloads manifest as IDE startup latency that degrades developer experience even when the registry is technically "up."

OpenVSX's open-source architecture means you have full visibility into what's running, but that visibility requires you to instrument it. External monitoring with Vigilmon gives you the user-perspective view — checking the same endpoints your IDE clients check — rather than just internal metrics. Catching a stalled upstream sync or a broken publish path before developers report it turns registry maintenance from reactive firefighting into proactive operations.

Sign up for a free Vigilmon account and add your first OpenVSX API monitor in under two minutes.

Monitor your app with Vigilmon

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

Start free →