Microservices architectures distribute complexity across many small services. This makes each service easier to reason about individually — but makes the whole system harder to observe. When something breaks, it's rarely obvious which service is the culprit, and cascading failures can take down half your system before any single alert fires.
This guide covers monitoring strategies for microservices using Vigilmon's HTTP uptime monitoring.
The Microservices Monitoring Problem
In a monolith, one monitor covering the main URL tells you most of what you need to know. In microservices, you have:
- 5–50+ independent services, each with its own failure mode
- Internal service-to-service calls that fail silently
- An API gateway that might mask downstream failures
- Shared infrastructure (databases, message queues) that, when broken, takes down multiple services at once
You need monitoring at multiple layers, not just the edge.
Layer 1: API Gateway Monitoring
Your API gateway (Kong, AWS API Gateway, Nginx, Traefik, Envoy) is the entry point for external traffic. Monitor it first:
GET https://api.your-app.com/health
If this returns an error, all downstream services are unreachable regardless of their individual health.
Most API gateways have built-in health endpoints:
-
Kong:
GET /_kong/health/readiness -
Nginx:
GET /nginx_status(with stub_status module) -
Traefik:
GET /ping
Layer 2: Service-Level Health Endpoints
Each microservice should expose its own health endpoint. Define a standard contract across all services:
// Standard health response format
{
"status": "ok", // "ok" | "degraded" | "error"
"service": "orders",
"version": "1.2.3",
"dependencies": {
"database": "ok",
"queue": "ok",
"payment-service": "ok"
}
}
Standardizing this format across services makes it easy to set up identical monitors for each.
Example: Node.js Microservice Health
// health.ts
import { Router } from 'express';
import { checkDatabase } from './db';
import { checkQueue } from './queue';
export const healthRouter = Router();
healthRouter.get('/health', async (req, res) => {
const [db, queue] = await Promise.allSettled([
checkDatabase(),
checkQueue(),
]);
const isHealthy =
db.status === 'fulfilled' &&
queue.status === 'fulfilled';
res.status(isHealthy ? 200 : 503).json({
status: isHealthy ? 'ok' : 'degraded',
service: process.env.SERVICE_NAME,
dependencies: {
database: db.status === 'fulfilled' ? 'ok' : 'error',
queue: queue.status === 'fulfilled' ? 'ok' : 'error',
},
});
});
Layer 3: Shared Infrastructure Monitoring
Services share databases, message queues, and caches. Monitor these independently:
| Resource | Monitor URL | What It Tests |
|---|---|---|
| PostgreSQL |
/health/db on any service |
Database connectivity |
| Redis |
/health/cache on any service |
Cache connectivity |
| Kafka/RabbitMQ |
/health/queue on queue consumer |
Queue connectivity |
If your shared Postgres goes down, you'll see multiple service monitors fail simultaneously — that pattern tells you it's infrastructure, not a service bug.
Vigilmon Monitor Configuration for Microservices
Set up one monitor per service, all routed through your API gateway:
# API Gateway
https://api.your-app.com/health
# Core Services (via gateway)
https://api.your-app.com/users/health
https://api.your-app.com/orders/health
https://api.your-app.com/payments/health
https://api.your-app.com/notifications/health
# Admin/Internal Services (if separately accessible)
https://admin.your-app.com/health
In Vigilmon:
- Create a monitor for each endpoint
- Group monitors by service name (use labels)
- Set alert channels per criticality (payments = PagerDuty; blog service = email only)
Dependency Chain Monitoring
Microservices call each other. When Service A calls Service B, a failure in B causes A to degrade or fail too. Map your dependency chains and monitor critical paths:
Frontend → API Gateway → Orders Service → [Database, Payment Service]
Payment Service → [Stripe, Database]
Monitor each step in the chain. If Vigilmon shows Orders Service degraded but Payment Service healthy, the problem is in Orders or its database — not in Payment.
Heartbeat Monitoring for Background Services
Not all microservices have HTTP endpoints. Workers, schedulers, and event consumers need heartbeat monitoring:
# Python worker that consumes from a queue
import requests
def process_batch():
events = queue.receive_messages(max_count=10)
for event in events:
handle_event(event)
# Signal successful processing every batch
if events:
requests.get('https://vigilmon.online/hb/YOUR_HEARTBEAT_ID', timeout=5)
If the worker crashes or the queue stalls, no heartbeat arrives within the window, and Vigilmon sends an alert.
Cascading Failure Detection
Pattern in Vigilmon alerts: if you see 5 services alerting within 60 seconds, that's a cascading failure from shared infrastructure — not 5 independent bugs. Configure Vigilmon's alert grouping to show simultaneous alerts together.
When this happens:
- Check shared infrastructure first (database, queue, cache)
- Check your API gateway and load balancer
- Check your Kubernetes cluster nodes or container orchestrator
Kubernetes Health Probes vs External Monitoring
Kubernetes liveness and readiness probes ensure containers restart when unhealthy, but they only test the container itself. Vigilmon's external monitoring complements probes by checking:
- That Kubernetes ingress is correctly routing traffic
- That external DNS resolves to your cluster
- That the full request path works (not just that the pod is alive)
Run both — they cover different failure scenarios.
Start Monitoring Your Microservices
Vigilmon's free tier covers 10 monitors, which is enough for a 5–8 service architecture. The paid plans scale to unlimited monitors for larger deployments.
Sign up at vigilmon.online.
Top comments (0)