Amazon CloudWatch

Has Demo

Monitoring, logging, and observability for your applications

šŸ’µ Cost: CloudWatch has partial Free Tier (10 custom metrics, 10 alarms, 5GB logs ingestion/month for 12 months). Log ingestion costs $0.50/GB - high-traffic apps can incur significant costs. Set retention policies (7-30 days) to control storage costs. See our Costs & Cleanup Guide for cleanup steps.

What is CloudWatch?

Amazon CloudWatch is the central monitoring service for AWS. It collects logs, metrics, and events from your applications and infrastructure, letting you visualize performance, set alarms, and troubleshoot issues.

Essential for Production

Without proper monitoring, you are flying blind. CloudWatch shows you what is happening inside your containers, helps debug errors, and alerts you before users notice problems.

CloudWatch Components

ComponentPurposeExample
LogsStore and search application logsconsole.log output, errors
MetricsNumerical data points over timeCPU usage, request count
AlarmsTrigger actions on metric thresholdsAlert when CPU exceeds 80%
DashboardsVisualize metrics in graphsReal-time performance view
Events/EventBridgeReact to state changesECS task stopped notification

CloudWatch Logs Structure

Plain Text
CloudWatch Logs
ā”œā”€ā”€ Log Group: /ecs/my-app-frontend
│   ā”œā”€ā”€ Log Stream: ecs/frontend/abc123
│   │   ā”œā”€ā”€ Log Event: "Server started on port 3000"
│   │   ā”œā”€ā”€ Log Event: "GET /api/health 200 5ms"
│   │   └── Log Event: "Error: Connection refused..."
│   │
│   └── Log Stream: ecs/frontend/def456
│       └── Log Event: "..."
│
└── Log Group: /ecs/my-app-worker
    └── Log Stream: ecs/worker/ghi789

ECS Fargate automatically sends container stdout/stderr to CloudWatch. Just ensure your task definition includes the log configuration:

JSON
{
  "logConfiguration": {
    "logDriver": "awslogs",
    "options": {
      "awslogs-group": "/ecs/my-app",
      "awslogs-region": "ap-southeast-1",
      "awslogs-stream-prefix": "ecs",
      "awslogs-create-group": "true"
    }
  }
}

View Logs via CLI

Terminal
$aws logs tail /ecs/my-app --follow
2024-01-15T10:30:00 Server started on port 3000
2024-01-15T10:30:01 Connected to database
2024-01-15T10:30:05 GET /api/health 200 2ms
2024-01-15T10:30:10 GET /api/users 200 45ms

CloudWatch Logs Insights lets you query logs using a SQL-like syntax:

SQL
# Find all errors in the last hour
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 100

# Count requests by status code
fields @message
| parse @message "* * * *" as method, path, status, duration
| stats count() by status

# Find slow requests (over 1 second)
fields @timestamp, @message
| parse @message "* * * *ms" as method, path, status, duration
| filter duration > 1000
| sort duration desc
TypeScript
import {
  CloudWatchLogsClient,
  PutLogEventsCommand,
  CreateLogStreamCommand
} from "@aws-sdk/client-cloudwatch-logs"

const client = new CloudWatchLogsClient({
  region: process.env.AWS_REGION
})

const LOG_GROUP = process.env.CLOUDWATCH_LOG_GROUP || "/app/custom-logs"

export async function logEvent(
  streamName: string,
  message: string,
  level: "INFO" | "WARN" | "ERROR" = "INFO"
) {
  const logEntry = JSON.stringify({
    level,
    message,
    timestamp: new Date().toISOString(),
    service: "my-app"
  })

  const command = new PutLogEventsCommand({
    logGroupName: LOG_GROUP,
    logStreamName: streamName,
    logEvents: [
      {
        timestamp: Date.now(),
        message: logEntry
      }
    ]
  })

  await client.send(command)
}

// Usage
await logEvent("api-requests", "User signed up", "INFO")
await logEvent("errors", "Payment failed: insufficient funds", "ERROR")

Try the Demo

Check out the live CloudWatch demo to send custom log entries and see them appear in the AWS Console.

CloudWatch Pricing

Tiered & Region-Specific Pricing

CloudWatch uses volume tiered pricing (starting at $0.50/GB, tiers down to $0.05/GB for high volumes). Prices vary by region. Always verify at aws.amazon.com/cloudwatch/pricing. Last verified: January 2026.
ComponentCost
Log ingestion$0.50 per GB
Log storage$0.03 per GB/month
Logs Insights queries$0.005 per GB scanned
Metrics (first 10 custom)Free
Alarms (first 10)Free

Log Volume Warning

High-traffic applications can generate significant log volume. Set log retention policies (7, 14, 30 days) to control costs. Avoid logging sensitive data or large request/response bodies.

AWS Deployment Guide — Built with Next.js