UNPKG

api-stats-logger

Version:

SDK completo de logging e monitoramento de APIs com auto-instrumentação, dashboard em tempo real e CLI para configuração automática

751 lines (583 loc) 17 kB
# 📋 Guia Completo de Instalação - API Stats Logger ## 🎯 Para Desenvolvedores Back-end Este guia foi criado especificamente para desenvolvedores back-end que precisam integrar o **API Stats Logger** em suas aplicações. Siga os passos em ordem para uma integração perfeita. --- ## 📦 Passo 1: Instalação do Pacote ### Método Recomendado ```bash npm install api-stats-logger ``` ### Se houver conflitos de dependências ```bash # Para Express 5.x ou conflitos peer npm install api-stats-logger --legacy-peer-deps # Para forçar instalação (não recomendado para produção) npm install api-stats-logger --force ``` ### Verificar instalação ```bash npx api-stats-init --version # Deve exibir: API Stats CLI v1.1.3+ ``` --- ## 🚀 Passo 2: Configuração Automática (RECOMENDADO) ### 2.1 Executar CLI de Configuração ```bash npx api-stats-init ``` ### 2.2 O que a CLI faz automaticamente: 1. **Autentica com a API** (https://apistats.squareweb.app) 2. **Cria projeto automaticamente** com nome do seu serviço 3. **Gera API key única** para seu projeto 4. **Detecta seu framework** (Express, NestJS, Fastify, Koa) 5. **Cria arquivos de configuração**: - `.env.api-stats` - Variáveis de ambiente - `api-stats.config.js` - Configurações avançadas - `api-stats-[framework]-example.js` - Exemplo pronto para uso - `API-STATS-SETUP.md` - Instruções específicas ### 2.3 Exemplo de saída da CLI: ``` 🚀 API Stats Logger - Configuração Inicial 🔄 Verificando autenticação... 📝 Login: Username ou email: seu-usuario@eway.dev Senha: ******** ✅ Login realizado com sucesso! 🔄 Coletando configurações do projeto... Nome do serviço/projeto: minha-api-backend URL base da API: https://api.minhaempresa.com Ambiente [development/staging/production]: production 🔍 Detectando framework... ✅ Framework detectado: express ✅ Projeto criado: 507f1f77bcf86cd799439011 ✅ API key gerada: ak_1a2b3c4d5e6f... 📝 Criado: .env.api-stats 📝 Criado: api-stats-express-example.js 📝 Criado: api-stats.config.js 📝 Criado: API-STATS-SETUP.md 🎉 Configuração concluída com sucesso! ``` --- ## ⚙️ Passo 3: Configuração de Variáveis de Ambiente ### 3.1 Copiar variáveis geradas A CLI cria o arquivo `.env.api-stats` com todas as variáveis: ```env # API Stats Logger Configuration API_STATS_ENABLED=true API_STATS_API_KEY=ak_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p API_STATS_URL=https://apistats.squareweb.app/logs API_STATS_SERVICE=minha-api-backend API_STATS_ENVIRONMENT=production API_STATS_BATCH_SIZE=10 API_STATS_FLUSH_INTERVAL=2000 # Optional: Capture settings API_STATS_CAPTURE_BODY=false API_STATS_CAPTURE_HEADERS=true # Project Info (for reference) API_STATS_PROJECT_ID=507f1f77bcf86cd799439011 ``` ### 3.2 Adicionar ao seu .env principal ```env # Suas variáveis existentes... DATABASE_URL=postgres://... REDIS_URL=redis://... # API Stats Logger (copie do .env.api-stats) API_STATS_ENABLED=true API_STATS_API_KEY=ak_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p API_STATS_URL=https://apistats.squareweb.app/logs API_STATS_SERVICE=minha-api-backend API_STATS_ENVIRONMENT=production ``` ### 3.3 Variáveis por ambiente ```env # .env.development API_STATS_ENVIRONMENT=development API_STATS_CAPTURE_BODY=true API_STATS_CAPTURE_HEADERS=true # .env.staging API_STATS_ENVIRONMENT=staging API_STATS_CAPTURE_BODY=false API_STATS_CAPTURE_HEADERS=true # .env.production API_STATS_ENVIRONMENT=production API_STATS_CAPTURE_BODY=false API_STATS_CAPTURE_HEADERS=false ``` --- ## 🔧 Passo 4: Integração por Framework ### 4.1 Express.js (Mais comum) #### Método 1: Auto-instrumentação (MAIS FÁCIL) ```javascript // No topo do seu app.js ou server.js, ANTES de outros requires require('api-stats-logger').init(); // Resto da sua aplicação continua igual const express = require('express'); const app = express(); // Suas rotas existentes continuam funcionando app.get('/users', (req, res) => { // Logs automáticos para esta rota! res.json({ users: [] }); }); app.listen(3000); ``` #### Método 2: Middleware manual (Mais controle) ```javascript const express = require('express'); const ApiStatsLogger = require('api-stats-logger'); const app = express(); // Inicializar logger const logger = new ApiStatsLogger({ service: process.env.API_STATS_SERVICE, environment: process.env.API_STATS_ENVIRONMENT }); // Adicionar middleware ANTES das suas rotas app.use(ApiStatsLogger.expressMiddleware({ logger, captureBody: process.env.API_STATS_CAPTURE_BODY === 'true', captureHeaders: process.env.API_STATS_CAPTURE_HEADERS === 'true', skipPaths: ['/health', '/metrics', '/favicon.ico'], skipMethods: ['OPTIONS'] })); // Suas rotas existentes app.get('/users', (req, res) => { logger.info('Listando usuários', { requestId: req.id }); res.json({ users: [] }); }); // Middleware de erro (opcional) app.use((err, req, res, next) => { logger.error('Erro na aplicação', { error: err.message, stack: err.stack, url: req.url, method: req.method }); res.status(500).json({ error: 'Internal server error' }); }); app.listen(3000); ``` ### 4.2 NestJS #### main.ts ```typescript import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ApiStatsLogger } from 'api-stats-logger'; async function bootstrap() { const app = await NestFactory.create(AppModule); // Adicionar middleware do API Stats const logger = new ApiStatsLogger({ service: process.env.API_STATS_SERVICE, environment: process.env.API_STATS_ENVIRONMENT }); app.use(ApiStatsLogger.nestMiddleware({ logger, captureBody: process.env.API_STATS_CAPTURE_BODY === 'true', captureHeaders: process.env.API_STATS_CAPTURE_HEADERS === 'true', skipRoutes: ['/health', '/metrics'] })); await app.listen(3000); logger.info('NestJS application started', { port: 3000, environment: process.env.NODE_ENV }); } bootstrap(); ``` #### Em um Controller ```typescript import { Controller, Get, Post, Body, Logger } from '@nestjs/common'; import { ApiStatsLogger } from 'api-stats-logger'; @Controller('users') export class UsersController { private readonly logger = new ApiStatsLogger({ service: 'users-service' }); @Get() async findAll() { this.logger.info('Listing all users'); try { const users = await this.userService.findAll(); this.logger.info('Users retrieved successfully', { count: users.length }); return users; } catch (error) { this.logger.error('Error retrieving users', { error: error.message }); throw error; } } @Post() async create(@Body() userData: any) { this.logger.info('Creating new user', { email: userData.email }); try { const user = await this.userService.create(userData); this.logger.info('User created successfully', { userId: user.id, email: user.email }); return user; } catch (error) { this.logger.error('Error creating user', { error: error.message, email: userData.email }); throw error; } } } ``` ### 4.3 Fastify ```javascript const fastify = require('fastify')({ logger: false }); const ApiStatsLogger = require('api-stats-logger'); // Configurar logger const logger = new ApiStatsLogger({ service: process.env.API_STATS_SERVICE, environment: process.env.API_STATS_ENVIRONMENT }); // Hook para logging automático de requisições fastify.addHook('onRequest', async (request, reply) => { request.startTime = Date.now(); request.requestId = `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; logger.info('Request started', { requestId: request.requestId, method: request.method, url: request.url, ip: request.ip, userAgent: request.headers['user-agent'] }); }); // Hook para logging automático de respostas fastify.addHook('onResponse', async (request, reply) => { const duration = Date.now() - request.startTime; const level = reply.statusCode >= 500 ? 'error' : reply.statusCode >= 400 ? 'warn' : 'info'; logger.log({ level, message: `${request.method} ${request.url} ${reply.statusCode}`, metadata: { requestId: request.requestId, statusCode: reply.statusCode, duration, ip: request.ip } }); }); // Suas rotas fastify.get('/users/:id', async (request, reply) => { const { id } = request.params; logger.info('Getting user', { userId: id, requestId: request.requestId }); try { const user = await getUserById(id); logger.info('User found', { userId: id, requestId: request.requestId }); return user; } catch (error) { logger.error('Error getting user', { userId: id, error: error.message, requestId: request.requestId }); reply.status(500); return { error: 'Internal server error' }; } }); // Start server const start = async () => { try { await fastify.listen({ port: 3000 }); logger.info('Fastify server started', { port: 3000 }); } catch (err) { logger.error('Error starting server', { error: err.message }); process.exit(1); } }; start(); ``` ### 4.4 Koa ```javascript const Koa = require('koa'); const Router = require('@koa/router'); const bodyParser = require('koa-bodyparser'); const ApiStatsLogger = require('api-stats-logger'); const app = new Koa(); const router = new Router(); // Configurar logger const logger = new ApiStatsLogger({ service: process.env.API_STATS_SERVICE, environment: process.env.API_STATS_ENVIRONMENT }); // Middleware de logging app.use(async (ctx, next) => { const startTime = Date.now(); const requestId = `koa_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; ctx.requestId = requestId; logger.info('Request started', { requestId, method: ctx.method, url: ctx.url, ip: ctx.ip, userAgent: ctx.get('user-agent') }); try { await next(); } catch (error) { logger.error('Request error', { requestId, error: error.message, stack: error.stack, url: ctx.url, method: ctx.method }); throw error; } const duration = Date.now() - startTime; const level = ctx.status >= 500 ? 'error' : ctx.status >= 400 ? 'warn' : 'info'; logger.log({ level, message: `${ctx.method} ${ctx.url} ${ctx.status}`, metadata: { requestId, statusCode: ctx.status, duration, ip: ctx.ip } }); }); app.use(bodyParser()); // Rotas router.get('/users/:id', async (ctx) => { const { id } = ctx.params; logger.info('Getting user', { userId: id, requestId: ctx.requestId }); try { const user = await getUserById(id); logger.info('User found', { userId: id, requestId: ctx.requestId }); ctx.body = user; } catch (error) { logger.error('Error getting user', { userId: id, error: error.message, requestId: ctx.requestId }); ctx.status = 500; ctx.body = { error: 'Internal server error' }; } }); app.use(router.routes()); app.use(router.allowedMethods()); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { logger.info('Koa server started', { port: PORT }); console.log(`🚀 Server running on port ${PORT}`); }); ``` --- ## 📊 Passo 5: Tipos de Logs e Métricas ### 5.1 Logs Automáticos (via middleware) Automaticamente capturados para cada requisição: ```javascript // O middleware captura automaticamente: { "timestamp": "2024-05-29T10:30:00.000Z", "level": "info", "message": "GET /users/123 200", "service": "minha-api-backend", "environment": "production", "metadata": { "requestId": "req_1234567890_abcdef", "method": "GET", "url": "/users/123", "statusCode": 200, "duration": 45, "ip": "192.168.1.1", "userAgent": "Mozilla/5.0...", "headers": { /* se habilitado */ }, "responseBody": { /* se habilitado */ } } } ``` ### 5.2 Logs Manuais ```javascript const logger = new ApiStatsLogger(); // Logs de negócio logger.info('User login successful', { userId: 123, email: 'user@example.com', ip: '192.168.1.1', loginMethod: 'oauth' }); // Logs de erro logger.error('Database connection failed', { error: 'ECONNREFUSED', database: 'users', host: 'db.company.com', retryAttempt: 3 }); // Logs de performance logger.info('Slow query detected', { query: 'SELECT * FROM users WHERE...', duration: 2500, threshold: 1000, rowsReturned: 1500 }); // Logs de auditoria logger.warn('Unauthorized access attempt', { ip: '192.168.1.100', endpoint: '/admin/users', token: 'invalid_or_expired', timestamp: Date.now() }); ``` ### 5.3 Métricas de Performance ```javascript // Monitoramento de operações async function processPayment(paymentData) { const startTime = Date.now(); const operationId = `payment_${Date.now()}`; logger.info('Payment processing started', { operationId, amount: paymentData.amount, currency: paymentData.currency, method: paymentData.method }); try { const result = await paymentGateway.process(paymentData); const duration = Date.now() - startTime; logger.info('Payment processed successfully', { operationId, paymentId: result.id, duration, status: result.status }); return result; } catch (error) { const duration = Date.now() - startTime; logger.error('Payment processing failed', { operationId, error: error.message, duration, amount: paymentData.amount }); throw error; } } ``` --- ## 🔍 Passo 6: Verificação e Teste ### 6.1 Testar envio de logs Execute o exemplo gerado pela CLI: ```bash node api-stats-[framework]-example.js ``` ### 6.2 Verificar no dashboard Acesse: https://apistats.squareweb.app 1. Faça login com suas credenciais 2. Selecione seu projeto 3. Verifique se os logs estão chegando ### 6.3 Teste manual via curl ```bash # Testar endpoint diretamente curl -X POST https://apistats.squareweb.app/logs \ -H "Content-Type: application/json" \ -H "x-api-key: sua-api-key-aqui" \ -d '[{ "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)'", "level": "info", "message": "Teste manual de log", "service": "teste", "environment": "development", "metadata": { "test": true, "source": "curl" } }]' ``` ### 6.4 Debug de conexão ```javascript // Habilitar debug process.env.DEBUG = 'api-stats-logger:*'; const logger = new ApiStatsLogger({ debug: true // Mostra logs detalhados }); // Verificar conectividade logger.testConnection().then(result => { console.log('Conexão OK:', result); }).catch(error => { console.error('Erro de conexão:', error); }); ``` --- ## ⚠️ Troubleshooting ### Problema 1: "API key inválida" ```bash # Verificar se a API key está correta echo $API_STATS_API_KEY # Regenerar API key npx api-stats-init # Escolha "Usar API key existente" # Cole uma nova API key ``` ### Problema 2: "Logs não aparecem no dashboard" 1. Verificar se as variáveis de ambiente estão corretas 2. Verificar conectividade com o endpoint 3. Verificar se o serviço está enviando logs ```javascript // Debug de logs const logger = new ApiStatsLogger({ debug: true }); logger.info('Teste de log'); // Deve mostrar: "Sending logs to API Stats..." ``` ### Problema 3: "Conflitos de dependências" ```bash # Limpar cache do npm npm cache clean --force # Reinstalar com legacy peer deps rm -rf node_modules package-lock.json npm install --legacy-peer-deps ``` ### Problema 4: "Performance degradada" ```javascript // Ajustar configurações de performance const logger = new ApiStatsLogger({ batchSize: 50, // Aumentar para menos requisições flushInterval: 10000, // Aumentar intervalo maxRetries: 1, // Reduzir tentativas captureBody: false, // Desabilitar capture de body captureHeaders: false // Desabilitar capture de headers }); ``` --- ## 📚 Recursos Adicionais ### Documentação Completa - **README.md** - Visão geral e exemplos - **TROUBLESHOOTING.md** - Soluções para problemas comuns - **CHANGELOG.md** - Histórico de versões ### Scripts Úteis ```bash # Verificar status da instalação npm run test:sdk # Testar configuração automática npm run test:auto-setup # Verificar logs npm run logs:stats ``` ### Suporte - 📧 **Email**: dev@grupoloyalty.com.br - 🌐 **API**: https://apistats.squareweb.app - 📚 **Docs**: https://github.com/grupo-loyalty/api-stats-logger --- **✅ Parabéns! Sua aplicação agora está monitorada pelo API Stats Logger!** Os logs começarão a aparecer no dashboard em tempo real. Para dúvidas ou suporte, consulte os recursos acima ou entre em contato conosco.