Logs, Errors, and Crashes: How to Know When Your App Is Broken
Your App Is Broken. Do You Even Know?
Picture this: You've just shipped your latest AI-assisted masterpiece. The deployment went smooth, your CI/CD pipeline is humming, and you're already planning your next feature. Then your phone starts buzzing with angry user messages. Your app has been throwing 500 errors for the past hour.
Welcome to every developer's nightmare - the silent failure.
The harsh truth? Your app is probably breaking right now, and you have no idea. Without proper monitoring, logging, and error tracking, you're flying blind. Let's fix that.
The Three Pillars of Not Being Clueless
1. Logging: Your App's Diary
Logs are like your app's diary - they tell you everything that happened, when it happened, and hopefully why. But most developers treat logging like that gym membership they never use.
// Bad: Silent failure
const result = await api.fetchUserData(userId);
if (!result) {
return null;
}
// Good: Proper logging
const result = await api.fetchUserData(userId);
if (!result) {
console.error(`Failed to fetch user data for userId: ${userId}`, {
timestamp: new Date().toISOString(),
endpoint: '/api/users',
userId
});
return null;
}
Log levels matter. Use them strategically:
- ERROR: Something broke that users will notice
- WARN: Something's fishy but not broken yet
- INFO: Important business events (user signup, payment)
- DEBUG: Developer breadcrumbs for troubleshooting
2. Error Tracking: Catching What Breaks
Error tracking goes beyond basic logging. It aggregates, categorizes, and prioritizes your failures. Tools like Sentry, Rollbar, or Bugsnag don't just tell you something broke - they tell you how often, which users are affected, and give you the stack trace to fix it.
# Python with Sentry integration
import sentry_sdk
sentry_sdk.init(dsn="your-dsn-here")
try:
risky_operation()
except Exception as e:
sentry_sdk.capture_exception(e)
logger.error(f"Operation failed: {e}")
raise
The magic happens when you add context:
// JavaScript error with context
try {
await processPayment(amount, userId);
} catch (error) {
Sentry.setContext('payment', {
amount,
userId,
paymentMethod: 'stripe'
});
Sentry.captureException(error);
throw error;
}
3. Health Checks: Your App's Pulse
Health checks are like taking your app's pulse. They proactively tell you if critical systems are working before users start complaining.
// Simple health check endpoint
app.get('/health', async (req, res) => {
const checks = {
database: await checkDatabase(),
redis: await checkRedis(),
external_api: await checkExternalAPI(),
disk_space: await checkDiskSpace()
};
const allHealthy = Object.values(checks).every(check => check.healthy);
res.status(allHealthy ? 200 : 503).json({
status: allHealthy ? 'healthy' : 'unhealthy',
checks,
timestamp: new Date().toISOString()
});
});
Monitoring That Actually Matters
Application Metrics
Don't just monitor if your app is up - monitor if it's working well:
- Response times: Are requests getting slower?
- Error rates: What percentage of requests are failing?
- Throughput: How many requests per second are you handling?
- Database query performance: Which queries are killing your performance?
Business Metrics
Technical metrics are great, but business metrics tell you what really matters:
- User signups per hour
- Payment processing success rate
- Feature adoption rates
- User session duration
// Custom metric tracking
const trackBusinessMetric = (event, data) => {
// Send to your analytics service
analytics.track(event, {
...data,
timestamp: Date.now(),
environment: process.env.NODE_ENV
});
// Also log for debugging
console.info(`Business metric: ${event}`, data);
};
// Usage
trackBusinessMetric('user_signup', {
userId: user.id,
plan: 'premium',
source: 'organic'
});
Setting Up Alerts That Don't Suck
The Art of Alert Tuning
Poor alerting is worse than no alerting. You either get alert fatigue (ignoring everything) or miss critical issues because they're buried in noise.
Good alerts are:
- Actionable: You can do something about it
- Relevant: It affects users or business
- Urgent: It needs immediate attention
# Example alert configuration
alerts:
- name: "High Error Rate"
condition: "error_rate > 5% for 5 minutes"
severity: "critical"
channels: ["slack", "pagerduty"]
- name: "Slow Response Time"
condition: "p95_response_time > 2s for 10 minutes"
severity: "warning"
channels: ["slack"]
- name: "Database Connection Issues"
condition: "db_connection_errors > 0"
severity: "critical"
channels: ["slack", "pagerduty", "sms"]
Alert Fatigue Is Real
Too many alerts = ignored alerts. Start conservative:
- Begin with critical alerts only (site down, payment failures)
- Add warning alerts gradually as you understand your app's behavior
- Review and tune regularly - what seemed important might not be
Debugging in Production: The Detective Work
When things go wrong (not if, when), you need to become a detective. Here's your toolkit:
Correlation IDs
Trace requests across services with correlation IDs:
// Generate correlation ID for each request
app.use((req, res, next) => {
req.correlationId = req.headers['x-correlation-id'] ||
Math.random().toString(36).substring(7);
res.setHeader('X-Correlation-ID', req.correlationId);
next();
});
// Use in all logs
const logWithCorrelation = (level, message, data = {}) => {
console[level](message, {
...data,
correlationId: req.correlationId,
timestamp: new Date().toISOString()
});
};
Structured Logging
JSON logs are searchable logs:
// Instead of this:
console.log(`User ${userId} failed to login with email ${email}`);
// Do this:
console.log(JSON.stringify({
event: 'login_failed',
userId,
email,
timestamp: new Date().toISOString(),
ip: req.ip,
userAgent: req.headers['user-agent']
}));
The Monitoring Stack for Vibe Coders
You don't need enterprise-grade complexity. Here's a solid, affordable stack:
Free Tier Heroes
- Logs: Start with your hosting provider's built-in logs
- Errors: Sentry (generous free tier)
- Uptime: UptimeRobot or Pingdom
- Metrics: Grafana Cloud free tier
Stepping Up
- APM: New Relic, Datadog, or Honeycomb
- Log aggregation: LogDNA, Papertrail, or Logtail
- Infrastructure monitoring: Prometheus + Grafana
Making It Stick: Monitoring Culture
Start Small, Scale Smart
- Week 1: Basic error tracking and uptime monitoring
- Week 2: Add application metrics (response time, error rate)
- Week 3: Set up business metrics tracking
- Week 4: Fine-tune alerts and add debugging tools
The Monitoring Checklist
Before you ship your next feature:
- Are errors properly tracked and logged?
- Do you have health checks for critical dependencies?
- Can you trace a request from start to finish?
- Will you know if this feature breaks?
- Are success/failure metrics tracked?
The Bottom Line
Your app will break. That's not a maybe - it's a guarantee. The question is: will you find out from monitoring dashboards or angry users?
Good monitoring isn't about having the most sophisticated setup - it's about having the right information when you need it. Start simple, be consistent, and iterate based on what you learn.
Remember: An app without monitoring is like driving with your eyes closed. You might be going fast, but you have no idea where you're headed or what you're about to hit.
Time to open your eyes and start monitoring like you mean it.
Alex Hackney
DeployMyVibe