How to Monitor Your AWS Lambda Functions with Vigilmon
AWS Lambda has transformed how teams build backends — no servers to manage, automatic scaling, pay-per-invocation. But serverless functions fail in subtle ways that traditional monitoring doesn't catch: cold starts, timeout errors, concurrent execution limits, and downstream service failures.
This guide shows you how to monitor your Lambda-powered applications with Vigilmon.
Lambda Failure Modes You Need to Monitor
AWS Lambda is reliable infrastructure, but your functions and the services they call can fail:
- Cold starts: First invocations after idle periods can be slow (500ms-10s for JVM runtimes)
- Timeouts: Functions that exceed the configured timeout return errors
- Memory pressure: Functions approaching memory limits run slowly and may crash
- Concurrent execution limits: Lambda has account-level concurrency limits
- Downstream failures: Database, external API, or AWS service failures
- Deployment errors: New versions with bugs replacing working functions
- Layer compatibility: Lambda layers that break after runtime updates
Approach 1: Monitor via API Gateway
Most Lambda functions are exposed via API Gateway or Function URLs. Monitor those endpoints:
// Lambda function with health check
exports.handler = async (event) => {
// Health check route
if (event.rawPath === '/health' || event.path === '/health') {
return await handleHealthCheck();
}
// Normal function logic...
return handleRequest(event);
};
async function handleHealthCheck() {
const checks = {};
const start = Date.now();
// Check DynamoDB
try {
const { DynamoDBClient, DescribeTableCommand } = require('@aws-sdk/client-dynamodb');
const client = new DynamoDBClient({ region: process.env.AWS_REGION });
await client.send(new DescribeTableCommand({ TableName: process.env.TABLE_NAME }));
checks.dynamodb = 'ok';
} catch (e) {
checks.dynamodb = 'error';
}
// Check RDS (if applicable)
// Check external APIs
const allOk = Object.values(checks).every(s => s === 'ok');
return {
statusCode: allOk ? 200 : 503,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
status: allOk ? 'ok' : 'degraded',
latency_ms: Date.now() - start,
checks,
region: process.env.AWS_REGION,
function_name: process.env.AWS_LAMBDA_FUNCTION_NAME,
memory_mb: parseInt(process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE)
})
};
}
Python Lambda Health Check
import json
import time
import boto3
import os
def handler(event, context):
path = event.get('rawPath') or event.get('path', '')
if path == '/health':
return handle_health_check()
return handle_request(event, context)
def handle_health_check():
start = time.time()
checks = {}
# Check DynamoDB table
try:
dynamodb = boto3.client('dynamodb', region_name=os.environ['AWS_REGION'])
dynamodb.describe_table(TableName=os.environ.get('TABLE_NAME', 'health-check'))
checks['dynamodb'] = 'ok'
except Exception as e:
checks['dynamodb'] = f'error: {str(e)[:50]}'
all_ok = all(v == 'ok' for v in checks.values())
return {
'statusCode': 200 if all_ok else 503,
'headers': {'Content-Type': 'application/json'},
'body': json.dumps({
'status': 'ok' if all_ok else 'degraded',
'latency_ms': round((time.time() - start) * 1000),
'checks': checks,
'function': os.environ.get('AWS_LAMBDA_FUNCTION_NAME'),
'memory_mb': os.environ.get('AWS_LAMBDA_FUNCTION_MEMORY_SIZE')
})
}
Approach 2: Lambda Function URLs
AWS Lambda Function URLs let you call Lambda directly without API Gateway:
// Lambda with Function URL
exports.handler = async (event) => {
if (event.requestContext?.http?.path === '/health') {
return {
statusCode: 200,
body: JSON.stringify({ status: 'ok', timestamp: new Date().toISOString() })
};
}
// Handle other requests...
};
Monitor the Function URL directly in Vigilmon:
https://FUNCTION_ID.lambda-url.us-east-1.on.aws/health
Approach 3: Heartbeat Monitoring for Scheduled Lambdas
For EventBridge Scheduled Lambda functions (replacing cron jobs), use heartbeat monitoring:
// Scheduled Lambda function
exports.handler = async (event) => {
try {
// Your scheduled task logic
await processQueue();
await syncToDataWarehouse();
// Ping Vigilmon heartbeat
const https = require('https');
await new Promise((resolve) => {
https.get('https://hb.vigilmon.online/YOUR_SLUG', resolve);
});
return { status: 'success' };
} catch (err) {
console.error('Scheduled Lambda failed:', err);
throw err; // Lambda will mark as failed, CloudWatch will log
// No Vigilmon ping = heartbeat alert fires
}
};
Setting Up Vigilmon Monitors
For API Gateway / Function URL Lambda:
- Go to vigilmon.online and sign up free
- Add Monitor → HTTP(S)
- URL:
https://api.yourdomain.com/health - Interval: 1 minute
- Response validation: status 200, body contains
"status":"ok" - Response time alert: warn if >3s (cold start threshold), critical if >10s
For Scheduled Lambdas:
- Add Monitor → Heartbeat Monitor
- Set the expected interval to your schedule + 20% grace period
- Paste the heartbeat URL into your Lambda code
Cold Start Monitoring
Vigilmon's response time tracking helps identify cold start patterns:
- Regular spikes at specific intervals = cold starts after idle periods
- Sustained slow responses = memory pressure or slow dependencies
- Sudden response time increase after deploy = new version has performance regression
Summary
AWS Lambda is powerful but needs proper monitoring. With a health endpoint and Vigilmon:
- Detect function failures within 60 seconds
- Monitor cold starts through response time tracking
- Catch deployment issues before they impact users
- Monitor scheduled jobs with heartbeat monitoring
Start monitoring your Lambda functions for free at vigilmon.online.
Top comments (0)