Por que seu código JavaScript está pedindo socorro e você não ouve?
\n\nImagine: você lançou uma aplicação web incrível. Os usuários entram, clicam, tudo funciona… ou não? Na verdade, em algum lugar nos bastidores do navegador, um erro cai silenciosamente: Uncaught TypeError: Cannot read property 'length' of undefined. O usuário simplesmente fecha a aba e vai para a concorrência, e você nem fica sabendo que algo deu errado.
Bem-vindo à realidade do desenvolvimento frontend. Sem monitoramento e registro de logs de aplicações JavaScript, você está trabalhando no escuro. Mas não se desespere — hoje vamos analisar como transformar o caos dos erros em um sistema organizado de notificações. Você aprenderá como registrar eventos corretamente, monitorar o desempenho e não se afogar em um mar de dados.
\n\nEste artigo é seu guia de sobrevivência em produção. Vamos nessa!
\n\nConsole.log — seu amigo ou inimigo?
\n\nVamos começar pelo básico. console.log() é a primeira coisa que vem à mente de todo desenvolvedor. E isso é normal. Mas se você o usa em código de produção, pare. Por quê? Porque:
- \n
- Ele polui o console do usuário (sim, alguns o abrem). \n
- Afeta o desempenho com um grande número de chamadas. \n
- Não fornece informações estruturadas. \n
É melhor usar níveis de registro de logs. Aqui está um exemplo da abordagem correta:
\n\n// Ruim\nconsole.log('User clicked button');\n\n// Bom\nconsole.info('User interaction', { \n action: 'click', \n element: '#submit-btn', \n timestamp: Date.now() \n});\n\n// Para erros\nconsole.error('API request failed', { \n status: 500, \n endpoint: '/api/users' \n});\n\n// Para avisos\nconsole.warn('Deprecated method used', { \n method: 'fetchData_v1' \n});\n\nMas mesmo isso é apenas a ponta do iceberg. O verdadeiro monitoramento de aplicações JavaScript começa onde o console não está disponível.
\n\nRegistro de logs estruturado: JSON ao seu dispor
\n\nQuando sua aplicação cresce, as mensagens caóticas no console viram uma bagunça. A solução é o registro de logs estruturado. Envie os dados em formato JSON para que possam ser analisados e processados.
\n\nVeja como fazer um logger simples:
\n\nclass 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 // Em produção, enviamos para o servidor\n if (process.env.NODE_ENV === 'production') {\n this.sendToServer(logEntry);\n } else {\n // Em desenvolvimento, exibimos no console\n console[level](`[${level.toUpperCase()}] ${message}`, data);\n }\n }\n\n sendToServer(entry) {\n // Usamos sendBeacon para garantir o envio\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// Uso\nconst logger = new Logger({ appVersion: '1.2.3', userId: getUserId() });\nlogger.info('Page loaded', { url: window.location.href, loadTime: performance.now() });\n\nObserve o navigator.sendBeacon() — é a melhor forma de enviar dados antes do usuário sair da página. Requisições fetch comuns podem ser canceladas.
Captura de erros: try/catch é só o começo
\n\nErros globais são os mais traiçoeiros. Eles podem ocorrer em qualquer lugar e são fáceis de passar despercebidos. Veja como configurar o monitoramento total de erros JavaScript:
\n\nManipulador global de erros
\n\n// Capturamos erros não tratados\nw