DevOps Fundamentals March 19, 2026 · 6 min read

Logs, Errors, and Crashes: How to Know When Your App Is Broken

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:

  1. Begin with critical alerts only (site down, payment failures)
  2. Add warning alerts gradually as you understand your app's behavior
  3. 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

  1. Week 1: Basic error tracking and uptime monitoring
  2. Week 2: Add application metrics (response time, error rate)
  3. Week 3: Set up business metrics tracking
  4. 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

Alex Hackney

DeployMyVibe

Ready to deploy?

Stop reading about it. Start shipping.

View Pricing