Azure Functions is Microsoft's serverless compute platform — you write a function, Azure runs it on demand. But "on demand" means it's invisible between invocations. There are no servers to SSH into, no persistent processes to watch, and Azure's built-in Application Insights only tells you what happened after a user hit your function. Vigilmon gives you an external, independent health check that alerts you before users start seeing errors.
This tutorial covers adding a dedicated health HTTP trigger to your Azure Function app and wiring it into Vigilmon for continuous uptime monitoring.
What You'll Build
- An HTTP trigger health function that checks your real dependencies
- A Vigilmon HTTP monitor with cold-start-aware timeout settings
- Alerting for function timeouts and cold-start failures
- A keyword assertion to catch degraded-but-200 responses
Prerequisites
- An Azure Function App (any plan: Consumption, Flex Consumption, or Premium)
- Azure Functions Core Tools or the VS Code Azure Functions extension
- A free account at vigilmon.online
Step 1: Add a Health HTTP Trigger
Azure Functions are isolated from each other, but you can add a dedicated HealthCheck function to your existing Function App. This function probes your real dependencies (database, downstream APIs, storage) and returns a structured JSON response.
C# (Isolated Worker)
// HealthCheckFunction.cs
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using System.Net;
public class HealthCheckFunction
{
private readonly HttpClient _http;
public HealthCheckFunction(IHttpClientFactory factory)
{
_http = factory.CreateClient();
}
[Function("HealthCheck")]
public async Task<HttpResponseData> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "health")] HttpRequestData req)
{
var checks = new Dictionary<string, string>();
bool ok = true;
// Example: probe a downstream dependency
try
{
var downstream = Environment.GetEnvironmentVariable("DOWNSTREAM_API_URL");
var resp = await _http.GetAsync(downstream + "/ping");
checks["downstream"] = resp.IsSuccessStatusCode ? "ok" : $"http_{(int)resp.StatusCode}";
if (!resp.IsSuccessStatusCode) ok = false;
}
catch (Exception ex)
{
checks["downstream"] = $"error: {ex.Message}";
ok = false;
}
var response = req.CreateResponse(ok ? HttpStatusCode.OK : HttpStatusCode.ServiceUnavailable);
response.Headers.Add("Content-Type", "application/json");
await response.WriteStringAsync(System.Text.Json.JsonSerializer.Serialize(new
{
status = ok ? "ok" : "degraded",
region = Environment.GetEnvironmentVariable("REGION_NAME") ?? "unknown",
checks
}));
return response;
}
}
JavaScript (Node.js v4 model)
// src/functions/health.js
const { app } = require("@azure/functions");
app.http("health", {
methods: ["GET"],
authLevel: "anonymous",
route: "health",
handler: async (request, context) => {
const checks = {};
let ok = true;
try {
const res = await fetch(process.env.DOWNSTREAM_API_URL + "/ping", {
signal: AbortSignal.timeout(3000),
});
checks.downstream = res.ok ? "ok" : `http_${res.status}`;
if (!res.ok) ok = false;
} catch (err) {
checks.downstream = `error: ${err.message}`;
ok = false;
}
return {
status: ok ? 200 : 503,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status: ok ? "ok" : "degraded", checks }),
};
},
});
Python
# function_app.py (v2 programming model)
import azure.functions as func
import json, os, urllib.request
app = func.FunctionApp()
@app.function_name(name="HealthCheck")
@app.route(route="health", auth_level=func.AuthLevel.ANONYMOUS)
def health_check(req: func.HttpRequest) -> func.HttpResponse:
checks = {}
ok = True
try:
url = os.environ.get("DOWNSTREAM_API_URL", "") + "/ping"
with urllib.request.urlopen(url, timeout=3) as r:
checks["downstream"] = "ok" if r.status == 200 else f"http_{r.status}"
except Exception as e:
checks["downstream"] = f"error: {str(e)}"
ok = False
body = json.dumps({"status": "ok" if ok else "degraded", "checks": checks})
return func.HttpResponse(body, status_code=200 if ok else 503,
mimetype="application/json")
Deploy using func azure functionapp publish <your-app-name> or via GitHub Actions.
Authorization tip: Use
authLevel: "anonymous"for health endpoints. Restrict access at the network level (IP allowlisting in the Function App's Networking settings) rather than function-level auth keys — Vigilmon doesn't need a key, and function keys rotate.
Step 2: Configure the Vigilmon HTTP Monitor
Once deployed, find your function URL in the Azure Portal under Functions → HealthCheck → Get Function URL (it will look like https://<app-name>.azurewebsites.net/api/health).
- Log in to Vigilmon → Add Monitor → HTTP.
- URL:
https://<your-app>.azurewebsites.net/api/health. - Check interval: 60 seconds.
- Response timeout: 15 seconds — Consumption plan cold starts can reach 5–10 seconds for .NET or JVM runtimes; give yourself headroom.
- Expected status:
200. - Keyword assertion: search for
"ok"in the body to catch503responses that somehow return 200 from a gateway.
Cold start note: On the Consumption plan, functions spin down after ~20 minutes of inactivity. Vigilmon's 60-second check interval keeps your function warm during business hours. For 24/7 warmth, use the Premium plan or add a second Vigilmon monitor on a 1-minute interval targeting the health endpoint specifically.
Step 3: Alert on Function Timeouts
Azure Functions on the Consumption plan have a default timeout of 5 minutes (configurable up to 10 minutes). Functions that hang silently — waiting on a deadlocked database connection, for example — will appear "up" until the timeout fires.
Set your Vigilmon response timeout below the function timeout. If your function should complete in under 5 seconds, set Vigilmon's timeout to 8 seconds. This way:
- Normal operation: Response arrives in < 2 s, check passes.
- Slow dependency: Response arrives in 6–8 s, Vigilmon timeout fires, alert sent.
- Deadlock: Function runs to its Azure timeout (~5 min), Vigilmon has already alerted after 8 s.
In Vigilmon's alert settings, configure:
- Notify after: 1 failure (serverless apps fail cleanly, not flakily)
- Re-notify: every 5 minutes while down
- Channel: Slack webhook + email for on-call
Step 4: Keyword Monitor for Cold-Start Error Pages
Azure sometimes returns an HTML error page (from the platform itself, not your code) with a 200 status code during cold starts or when the function host is starting. A plain HTTP status monitor would miss this.
Add a second Keyword monitor in Vigilmon:
- URL: same health endpoint URL.
- Keyword:
"status"(a JSON key that only your code returns, not an Azure error page). - Keyword must be present: yes.
- Interval: 60 seconds.
If Azure returns an HTML splash page instead of your JSON, this keyword check fires immediately.
Step 5: Alerting Configuration
| Scenario | What fires | Action | |---|---|---| | HTTP 503 from health function | HTTP monitor (status check) | Page on-call, post to Slack | | Response timeout exceeded | HTTP monitor (timeout) | Page on-call — dependency likely deadlocked | | HTML error page returned | Keyword monitor | Investigate Azure platform issue | | Health endpoint unreachable | HTTP monitor (connection failed) | Check Azure service health dashboard |
Set up your alert channels in Vigilmon under Settings → Notifications. Webhook support lets you route to Slack, PagerDuty, or any custom endpoint.
What Vigilmon Catches That Azure Monitor Misses
| Scenario | Azure Monitor | Vigilmon | |---|---|---| | Function returns 503 | Requires explicit metric alert on HTTP 5xx | HTTP monitor fires immediately | | Response time exceeds threshold | Requires custom Application Insights query | Timeout setting catches it | | Azure platform returns error page | No visibility | Keyword monitor catches it | | Cold-start causes user-facing delay | P99 latency alert (lagging) | Timeout alert (proactive) | | Your Azure account has an IAM issue | Your own alerts may be affected | Vigilmon is external and unaffected |
Azure Functions' ephemeral nature makes external monitoring essential — there's no persistent server state to observe from the inside. Vigilmon watches from the outside, where your users are, and alerts you the moment the function stops responding correctly.
Add your first Azure Functions monitor in under 5 minutes — register free at vigilmon.online.