| name | devops-log-analyzer |
| description | Log analysis and debugging skill. Use when the user says 'analyze logs', 'debug logs', 'find errors in logs', 'log patterns', 'parse logs', 'what went wrong', 'error investigation', or discusses log analysis, incident investigation, error pattern detection, or debugging from log output. |
| argument-hint | [docker|kubernetes|cloudwatch|file-path] |
Log Analysis & Debugging
You are an expert in log analysis, incident investigation, and root cause analysis. Analyze logs systematically to identify errors, patterns, and root causes with actionable recommendations.
Phase 1: Find Log Sources
Reference: references/log-formats.md for parsing JSON, logfmt, Apache/Nginx, and common framework log formats.
Identify where logs are located based on the project context:
Application Logs
- stdout/stderr: Check if the application logs to console
- Node.js:
console.log, console.error, or structured logger output
- Python:
logging module, print statements
- Go:
log package, slog, or structured logger
- File-based logs:
/var/log/ directory (syslog, auth.log, application-specific)
- Application-configured log paths (check config files)
- PM2 logs:
~/.pm2/logs/ or pm2 logs
- Nginx/Apache:
/var/log/nginx/, /var/log/apache2/
- Systemd journal:
journalctl -u service-name
Docker Logs
- Single container:
docker logs <container> --tail 1000 --timestamps
- Compose stack:
docker compose logs --tail 500 --timestamps
- Specific service:
docker compose logs <service> --since 1h
- Check log driver configuration (json-file, syslog, fluentd)
Kubernetes Logs
- Pod logs:
kubectl logs <pod> -n <namespace> --tail=1000
- Previous container:
kubectl logs <pod> --previous (for crash loops)
- All pods in deployment:
kubectl logs -l app=<name> --all-containers
- Init container logs:
kubectl logs <pod> -c <init-container>
- Events:
kubectl get events --sort-by='.lastTimestamp'
- Node-level:
kubectl describe node <node> for resource pressure
Cloud Provider Logs
- AWS CloudWatch: Log groups, log streams, filter patterns
- GCP Cloud Logging:
gcloud logging read with filters
- Azure Monitor: Log Analytics workspace queries
CI/CD Logs
- GitHub Actions: Check workflow run logs via
gh run view
- GitLab CI: Pipeline job logs
- Jenkins: Build console output
- Check for artifact-uploaded log files
Phase 2: Ask the User
Determine what the user is investigating:
-
What are you looking for?
- Errors and exceptions (application crashes, unhandled errors)
- Performance issues (slow requests, timeouts, high latency)
- Specific user/request tracing (follow a request through services)
- Pattern analysis (recurring issues, frequency trends)
- Timeline reconstruction (what happened at a specific time)
- Security events (auth failures, suspicious activity)
- Resource issues (OOM, disk full, connection limits)
-
Time range: When did the issue occur?
- Last N minutes/hours
- Specific time window
- Since a deployment
- Ongoing
-
Scope:
- Single service or multiple services?
- Specific environment (dev, staging, production)?
- Specific user, request ID, or session?
Phase 3: Analysis Strategies
Strategy 1: Error Frequency Analysis
Systematic approach to understanding error landscape:
- Extract all errors: Filter for ERROR, FATAL, Exception, Error, panic, CRITICAL
- Normalize error messages: Strip variable parts (IDs, timestamps, paths) to group similar errors
- Count and rank: Group by normalized message, sort by frequency
- Time bucketing: Count errors per time bucket (1min, 5min, 1hr) to detect spikes
- Categorize:
- Application errors (business logic, validation)
- Infrastructure errors (connection, timeout, resource)
- Third-party errors (external API, service dependency)
Output as a ranked table:
| # | Error Pattern | Count | First Seen | Last Seen | Example |
|---|---------------------------|-------|------------|-----------|---------|
| 1 | Connection refused :5432 | 342 | 10:05:23 | 10:47:12 | full msg|
| 2 | NullPointerException at X | 89 | 09:30:00 | 10:50:00 | full msg|
Strategy 2: Timeline Analysis
Reconstruct the sequence of events around an incident:
- Anchor event: Identify the primary failure (first error, alert trigger, user report)
- Look backward: What happened in the 5-30 minutes before?
- Deployments or config changes
- Resource usage trends (gradual memory increase)
- Warning-level logs
- External dependency changes
- Look forward: What cascaded after the initial failure?
- Secondary errors triggered by the primary
- Retry storms
- Circuit breaker activations
- Auto-scaling events
- Construct timeline:
10:00:00 - Deploy v2.3.1 started
10:02:15 - Health check passed, traffic shifted
10:05:23 - First connection refused error to database
10:05:24 - Error rate spike: 0.1% -> 15%
10:06:00 - Circuit breaker opened for db-service
10:06:30 - Alerts fired: high-error-rate, db-connection-failure
10:10:00 - Rollback initiated
10:12:00 - Error rate returned to baseline
Strategy 3: Pattern Detection
Find recurring issues and trends:
- Periodic patterns: Do errors occur at regular intervals?
- Cron jobs failing (check for patterns at :00, :15, :30, :45)
- Connection pool exhaustion during peak hours
- Memory leaks causing periodic restarts
- Correlated patterns: Do errors appear together?
- Error A always follows Error B within 5 seconds
- Latency spike correlates with CPU spike
- Error rate correlates with request rate
- Gradual degradation:
- Slowly increasing response times
- Growing error count over days
- Memory usage trending upward between restarts
Strategy 3b: Distributed Trace Correlation
When debugging issues across multiple services, trace IDs are the key to reconstructing the full request journey.
Finding Trace IDs in Logs
Trace IDs appear in logs under various formats depending on the framework and infrastructure:
grep -oE 'trace_id=([a-f0-9-]+)' logs.txt
grep -oE 'x-request-id:\s*([a-f0-9-]+)' logs.txt
grep -oE 'X-Amzn-Trace-Id:\s*Root=[^\s;]+' logs.txt
grep -oE 'traceId["\s:=]+([a-f0-9]+)' logs.txt
grep -oE 'dd\.trace_id=([0-9]+)' logs.txt
grep -oE 'uber-trace-id:\s*([a-f0-9]+)' logs.txt
Cross-Service Request Flow Reconstruction
Once you have a trace ID, search across all service logs to build the full request flow:
grep "abc123" api-gateway.log order-service.log payment-service.log notification-service.log
kubectl logs -l app.kubernetes.io/part-of=myapp --all-containers -n production | grep "abc123"
docker compose logs | grep "abc123"
Reconstruct the flow as a timeline showing service hops, durations, and outcomes:
Request Flow (trace: abc123)
─────────────────────────────
10:23:01.001 api-gateway → POST /api/orders (200ms)
10:23:01.050 order-service → Validate order (30ms)
10:23:01.080 payment-service → Charge card (150ms)
10:23:01.230 order-service → Save to DB (20ms)
10:23:01.250 notification → Send email (async)
This visualization immediately reveals which service introduced latency or where a failure occurred in the chain.
Correlating Across Log Platforms
In real-world systems, logs for a single request are often spread across multiple platforms:
-
CloudWatch + Application Logs: Use the trace ID to query CloudWatch Log Insights:
fields @timestamp, @message
| filter @message like /abc123/
| sort @timestamp asc
-
kubectl logs + CloudWatch: Extract the trace from pod logs, then search CloudWatch for the same trace to find ALB or API Gateway entries:
kubectl logs deploy/order-service -n prod | grep "trace_id" | head -5
aws logs filter-log-events --log-group-name /aws/alb/myapp \
--filter-pattern '"abc123"'
-
Multi-service correlation: When services use different log formats, normalize timestamps to UTC and sort all entries together:
cat api-gateway.log order-service.log payment-service.log \
| grep "abc123" \
| sort -t' ' -k1,2
If no trace ID exists in the logs, fall back to correlating by timestamp windows and matching request parameters (IP, user ID, endpoint path).
Strategy 4: Request Correlation
Trace a specific request across services:
- Find the correlation ID: Request ID, trace ID, session ID
- Search all services for that ID
- Order by timestamp to see the request flow
- Identify where it failed: Which service, which step
- Check context: What was the request payload, headers, user state
Strategy 5: Rate Analysis
Detect anomalies in error rates and performance:
- Baseline: What is the normal error rate / latency?
- Detect spikes: When did metrics deviate from baseline?
- Correlate with events: What changed at that time?
- Deployment
- Traffic spike
- External dependency issue
- Infrastructure change
- Quantify impact: How many users/requests were affected?
Phase 4: Smart Grep Patterns
Reference: references/grep-patterns.md for the full catalog of ready-to-use grep/ripgrep patterns by error class.
Use these patterns to quickly find common issues:
Out of Memory
grep -iE "Killed process|OutOfMemoryError|JavaScript heap out of memory|ENOMEM|oom-killer|Cannot allocate memory|MemoryError|fatal error: runtime: out of memory" logs.txt
Connection Issues
grep -iE "ECONNREFUSED|ETIMEDOUT|ECONNRESET|EHOSTUNREACH|Connection refused|Connection timed out|Connection reset by peer|broken pipe|no route to host" logs.txt
Authentication & Authorization
grep -iE "401|403|Unauthorized|Forbidden|token expired|invalid token|authentication failed|access denied|permission denied|InvalidSignatureException" logs.txt
Database Issues
grep -iE "deadlock|lock wait timeout|too many connections|connection pool|SQLSTATE|duplicate key|foreign key constraint|relation .* does not exist|ER_LOCK_DEADLOCK|FATAL:.*database" logs.txt
Crash & Fatal Errors
grep -iE "FATAL|panic:|segfault|Segmentation fault|SIGSEGV|SIGABRT|unhandled rejection|uncaught exception|stack overflow|core dump" logs.txt
SSL/TLS Issues
grep -iE "SSL|TLS|certificate|CERT_|x509|handshake failure|ERR_CERT|SSL_ERROR|certificate has expired|self-signed" logs.txt
DNS Issues
grep -iE "ENOTFOUND|EAI_AGAIN|name resolution|DNS|getaddrinfo|could not resolve|NXDOMAIN|SERVFAIL" logs.txt
Disk Space
grep -iE "No space left on device|ENOSPC|disk full|filesystem.*full|write error.*space|IOError.*space" logs.txt
Rate Limiting
grep -iE "429|rate limit|too many requests|throttl|quota exceeded|RateLimitError|SlowDown" logs.txt
Timeout Patterns
grep -iE "timeout|timed out|ETIMEDOUT|deadline exceeded|context deadline|request timeout|gateway timeout|504|408" logs.txt
Phase 5: Output Format
Executive Summary
Provide a clear, concise summary:
## Incident Summary
**What happened**: Database connection pool exhausted due to connection leak in v2.3.1
**When**: 2024-01-15 10:05 - 10:12 UTC (7 minutes)
**Impact**: ~2,400 failed requests (15% error rate), affecting approximately 800 users
**Root cause**: New database query in /api/users endpoint was not releasing connections
**Resolution**: Rollback to v2.3.0 at 10:10, error rate normalized by 10:12
**Status**: Resolved
Top Errors Table
## Top Errors (last 24h)
| Rank | Error | Count | % of Total | First Seen | Last Seen |
|------|------------------------------------|-------|------------|--------------------|--------------------|
| 1 | ECONNREFUSED 10.0.1.5:5432 | 342 | 45% | 2024-01-15 10:05 | 2024-01-15 10:12 |
| 2 | Query timeout after 30000ms | 156 | 20% | 2024-01-15 10:03 | 2024-01-15 10:12 |
| 3 | Connection pool exhausted | 98 | 13% | 2024-01-15 10:05 | 2024-01-15 10:11 |
Timeline of Events
## Event Timeline
10:00:00 [DEPLOY] v2.3.1 deployment started (commit abc123)
10:02:15 [DEPLOY] Health check passed, traffic shifted to new version
10:03:00 [WARN] Database query time increasing: p99 500ms -> 2s
10:05:23 [ERROR] First connection refused error to PostgreSQL
10:05:24 [ALERT] Error rate crossed 5% threshold
10:05:30 [ERROR] Connection pool exhausted (max: 20, active: 20, waiting: 47)
10:06:00 [SYSTEM] Circuit breaker opened for database connections
10:06:30 [ALERT] PagerDuty alert fired: high-error-rate
10:10:00 [ACTION] Rollback to v2.3.0 initiated
10:11:30 [DEPLOY] v2.3.0 serving all traffic
10:12:00 [CLEAR] Error rate returned to baseline (0.1%)
Root Cause Hypothesis
## Root Cause Analysis
**Primary cause**: Connection leak in the new /api/users endpoint added in v2.3.1.
The endpoint opens a database connection for each sub-query but does not release
it in the error path, causing connections to accumulate until the pool is exhausted.
**Evidence**:
1. Connection pool active count steadily increased after deploy (20 -> 20/20 in 3 min)
2. Error only occurs on the /api/users endpoint path
3. No connection release in the catch block (code review confirms)
4. Issue does not reproduce with v2.3.0
**Contributing factors**:
- No connection pool monitoring alert (would have caught earlier)
- Integration tests did not cover the error path for this endpoint
- Connection pool size (20) is low for production traffic
Recommended Fixes
## Recommendations
### Immediate (fix now)
1. Fix connection leak in /api/users error handler (add finally block)
2. Add connection pool metrics to monitoring dashboard
3. Alert on connection pool utilization > 80%
### Short-term (this sprint)
4. Add integration tests for database error paths
5. Increase connection pool size to 50 with proper timeout config
6. Add request-scoped database connection management (middleware)
### Long-term (next quarter)
7. Implement connection pooling with PgBouncer
8. Add distributed tracing for database query tracking
9. Implement automated canary analysis for deployments
Phase 6: Advanced Techniques
Log Aggregation Commands
When dealing with multiple log files or sources:
-
Merge and sort by timestamp:
- Combine logs from multiple services
- Sort chronologically for unified timeline
- Align timestamp formats before merging
-
Statistical analysis:
- Requests per second/minute calculation
- Error rate calculation (errors / total requests)
- Latency percentile calculation from access logs
- Unique error count over time
-
Diff analysis:
- Compare log patterns before and after an incident
- Compare log patterns between healthy and unhealthy instances
- Identify new error types that appeared after a change
Working with Large Log Files
- Use
tail -n and head -n for targeted reading
- Use
grep -c for counting before extracting
- Use time-range filters to narrow scope first
- Process in chunks if files are very large
- Suggest log rotation if files are excessively large
Safety Rules
- NEVER modify or delete log files during analysis
- NEVER expose sensitive data from logs (PII, tokens, passwords) in output
- ALWAYS redact sensitive information when sharing analysis results
- ALWAYS ask before running commands that could affect production systems
- When analyzing production logs, prefer read-only access methods
- Warn if log volume suggests a logging misconfiguration (debug logging in production)
- If logs contain evidence of a security breach, immediately flag it to the user
- NEVER ignore signs of data exfiltration, unauthorized access, or security compromise in logs