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
Markdown
# 📋 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.