topsapp: estruturar suporte

Signed-off-by: Rodrigo B. de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
rodrigo committed 2025-08-08 21:48:26 -03:00
1 parent 723ad8c268
commit 8dc6c594c9
7 files changed
+1687 -104

No files matched your search

+173
View File
@@ -0,0 +1,173 @@
const fs = require('fs');
const path = require('path');
class Logger {
constructor() {
this.logDir = path.join(__dirname, '../../logs');
this.logFile = path.join(this.logDir, 'bot-debug.log');
this.maxLogSize = 10 * 1024 * 1024; // 10MB
this.maxBackups = 5;
// Criar diretório de logs se não existir
this.ensureLogDir();
// Só ativa logs se estiver em modo debug
this.isDebug = process.env.NODE_ENV === 'development' || process.env.DEBUG === 'true';
}
ensureLogDir() {
if (!fs.existsSync(this.logDir)) {
fs.mkdirSync(this.logDir, { recursive: true });
}
}
formatMessage(level, message, data = null) {
const timestamp = new Date().toISOString();
let logLine = `[${timestamp}] [${level}] ${message}`;
if (data) {
if (typeof data === 'object') {
logLine += '\n' + JSON.stringify(data, null, 2);
} else {
logLine += ` - ${data}`;
}
}
return logLine + '\n';
}
rotateLogIfNeeded() {
if (!fs.existsSync(this.logFile)) {
return;
}
const stats = fs.statSync(this.logFile);
if (stats.size > this.maxLogSize) {
// Fazer backup dos logs existentes
for (let i = this.maxBackups - 1; i >= 0; i--) {
const oldFile = i === 0 ? this.logFile : `${this.logFile}.${i}`;
const newFile = `${this.logFile}.${i + 1}`;
if (fs.existsSync(oldFile)) {
if (i === this.maxBackups - 1) {
fs.unlinkSync(oldFile); // Deletar o mais antigo
} else {
fs.renameSync(oldFile, newFile);
}
}
}
}
}
writeLog(level, message, data = null) {
if (!this.isDebug) {
return; // Só loga em modo debug
}
try {
this.rotateLogIfNeeded();
const logMessage = this.formatMessage(level, message, data);
// Escrever no arquivo de log
fs.appendFileSync(this.logFile, logMessage);
// Também mostrar no console se for erro ou warning
if (level === 'ERROR' || level === 'WARN') {
console.log(logMessage.trim());
}
} catch (error) {
console.error('Erro ao escrever log:', error);
}
}
debug(message, data = null) {
this.writeLog('DEBUG', message, data);
}
info(message, data = null) {
this.writeLog('INFO', message, data);
}
warn(message, data = null) {
this.writeLog('WARN', message, data);
}
error(message, data = null) {
this.writeLog('ERROR', message, data);
}
// Métodos específicos para o bot
botCommand(userId, command, data = null) {
this.debug(`Comando recebido - User: ${userId}, Command: ${command}`, data);
}
apiCall(endpoint, params = null, response = null) {
this.debug(`API Call - Endpoint: ${endpoint}`, {
params,
responseStatus: response?.status,
responseDataLength: response?.data?.length
});
}
botError(userId, error, context = null) {
this.error(`Bot Error - User: ${userId}`, {
error: error.message,
stack: error.stack,
context
});
}
topsappOperation(operation, clientId, result = null) {
this.debug(`TopSapp Operation - ${operation} - Cliente: ${clientId}`, {
success: result?.success,
dataCount: result?.data?.length || result?.servicos?.length || result?.clientes?.length,
error: result?.error
});
}
// Limpar logs antigos (método utilitário)
clearLogs() {
if (!this.isDebug) {
return;
}
try {
if (fs.existsSync(this.logFile)) {
fs.unlinkSync(this.logFile);
}
// Limpar backups também
for (let i = 1; i <= this.maxBackups; i++) {
const backupFile = `${this.logFile}.${i}`;
if (fs.existsSync(backupFile)) {
fs.unlinkSync(backupFile);
}
}
this.info('Logs limpos com sucesso');
} catch (error) {
console.error('Erro ao limpar logs:', error);
}
}
// Obter últimas linhas do log
getRecentLogs(lines = 100) {
if (!this.isDebug || !fs.existsSync(this.logFile)) {
return [];
}
try {
const content = fs.readFileSync(this.logFile, 'utf8');
const allLines = content.split('\n').filter(line => line.trim());
return allLines.slice(-lines);
} catch (error) {
console.error('Erro ao ler logs:', error);
return [];
}
}
}
// Singleton instance
const logger = new Logger();
module.exports = logger;