Monitoring & Logging
Implement CloudWatch monitoring, error tracking with Sentry, structured logging, and alert configuration. Apply when setting up monitoring, tracking errors, debugging production issues, or configuring dashboards.
git clone --depth 1 https://github.com/ThamJiaHe/claude-code-handbook /tmp/monitoring-logging && cp -r /tmp/monitoring-logging/skills/examples/monitoring-logging- ~/.claude/skills/monitoring-loggingmonitoring-logging-skill.md
# Monitoring & Logging
Systematic monitoring, logging, and alerting for production applications.
## Overview
This Skill enforces:
- Structured logging (JSON format)
- CloudWatch integration
- Error tracking with Sentry
- Distributed tracing
- Alert configuration
- Dashboard setup
- Log aggregation
- Metrics collection
Apply when setting up monitoring, tracking errors, or debugging production issues.
## Structured Logging
### JSON Logging Format
```ts
// ✅ GOOD: Structured logs with context
const logger = {
info: (message: string, context?: Record<string, any>) => {
console.log(JSON.stringify({
timestamp: new Date().toISOString(),
level: 'info',
message,
requestId: context?.requestId,
userId: context?.userId,
duration: context?.duration,
...context
}));
},
error: (message: string, error?: Error, context?: Record<string, any>) => {
console.error(JSON.stringify({
timestamp: new Date().toISOString(),
level: 'error',
message,
errorName: error?.name,
errorMessage: error?.message,
errorStack: error?.stack,
requestId: context?.requestId,
...context
}));
},
warn: (message: string, context?: Record<string, any>) => {
console.warn(JSON.stringify({
timestamp: new Date().toISOString(),
level: 'warn',
message,
requestId: context?.requestId,
...context
}));
}
};
// Usage
logger.info('User created', { userId: user.id, email: user.email });
logger.error('Database connection failed', error, {
host: 'db.example.com',
port: 5432
});
```
### Middleware for Request Logging
```ts
// middleware/logging.ts
import { NextRequest, NextResponse } from 'next/server';
export function middleware(request: NextRequest) {
const requestId = crypto.randomUUID();
const start = Date.now();
const response = NextResponse.next();
response.headers.set('x-request-id', requestId);
// Log after response
const duration = Date.now() - start;
console.log(JSON.stringify({
timestamp: new Date().toISOString(),
level: 'info',
message: 'HTTP Request',
requestId,
method: request.method,
path: request.nextUrl.pathname,
status: response.status,
duration,
userAgent: request.headers.get('user-agent')
}));
return response;
}
```
## CloudWatch Integration
### AWS SDK Logging
```ts
// lib/cloudwatch.ts
import { CloudWatchLogsClient, PutLogEventsCommand } from '@aws-sdk/client-cloudwatch-logs';
const client = new CloudWatchLogsClient({ region: 'us-east-1' });
export async function logToCloudWatch(
logGroup: string,
logStream: string,
message: string
) {
const command = new PutLogEventsCommand({
logGroupName: logGroup,
logStreamName: logStream,
logEvents: [
{
message: JSON.stringify({
timestamp: new Date().toISOString(),
message
}),
timestamp: Date.now()
}
]
});
try {
await client.send(command);
} catch (error) {
console.error('Failed to log to CloudWatch:', error);
}
}
```
### Log Agent Setup
```bash
# Install CloudWatch Logs agent
sudo apt install awslogs -y
# Configure /etc/awslogs/awslogs.conf
[/var/log/nodejs/app.log]
log_group_name = /aws/nodejs/myapp
log_stream_name = {instance_id}
file = /var/log/nodejs/app.log
datetime_format = %Y-%m-%d %H:%M:%S
# Restart agent
sudo systemctl restart awslogsd
```
## Structured Logging in Code
```ts
// lib/logger.ts
import winston from 'winston';
const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
),
defaultMeta: {
service: 'myapp',
environment: process.env.NODE_ENV
},
transports: [
new winston.transports.Console(),
new winston.transports.File({
filename: 'logs/error.log',
level: 'error'
}),
new winston.transports.File({
filename: 'logs/combined.log'
})
]
});
export default logger;
// Usage
logger.info('User logged in', { userId: user.id });
logger.error('Database error', { error: err.message });
```
## Error Tracking with Sentry
### Setup Sentry
```bash
npm install @sentry/nextjs
```
### Configure
```ts
// sentry.client.config.ts
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 0.1, // 10% of transactions
beforeSend(event) {
// Filter out certain errors
if (event.exception) {
const error = event.exception.values?.[0];
if (error?.value?.includes('ResizeObserver')) {
return null; // Don't send
}
}
return event;
}
});
```
### Capture Errors
```ts
// Manual error capture
try {
riskyOperation();
} catch (error) {
Sentry.captureException(error, {
tags: {
section: 'user-profile'
},
contexts: {
user: {
userId: user.id,
email: user.email
}
}
});
}
// Automatic error capture
Sentry.withScope((scope) => {
scope.setContext('user', { userId: user.id });
Sentry.captureMessage('User action completed');
});
```
## Metrics Collection
### Custom Metrics
```ts
// lib/metrics.ts
import { CloudWatchClient, PutMetricDataCommand } from '@aws-sdk/client-cloudwatch';
const client = new CloudWatchClient({ region: 'us-east-1' });
export async function putMetric(
metricName: string,
value: number,
unit: 'Count' | 'Seconds' | 'Milliseconds' = 'Count'
) {
const command = new PutMetricDataCommand({
Namespace: 'MyApp',
MetricData: [
{
MetricName: metricName,
Value: value,
Unit: unit,
Timestamp: new Date()
}
]
});
try {
await client.send(command);
} catch (error) {
console.error('Failed to put metric:', error);
}
}
// Usage
await putMetric('UserCreated', 1, 'Count');
await putMeBuild REST APIs with proper error handling, status codes, request validation, response formatting, and rate limiting. Apply when creating API routes, handling errors, validating input, or designing API responses.
Harden REST and GraphQL APIs against common attack vectors. Apply when building API endpoints, implementing authentication, handling file uploads, or exposing APIs to external consumers.
Deploy Node.js applications on AWS using EC2, RDS, and managed services with security best practices. Apply when setting up AWS infrastructure, configuring databases, managing security, or optimizing costs.
Rapidly fix build failures, type errors, and lint issues with minimal diffs. Apply when builds fail, TypeScript reports errors, or CI/CD pipelines break. Focuses on getting the build green fast.
STRIDE-based threat modeling for application architecture. Apply when designing new systems, reviewing architecture, or assessing security posture of existing applications.
Production-ready Docker patterns for multi-stage builds, security hardening, and orchestration. Apply when creating Dockerfiles, docker-compose configs, or deploying containerized applications.
Enforces Conventional Commits, PR standards, merge conflict resolution, and branch management. Apply when committing code, opening PRs, resolving conflicts, managing branches, or handling Git operations.
Deploy Node.js applications on Google Cloud with Cloud Run, Cloud Firestore, and Google APIs. Implement OAuth2 authentication and manage service accounts. Apply when building serverless applications, integrating Google services, or deploying to GCP.