@sagatechbrasildev/argus-metrics-adonis
v1.0.0
Published
Professional metrics collection library for AdonisJS v6
Maintainers
Readme
AdonisJS Metrics Library
📊 Biblioteca profissional de coleta de métricas para AdonisJS v6
🚀 Recursos
- ✅ Coleta Automática de Métricas - Requests, queries SQL, jobs, eventos e erros
- 📈 Agregação Inteligente - Dados agregados por endpoint, status code e intervalo de tempo
- 🔒 Sanitização de Dados Sensíveis - Remove automaticamente passwords, tokens e headers sensíveis
- 📊 Percentis de Performance - P50, P95, P99 para análise detalhada
- 🔄 Flush Automático - Envia métricas periodicamente para seu backend
- 💾 Buffer com Retry - Queue local com exponential backoff em caso de falha
- 🎯 Sampling Rate - Controle a porcentagem de requests monitoradas
- 🚦 Health Checks - Monitora uptime, memória e CPU
- 🔍 Consumer Tracking - Rastreio de API keys e usuários
- ⚡ Zero Dependencies - Apenas peer dependencies do AdonisJS
📦 Instalação
npm install argus-metrics-adonis
# ou
yarn add argus-metrics-adonis⚙️ Configuração
1. Configurar a Biblioteca
Execute o comando de configuração para registrar automaticamente o comando e o provider:
node ace configure argus-metrics-adonisDepois, publique o arquivo de configuração:
node ace metrics:publish-configIsso criará o arquivo config/metrics.ts no seu projeto com todas as opções disponíveis.
2. Registrar o Provider (Manual)
Se preferir configurar manualmente, adicione ao arquivo adonisrc.ts:
export default defineConfig({
// ...
providers: [
() => import("@adonisjs/core/providers/app_provider"),
() => import("argus-metrics-adonis/providers/adonis-provider"),
],
});3. Adicionar Middleware
No arquivo start/kernel.ts:
import { metricsMiddleware } from "argus-metrics-adonis";
router.use([metricsMiddleware()]);4. Configurar Variáveis de Ambiente
Crie ou edite o arquivo .env:
# Habilitar coleta de métricas
METRICS_ENABLED=true
# API Key para autenticação
METRICS_API_KEY=your-api-key-here
# Endpoint do backend que receberá as métricas
METRICS_ENDPOINT=https://your-backend.com/api/metrics
# Intervalo de envio (em segundos)
METRICS_FLUSH_INTERVAL=60
# Taxa de amostragem (0.0 a 1.0)
METRICS_SAMPLE_RATE=1.0
# Paths excluídos
METRICS_EXCLUDE_PATHS=/health,/metrics
# Capturar payloads (cuidado com dados sensíveis)
METRICS_CAPTURE_PAYLOADS=false
# Capturar queries SQL
METRICS_CAPTURE_QUERIES=true
# Tamanho máximo do buffer
METRICS_MAX_BUFFER_SIZE=1000
# Threshold para queries lentas (ms)
METRICS_SLOW_QUERY_THRESHOLD=1005. Configuração Customizada (Opcional)
Crie o arquivo config/metrics.ts:
import { defineConfig } from "@adonisjs/core/app";
import type { MetricsConfig } from "argus-metrics-adonis";
export default defineConfig<MetricsConfig>({
enabled: true,
apiKey: "your-api-key",
endpoint: "https://your-backend.com/api/metrics",
flushInterval: 60,
aggregationInterval: 60,
sampleRate: 1.0,
excludePaths: ["/health", "/metrics"],
excludeHeaders: ["authorization", "cookie"],
capturePayloads: false,
captureQueries: true,
maxBufferSize: 1000,
slowQueryThreshold: 100,
});📖 Uso Avançado
Acessar o Collector Manualmente
import { getMetricsCollector } from "argus-metrics-adonis";
export default class UsersController {
async index({ app }) {
const collector = await getMetricsCollector(app);
// Coletar métrica customizada
collector.collectEvent("user.login", { userId: 123 }, 1);
// Ver métricas atuais
const metrics = collector.getMetrics();
console.log(metrics);
}
}Coletar Erros Manualmente
try {
// código que pode falhar
} catch (error) {
const collector = await getMetricsCollector(app);
collector.collectError(error, ctx);
throw error;
}Health Check Endpoint
import { getMetricsCollector } from "argus-metrics-adonis";
router.get("/health", async ({ app }) => {
const collector = await getMetricsCollector(app);
const health = collector.collectHealth();
return {
status: "ok",
uptime: health.uptime,
memory: health.memoryUsage,
cpu: health.cpuUsage,
};
});📊 Formato de Dados Enviados
A biblioteca envia dados agregados no seguinte formato:
{
"timestamp": "2025-12-17T10:00:00Z",
"interval": 60, // segundos
"requests": [
{
"method": "GET",
"path": "/api/users",
"statusCode": 200,
"count": 150,
"avgDuration": 45.2,
"minDuration": 12.1,
"maxDuration": 156.8,
"p50": 42.0,
"p95": 89.5,
"p99": 145.2,
"totalRequestSize": 15000,
"totalResponseSize": 450000,
"errors": 0
}
],
"queries": [
{
"sql": "SELECT * FROM users WHERE id = ?",
"count": 150,
"avgDuration": 3.5,
"minDuration": 1.2,
"maxDuration": 12.8,
"slowQueries": 2
}
],
"jobs": [
{
"name": "SendEmailJob",
"duration": 1250,
"status": "success",
"timestamp": "2025-12-17T10:00:15Z"
}
],
"events": [
{
"name": "user.login",
"payload": { "userId": 123 },
"listeners": 1,
"timestamp": "2025-12-17T10:00:30Z"
}
]
}🔒 Segurança e Privacidade
Dados Automaticamente Sanitizados
- Headers:
authorization,cookie,set-cookie,x-api-key - Body Fields:
password,token,secret,api_key,credit_card,cvv,ssn
Adicionar Campos Customizados
import { DataSanitizer } from "argus-metrics-adonis";
// Customizar sanitizador
const sanitized = DataSanitizer.sanitizeBody({
email: "[email protected]",
password: "secret123", // será [REDACTED]
cpf: "123.456.789-00", // adicione à lista se necessário
});📈 Backend de Métricas
Você precisará criar um backend para receber as métricas. Exemplo simples:
// Endpoint no seu backend
app.post("/api/metrics", async (req, res) => {
const metrics = req.body;
// Validar API Key
if (req.headers["x-api-key"] !== process.env.METRICS_API_KEY) {
return res.status(401).json({ error: "Unauthorized" });
}
// Salvar no banco de dados
await db.insert("metrics").values(metrics);
// Ou enviar para serviço de analytics
await analytics.track(metrics);
res.json({ success: true });
});🛠️ API Reference
MetricsCollector
class MetricsCollector {
collectRequest(ctx: HttpContext, startTime: number): void;
collectQuery(sql: string, duration: number, bindings?: any[]): void;
collectJob(
name: string,
startTime: number,
status: "success" | "failed"
): void;
collectEvent(name: string, payload: any, listeners: number): void;
collectError(error: Error, ctx?: HttpContext): void;
collectHealth(): HealthMetrics;
flush(): Promise<boolean>;
getMetrics(): AggregatedMetrics;
shutdown(): Promise<void>;
}MetricsConfig
interface MetricsConfig {
enabled: boolean;
apiKey: string;
endpoint: string;
flushInterval: number;
aggregationInterval: number;
sampleRate: number;
excludePaths: string[];
excludeHeaders: string[];
capturePayloads: boolean;
captureQueries: boolean;
maxBufferSize: number;
slowQueryThreshold: number;
}🤝 Contribuindo
Contribuições são bem-vindas! Por favor:
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/amazing-feature) - Commit suas mudanças (
git commit -m 'Add amazing feature') - Push para a branch (
git push origin feature/amazing-feature) - Abra um Pull Request
Desenvolvido com ❤️ para a comunidade AdonisJS
