tutorial

Monitoring Umbraco CMS with Vigilmon

Umbraco is the leading .NET CMS for enterprise and government sites — but self-hosted Umbraco needs active monitoring. Here's how to monitor Umbraco application health, SQL Server, Examine search, media storage, and the backoffice with Vigilmon.

Umbraco is the .NET-native CMS of choice for enterprise, government, and media sites across Europe and beyond. Running Umbraco on your own infrastructure means you own uptime, database health, search index integrity, and backoffice availability — none of which a managed host handles for you. Vigilmon closes that gap with HTTP uptime monitors, heartbeat checks for SQL Server and Examine search, and memory and media storage alerts for your Umbraco deployment.

What You'll Set Up

  • Umbraco application and backoffice uptime monitors
  • SQL Server connectivity and query latency checks
  • Examine search index health monitoring
  • Media storage availability and capacity alerts
  • .NET process memory monitoring
  • Content Delivery API health for headless deployments
  • Umbraco version currency tracking

Prerequisites

  • A self-hosted Umbraco 13+ installation running on ASP.NET Core (.NET 8+)
  • Windows Server with IIS or Linux with Kestrel
  • Access to the server for cron/scheduled task setup
  • A free Vigilmon account

Why Monitoring Matters for Umbraco

Umbraco's .NET architecture introduces failure modes that differ from PHP CMS platforms. The ASP.NET Core process can crash (or enter a degraded state) and IIS will typically restart it — but during that window, all requests return 503. SQL Server connection pool exhaustion silently queues requests until timeouts cascade. Examine's Lucene.NET indexes can become corrupted or out of sync, causing search to return zero results without any visible error on the frontend. And for headless Umbraco deployments, the Content Delivery API is a first-class availability target.

Monitoring Umbraco means watching the .NET process, the database, the search indexes, and the content delivery surface.


Key Metrics to Monitor

| Metric | Why It Matters | Alert Threshold | |--------|---------------|-----------------| | Application root health | .NET process availability | Any non-2xx | | Backoffice (/umbraco) health | Editorial interface availability | Unavailable | | SQL Server connectivity | All content stored in DB | Any failure | | SQL Server query latency | CMS responsiveness | > 500ms | | Examine index rebuild status | Search correctness | Rebuild failure | | Media storage availability | Uploaded assets | Connectivity failure | | Media storage capacity | Disk or blob space | > 80% | | .NET process RSS memory | Memory leak or pressure | > 80% of available | | Content node count | Accidental content deletion | Unexpected drop | | Content Delivery API health | Headless consumers | Any errors | | Umbraco version lag | LTS security patches | > 1 minor version behind |


Step 1: Add a Health Check Endpoint to Umbraco

Umbraco 10+ ships with ASP.NET Core's built-in health checks infrastructure. Wire up a health endpoint that Vigilmon can probe:

In Program.cs (or Startup.cs for older configurations):

builder.Services.AddHealthChecks()
    .AddSqlServer(
        connectionString: builder.Configuration.GetConnectionString("umbracoDbDSN")!,
        name: "sql-server",
        tags: new[] { "db", "sql" })
    .AddUrlGroup(
        new Uri("https://yourumbracosite.com/umbraco"),
        name: "backoffice",
        tags: new[] { "ui" });

// In the app pipeline:
app.MapHealthChecks("/health", new HealthCheckOptions
{
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
app.MapHealthChecks("/health/live", new HealthCheckOptions
{
    Predicate = _ => false  // liveness: just process health
});

Install the required packages:

dotnet add package AspNetCore.HealthChecks.SqlServer
dotnet add package AspNetCore.HealthChecks.UI.Client

The /health endpoint returns JSON with the status of each registered check. Point Vigilmon at https://yourumbracosite.com/health/live for liveness (just the .NET process) and /health for full stack readiness.


Step 2: Monitor the Umbraco Application and Backoffice

Add two HTTP monitors in Vigilmon:

Monitor 1 — Application liveness:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://yourumbracosite.com/health/live
  3. Check interval: 1 minute
  4. Expected status: 200
  5. Click Save.

Monitor 2 — Backoffice availability:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://yourumbracosite.com/umbraco
  3. Check interval: 5 minutes
  4. Expected status: 200 or 302 (redirect to login)
  5. Click Save.

Alert condition for Monitor 1: immediate notification on any non-2xx response — this means the .NET process is down or unhealthy.

Alert condition for Monitor 2: notify after 2 consecutive failures — the backoffice going down blocks all content editors.


Step 3: Monitor SQL Server Health

Umbraco stores content nodes, document types, relations, users, and media metadata in SQL Server. Use the health check endpoint from Step 1 to include SQL Server status, or add a dedicated heartbeat probe via PowerShell scheduled task:

# umbraco-db-check.ps1
$connectionString = "Server=localhost;Database=UmbracoDb;Integrated Security=true;"
$heartbeatUrl = "https://vigilmon.online/api/heartbeat/YOUR_HEARTBEAT_ID"

try {
    $conn = New-Object System.Data.SqlClient.SqlConnection($connectionString)
    $conn.Open()
    
    $cmd = $conn.CreateCommand()
    $cmd.CommandText = "SELECT COUNT(*) FROM umbracoNode WHERE nodeObjectType = 'C66BA18E-EAF3-4CFF-8A22-41B16D66A972'"
    $cmd.CommandTimeout = 5
    $nodeCount = $cmd.ExecuteScalar()
    
    $conn.Close()
    
    # Send heartbeat — DB is alive and responding
    Invoke-WebRequest -Uri $heartbeatUrl -Method Get -UseBasicParsing | Out-Null
    Write-Host "DB OK: $nodeCount content nodes"
} catch {
    Write-Host "DB check failed: $_"
    # Heartbeat not sent — Vigilmon will alert
}

Schedule this as a Windows Task Scheduler task running every 5 minutes, or as a Linux systemd timer if running on Linux with sqlcmd.


Step 4: Monitor Examine Search Index Health

Umbraco's Examine search (backed by Lucene.NET) can silently go out of sync — content is published but search returns stale or zero results. Add a health check for Examine in your Umbraco application:

// Custom Examine health check
public class ExamineHealthCheck : IHealthCheck
{
    private readonly IExamineManager _examineManager;
    
    public ExamineHealthCheck(IExamineManager examineManager)
    {
        _examineManager = examineManager;
    }
    
    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        if (!_examineManager.TryGetIndex("ExternalIndex", out var index))
            return Task.FromResult(HealthCheckResult.Unhealthy("ExternalIndex not found"));
        
        var searcher = index.GetSearcher();
        var results = searcher.CreateQuery().All().Execute(maxResults: 1);
        
        if (results.TotalItemCount == 0)
            return Task.FromResult(HealthCheckResult.Degraded(
                "ExternalIndex appears empty — may need rebuild"));
        
        return Task.FromResult(HealthCheckResult.Healthy(
            $"ExternalIndex has {results.TotalItemCount} documents"));
    }
}

Register in Program.cs:

builder.Services.AddHealthChecks()
    .AddCheck<ExamineHealthCheck>("examine-search", tags: new[] { "search" });

Expose a separate endpoint for search health:

app.MapHealthChecks("/health/search", new HealthCheckOptions
{
    Predicate = check => check.Tags.Contains("search")
});

Add a Vigilmon HTTP monitor for https://yourumbracosite.com/health/search with a 5-minute interval. Alert on any non-200 or degraded response — an empty Examine index causes frontend search to return no results.


Step 5: Monitor Media Storage Health

Umbraco stores uploaded media on local disk, Azure Blob Storage, or S3-compatible storage depending on your configuration. Media storage failure prevents editors from uploading assets and can break existing asset references.

For local disk storage:

#!/bin/bash
# /usr/local/bin/umbraco-media-check.sh
MEDIA_DIR="/var/www/umbraco/wwwroot/media"
HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/YOUR_MEDIA_HEARTBEAT_ID"

USAGE=$(df "$MEDIA_DIR" | awk 'NR==2 {print $5}' | tr -d '%')
WRITABLE=$([ -w "$MEDIA_DIR" ] && echo "yes" || echo "no")

if [ "$WRITABLE" = "yes" ] && [ "$USAGE" -lt 80 ]; then
    curl -s "$HEARTBEAT_URL" > /dev/null
fi

For Azure Blob Storage:

# umbraco-blob-check.ps1
$storageAccount = "yourstorageaccount"
$containerName = "umbraco-media"
$heartbeatUrl = "https://vigilmon.online/api/heartbeat/YOUR_MEDIA_HEARTBEAT_ID"

try {
    $ctx = New-AzStorageContext -StorageAccountName $storageAccount -UseConnectedAccount
    $blobs = Get-AzStorageBlob -Container $containerName -Context $ctx -MaxCount 1
    Invoke-WebRequest -Uri $heartbeatUrl -Method Get -UseBasicParsing | Out-Null
} catch {
    Write-Host "Blob storage check failed: $_"
}

Alert threshold: storage unavailable or > 80% full.


Step 6: Monitor .NET Process Memory

ASP.NET Core memory leaks or unexpected memory pressure can degrade Umbraco performance before causing an outright crash. Expose memory metrics via the health check or a custom metrics endpoint:

// Add to health checks
builder.Services.AddHealthChecks()
    .AddCheck("memory", () =>
    {
        var totalMemory = GC.GetTotalMemory(forceFullCollection: false);
        var availableMemory = 8L * 1024 * 1024 * 1024; // 8GB — adjust to your server RAM
        var usagePercent = (double)totalMemory / availableMemory * 100;
        
        if (usagePercent > 90)
            return HealthCheckResult.Unhealthy($"Memory usage critical: {usagePercent:F1}%");
        if (usagePercent > 80)
            return HealthCheckResult.Degraded($"Memory usage high: {usagePercent:F1}%");
        
        return HealthCheckResult.Healthy($"Memory usage: {usagePercent:F1}%");
    }, tags: new[] { "memory" });

Expose at /health/memory and add a Vigilmon monitor with a 2-minute interval. Alert on degraded (>80%) or unhealthy (>90%) states.


Step 7: Monitor the Content Delivery API (Headless)

If you're using Umbraco in headless mode, the Content Delivery API is a first-class service for your frontend consumers (Next.js, Nuxt, React, etc.). Monitor it explicitly:

  1. In Vigilmon, click Add MonitorHTTP / HTTPS.
  2. URL: https://yourumbracosite.com/umbraco/delivery/api/v2/content?take=1
  3. Add header: Api-Key: your-api-key if API key protection is enabled.
  4. Expected status: 200.
  5. Check interval: 2 minutes.

Alert condition: any non-200 response — headless consumers will be returning empty or error pages immediately.


Step 8: Configure Alerting

Set up notification channels in Vigilmon for your Umbraco monitors:

  1. Go to Settings → Notifications.
  2. Configure email, Slack, Microsoft Teams, or PagerDuty.
  3. Route critical alerts immediately; route informational alerts with a delay.

Recommended routing:

| Monitor | Severity | Notification | |---------|----------|-------------| | Application down | Critical | Immediate: Slack + email | | Backoffice down | High | Immediate: Slack | | SQL Server failure | Critical | Immediate: Slack + email | | Examine index empty | High | Slack | | Media storage failure | High | Slack | | Memory > 80% | Medium | Email | | Content Delivery API error | Critical | Immediate: Slack + email | | Disk > 80% | Medium | Email |


Step 9: Test Your Monitors

Validate each monitor fires correctly before trusting them in production:

# Test SQL Server alert
Stop-Service MSSQLSERVER
# → heartbeat missed within 10 minutes — Vigilmon alerts
Start-Service MSSQLSERVER

# Test application health
Stop-WebSite "UmbracoSite"
# → HTTP monitor alerts within 1-2 minutes
Start-WebSite "UmbracoSite"

# Trigger Examine empty check (careful — this clears the index)
# In Umbraco backoffice: Examine Management → ExternalIndex → Clear
# → /health/search should return degraded within 5 minutes
# Rebuild the index after testing

Conclusion

Umbraco on self-hosted infrastructure requires monitoring at four distinct layers: the ASP.NET Core process, the SQL Server database, the Examine search subsystem, and the media storage layer. With Vigilmon covering each of these — plus optional Content Delivery API monitoring for headless deployments — you'll catch failures before editors and visitors do.

Start with the application liveness check and SQL Server heartbeat. Then add Examine search monitoring — it's the failure mode most specific to Umbraco that generic uptime monitoring misses entirely.

Start monitoring your Umbraco site with Vigilmon →

Monitor your app with Vigilmon

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

Start free →