Introdução: Por que o logging é necessário em TypeScript?
Logging não é apenas registrar mensagens no console. Em aplicações TypeScript modernas (server-side em Node.js, client-side em React/Angular ou projetos full-stack), o logging se torna uma ferramenta crítica para depuração, monitoramento e análise de desempenho. Sem um logging de qualidade, desenvolvedores perdem horas reproduzindo erros, e engenheiros DevOps não conseguem identificar rapidamente a causa de uma falha em produção.
TypeScript, como uma extensão do JavaScript, adiciona tipagem estática, o que permite criar sistemas de logging mais confiáveis e previsíveis. Neste artigo, abordaremos as melhores práticas que ajudarão você a organizar um logging eficiente em projetos TypeScript.
Princípios básicos de logging
Níveis de logging
O uso correto dos níveis de logging é a base de qualquer sistema de monitoramento. Em TypeScript, é comum usar os seguintes níveis (em ordem crescente de importância):
debug— informações detalhadas de depuração (apenas para desenvolvimento);info— mensagens informativas padrão (inicialização do servidor, requisições);warn— avisos (problemas não críticos);error— erros que exigem atenção;fatal— erros críticos que causam a parada da aplicação.
Exemplo de configuração de níveis usando a biblioteca Winston:
import winston from 'winston';
const logger = winston.createLogger({ level: process.env.NODE_ENV === 'production' ? 'info' : 'debug', format: winston.format.json(), transports: [ new winston.transports.Console(), new winston.transports.File({ filename: 'error.log', level: 'error' }), ],});
logger.info('Servidor iniciado na porta 3000');logger.warn('Memória próxima do limite');logger.error('Erro de conexão com o BD');Logs estruturados
Evite mensagens de texto simples. Use logs estruturados com informações contextuais (formato JSON). Isso simplifica a busca e análise em sistemas como ELK ou Grafana.
// Ruimlogger.info(`Usuário ${userId} executou a ação ${action}`);
// Bomlogger.info('Ação do usuário', { userId: userId, action: action, timestamp: new Date().toISOString(), ip: request.ip,});Essa abordagem permite filtrar logs por campos e criar gráficos.
Melhores práticas para TypeScript
Uso de TypeScript para tipagem de logs
TypeScript permite definir interfaces para o contexto dos logs, prevenindo erros acidentais nos nomes dos campos:
interface LogContext { userId: string; action: string; durationMs: number; success: boolean;}
function logUserAction(context: LogContext): void { logger.info('User action', context);}
// O compilador verificará se todos os campos foram passados corretamentelogUserAction({ userId: '123', action: 'login', durationMs: 150, success: true,});Evite logar dados sensíveis
Nunca registre senhas, tokens, números de cartão de crédito ou dados pessoais (GDPR). Use utilitários para mascaramento:
function sanitizeLogData(data: Record<string, unknown>): Record<string, unknown> { const sensitiveFields = ['password', 'token', 'ssn']; const sanitized = { ...data }; for (const field of sensitiveFields) { if (sanitized[field]) { sanitized[field] = '***'; } } return sanitized;}
logger.info('Registro de usuário', sanitizeLogData(userData));Logging assíncrono e desempenho
Em aplicações de alta carga, o logging síncrono pode reduzir a performance. Use transportes assíncronos (por exemplo, winston suporta buffering).