Catching Bugs on the Fly: Monitoring and Logging JavaScript Applications

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why Is Your JavaScript Code Crying for Help, and You Can't Hear It?

\n\n

Imagine: you've launched a cool web application. Users come in, click around, everything works... or does it? In reality, somewhere deep in the browser, an error silently occurs: Uncaught TypeError: Cannot read property 'length' of undefined. The user simply closes the tab and goes to your competitors, and you don't even know something went wrong.

\n\n

Welcome to the reality of frontend development. Without monitoring and logging JavaScript applications, you're working blind. But don't panic — today we'll break down how to turn the chaos of errors into a structured alert system. You'll learn how to properly log events, track performance, and not drown in a sea of data.

\n\n

This article is your survival guide for production. Let's go!

\n\n

Console.log — Your Friend or Foe?

\n\n

Let's start with the basics. console.log() is the first thing that comes to every developer's mind. And that's normal. But if you're using it in production code, stop. Why? Because:

\n\n
    \n
  • It clutters the user's console (yes, some people open it).
  • \n
  • It impacts performance with a large number of calls.
  • \n
  • It doesn't provide structured information.
  • \n
\n\n

It's better to use logging levels. Here's an example of the right approach:

\n\n
// Bad\nconsole.log('User clicked button');\n\n// Good\nconsole.info('User interaction', { \n    action: 'click', \n    element: '#submit-btn', \n    timestamp: Date.now() \n});\n\n// For errors\nconsole.error('API request failed', { \n    status: 500, \n    endpoint: '/api/users' \n});\n\n// For warnings\nconsole.warn('Deprecated method used', { \n    method: 'fetchData_v1' \n});
\n\n

But even this is just the tip of the iceberg. Real JavaScript application monitoring begins where the console is unavailable.

\n\n

Structured Logging: JSON to the Rescue

\n\n

When your application grows, chaotic console messages turn into a mess. The solution is structured logging. Send data in JSON format so it can be parsed and analyzed.

\n\n

Here's how to make a simple logger:

\n\n
class Logger {\n    constructor(context = {}) {\n        this.context = context;\n    }\n\n    log(level, message, data = {}) {\n        const logEntry = {\n            timestamp: new Date().toISOString(),\n            level,\n            message,\n            ...this.context,\n            ...data\n        };\n\n        // In production, send to server\n        if (process.env.NODE_ENV === 'production') {\n            this.sendToServer(logEntry);\n        } else {\n            // In development, output to console\n            console[level](`[${level.toUpperCase()}] ${message}`, data);\n        }\n    }\n\n    sendToServer(entry) {\n        // Use sendBeacon for guaranteed delivery\n        navigator.sendBeacon('/api/logs', JSON.stringify(entry));\n    }\n\n    info(message, data) { this.log('info', message, data); }\n    warn(message, data) { this.log('warn', message, data); }\n    error(message, data) { this.log('error', message, data); }\n}\n\n// Usage\nconst logger = new Logger({ appVersion: '1.2.3', userId: getUserId() });\nlogger.info('Page loaded', { url: window.location.href, loadTime: performance.now() });
\n\n

Note navigator.sendBeacon() — this is the best way to send data before the user leaves the page. Regular fetch requests can be cancelled.

\n\n

Error Catching: try/catch is Just the Beginning

\n\n

Global errors are the most insidious. They can occur anywhere and are easy to miss. Here's how to set up comprehensive JavaScript error monitoring:

\n\n

Global Error Handler

\n\n
// Catch unhandled errors
w                

Blogs

Book Recommendations