Agent skill
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.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/examples-thamjiahe-claude-prompt-engine-11
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
// ✅ 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
// 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
// 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
# 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
// 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
npm install @sentry/nextjs
Configure
// 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
// 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
// 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 putMetric('DatabaseQueryTime', 45, 'Milliseconds');
Alert Configuration
CloudWatch Alarms
// lib/alarms.ts
import { CloudWatchClient, PutMetricAlarmCommand } from '@aws-sdk/client-cloudwatch';
const client = new CloudWatchClient({ region: 'us-east-1' });
export async function createErrorCountAlarm() {
const command = new PutMetricAlarmCommand({
AlarmName: 'ApplicationErrors',
MetricName: 'Errors',
Namespace: 'MyApp',
Statistic: 'Sum',
Period: 300, // 5 minutes
EvaluationPeriods: 1,
Threshold: 10, // Alert if > 10 errors
ComparisonOperator: 'GreaterThanThreshold',
AlarmActions: [
'arn:aws:sns:us-east-1:123456789012:AlertTopic'
]
});
await client.send(command);
}
// ✅ GOOD: Multiple metrics
PutMetricAlarmCommand({
AlarmName: 'HighErrorRate',
Metrics: [
{
Id: 'error_rate',
Expression: '(errors / requests) * 100',
ReturnData: true
},
{
Id: 'errors',
MetricStat: {
Metric: { MetricName: 'Errors', Namespace: 'MyApp' },
Stat: 'Sum',
Period: 300
}
},
{
Id: 'requests',
MetricStat: {
Metric: { MetricName: 'Requests', Namespace: 'MyApp' },
Stat: 'Sum',
Period: 300
}
}
],
Threshold: 5, // Alert if error rate > 5%
ComparisonOperator: 'GreaterThanThreshold'
});
Dashboards
CloudWatch Dashboard
// lib/dashboard.ts
import { CloudWatchClient, PutDashboardCommand } from '@aws-sdk/client-cloudwatch';
const client = new CloudWatchClient({ region: 'us-east-1' });
export async function createDashboard() {
const command = new PutDashboardCommand({
DashboardName: 'MyAppDashboard',
DashboardBody: JSON.stringify({
widgets: [
{
type: 'metric',
properties: {
metrics: [
['MyApp', 'Requests', { stat: 'Sum' }],
['MyApp', 'Errors', { stat: 'Sum' }],
['MyApp', 'Latency', { stat: 'Average' }]
],
period: 300,
stat: 'Average',
region: 'us-east-1',
title: 'Application Metrics'
}
},
{
type: 'log',
properties: {
query: 'fields @timestamp, @message | filter @message like /ERROR/',
region: 'us-east-1',
title: 'Recent Errors'
}
}
]
})
});
await client.send(command);
}
Distributed Tracing
OpenTelemetry
// lib/tracing.ts
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { AWSXRayIdGenerator } from '@opentelemetry/id-generator-aws-xray';
import { AWSXRayPropagator } from '@opentelemetry/aws-xray-propagator';
const sdk = new NodeSDK({
idGenerator: new AWSXRayIdGenerator(),
instrumentations: [getNodeAutoInstrumentations()],
traceExporter: new AWSXRayExporter({})
});
sdk.start();
process.on('SIGTERM', () => {
sdk
.shutdown()
.then(() => process.exit(0))
.catch((err) => {
console.error('Error shutting down tracing:', err);
process.exit(1);
});
});
export default sdk;
Log Retention
Set Retention Policy
import { CloudWatchLogsClient, PutRetentionPolicyCommand } from '@aws-sdk/client-cloudwatch-logs';
const client = new CloudWatchLogsClient({ region: 'us-east-1' });
export async function setLogRetention(logGroup: string, days: number) {
const command = new PutRetentionPolicyCommand({
logGroupName: logGroup,
retentionInDays: days
});
await client.send(command);
}
// Usage: Keep logs for 30 days
await setLogRetention('/aws/nodejs/myapp', 30);
Anti-Patterns
// ❌ BAD: No structured logging
console.log('User created');
console.error('Something went wrong');
// ✅ GOOD: Structured with context
logger.info('User created', { userId: user.id, email: user.email });
logger.error('Database failed', error, { host: 'db.example.com' });
// ❌ BAD: No error tracking
try {
riskyOperation();
} catch (error) {
console.error(error); // Lost!
}
// ✅ GOOD: Error tracking
try {
riskyOperation();
} catch (error) {
Sentry.captureException(error);
}
// ❌ BAD: No correlation IDs
// Impossible to trace requests
// ✅ GOOD: Correlation IDs
const requestId = crypto.randomUUID();
logger.info('Request started', { requestId });
Verification Before Production
- Structured logging implemented
- CloudWatch integrated
- Sentry configured for error tracking
- Alarms set up for critical metrics
- Dashboard created
- Log retention policy set
- Request correlation IDs used
- Sensitive data filtered from logs
- Metrics collected for key operations
- Alert channels configured (email, Slack)
Integration with Project Standards
Enforces observability:
- Quick error detection
- Production debugging capability
- Performance monitoring
- SLA compliance
Resources
- CloudWatch Docs: https://docs.aws.amazon.com/cloudwatch
- Sentry: https://sentry.io
- OpenTelemetry: https://opentelemetry.io
- Winston Logger: https://github.com/winstonjs/winston
Last Updated: January 24, 2026 Compatibility: Claude Opus 4.5, Claude Code v2.x Status: Production Ready
January 2026 Update: This skill is compatible with Claude Opus 4.5 and Claude Code v2.x. For complex tasks, use the
effort: highparameter for thorough analysis.
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?