Azify Logger Client - Centralized logging for OpenSearch
npm install azify-loggerSistema de logging centralizado com OpenTelemetry e OpenSearch para múltiplas aplicações.
| Ambiente | URL |
|----------|-----|
| Development | http://localhost:3001/log |
| Staging | https://logsdashboard.azify.dev/send |
| Production | https://cadence.aztech.host/send |
| Ambiente | URL |
|----------|-----------------------------------|
| Development | http://localhost:3002 |
| Staging | https://logsdashboard.azify.dev |
| Production | https://cadence.aztech.host |
``bash`
npm install azify-logger
`javascript
// 1. No arquivo de inicialização
require('azify-logger/register-otel');
// 2. No servidor
import { middleware as azifyMiddleware } from 'azify-logger'
const server = restify.createServer()
server.use(azifyMiddleware.restify())
// 3. Variável de ambiente
APP_NAME=nome-app
`
`javascript`
require('azify-logger')
const express = require('express')
const app = express()
const azifyMiddleware = require('azify-logger/middleware-express')
app.use(azifyMiddleware())
`javascript
const fastify = require('fastify')()
const azifyPlugin = require('azify-logger/middleware-fastify')
await fastify.register(azifyPlugin, {
serviceName: 'minha-app'
})
await fastify.listen({ port: 3000 })
`
| Variável | Padrão | Descrição |
|----------|------------------------------------|-----------|
| APP_NAME | - | Nome da aplicação |AZIFY_LOGGER_URL
| | http://localhost:3001/log | URL do logger |AZIFY_LOGGER_REDIS_URL
| | redis://localhost:6381 | URL do Redis (fila de logs) |AZIFY_LOGGER_REDIS_PASSWORD
| | — | Obrigatório em todos os ambientes. Sem senha, a app continua (usa HTTP direto) e a mensagem de aviso é exibida. |OTEL_EXPORTER_OTLP_ENDPOINT
| | http://localhost:4318/v1/traces | Endpoint OTLP para traces (opcional) |NODE_ENV
| | development | Ambiente |
- ✅ Zero Config: OpenTelemetry habilitado automaticamente
- ✅ Logs Completos: Headers, body, query params, status
- ✅ Trace Consistente: REQUEST e RESPONSE com mesmo traceId/spanId
- ✅ Genérico: Funciona com Bunyan, Pino, console.log ou qualquer logger
- ✅ Centralizado: Todos os logs no OpenSearch
- ✅ Tracing Completo: Traces exportados via OTLP para Grafana Tempo (opcional)
O azify-logger inclui um OpenTelemetry Collector configurado para receber traces via OTLP e exportá-los para Grafana Tempo.
Para habilitar o envio de traces, configure a variável de ambiente na sua aplicação:
`bash`
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:3001/v1/traces
| Ambiente | URL |
|----------|-----|
| Development (Docker) | http://localhost:3001/v1/traces |https://logsdashboard.azify.dev/v1/traces
| Staging | |https://cadence.aztech.host/v1/traces
| Production | |
1. OpenTelemetry cria um span para cada request HTTP
2. Middleware captura request e response com o mesmo span ativo
3. Logger envia ambos os logs com traceId e spanId iguais
4. OpenSearch indexa e permite buscar por traceId
``
┌─────────────┐
│ aplicação │
└──────┬──────┘
│ HTTP POST
↓
┌─────────────┐
│ azify-logger│ (recebe logs)
└──────┬──────┘
│
↓
┌─────────────┐
│ OpenSearch │ (armazena em logs-{appName})
└──────┬──────┘
│
↓
┌─────────────┐
│ Grafana │ (visualiza - Organizations por app)
└─────────────┘
O azify-logger usa Grafana para visualização dos logs com controle de acesso por aplicação.
- 📊 Explore: Busca e visualização de logs em tempo real
- 📈 Dashboards: Dashboards automáticos com métricas (Total de Requisições, Taxa de Sucesso, Erros, Tempo Médio de Resposta, etc.)
Quando uma aplicação envia logs pela primeira vez, o sistema automaticamente:
1. ✅ Cria uma Organization no Grafana com o nome da aplicação
2. ✅ Cria um Datasource filtrado para o índice logs-{appName}
3. ✅ Cria um Dashboard completo com métricas
4. ✅ Isola completamente os logs da aplicação
Gerenciar acesso:
- Acesse Grafana como Server Admin
- Vá em Administration → Organizations
- Adicione usuários à Organization da app
- ⚠️ Importante: Use role Editor ou Admin para acesso ao Explorer (onde estão os logs). Role Viewer não tem acesso ao Explorer.
`bash`
./start-docker.sh
Aguarde alguns minutos. Você verá:
``
✅ Tudo pronto!
📊 OpenSearch: http://localhost:9200
📈 Grafana: http://localhost:3002
📝 Logger API: http://localhost:3001/log
Copie os arquivos de exemplo e preencha com seus valores:
`bash`
cp env/app.env.example env/app.env
cp env/grafana.env.example env/grafana.env
#### ✅ Importante: configure seu e-mail para ser promovido a Admin
1. Abra env/grafana.env.ADMIN_GLOBAL_EMAIL
2. Atualize com seu e-mail corporativo (ex.: ADMIN_GLOBAL_EMAIL=seu.email@exemplo.com).env/app.env
3. Abra .ADMIN_EMAILS
4. Garanta que contenha o mesmo e-mail (ex.: ADMIN_EMAILS=seu.email@exemplo.com)../start-docker.sh
5. Salve os arquivos e reinicie os containers ().
Assim, ao fazer login com Azure AD, você é promovido automaticamente a Server Admin e já enxerga o Explore e os dashboards da sua aplicação.
`bash`
curl -X POST http://localhost:3001/log \
-H "Content-Type: application/json" \
-d '{
"level": "info",
"message": "Teste",
"meta": {"service": {"name": "minha-app"}}
}'
Acesse http://localhost:3002 e faça login com Azure AD.
Por padrão, o azify-logger só aceita chamadas dos próprios serviços locais (mesma VM / rede privada).
Se sua aplicação não estiver rodando na mesma máquina/VM do azify-logger:
- Descubra o IP público da aplicação cliente
- Envie esse IP para que ele seja incluído na configuração interna (ALLOWED_SOURCE_IPS)
Isso vale tanto para:
- Envio de logs (/log e /send)/v1/traces
- Envio de traces ()
Enquanto o IP não for incluído nessa lista, chamadas vindas de fora da mesma máquina/rede serão bloqueadas com 403 Forbidden.
`bash`
git push origin master
O deploy é feito automaticamente via GitHub Actions.
1. Acesse: GitHub → Actions → Deploy
2. Clique em Run workflow
3. Configure: Environment: production
4. Clique em Run workflow
> ⚠️ Importante: A retenção é configurada apenas no servidor azify-logger. As aplicações que usam a lib não precisam se preocupar com retenção - elas apenas enviam logs normalmente.
O azify-logger inclui um sistema automático de retenção que:
- ✅ Mantém sempre os últimos 30 dias de logs disponíveis no OpenSearch para consulta imediata
- ✅ Compacta e arquiva logs mais antigos automaticamente
- ✅ Envia para Azure Blob Storage para armazenamento de longo prazo
- ✅ Remove logs antigos do OpenSearch após arquivamento bem-sucedido
1. Agendamento: O serviço de retenção executa automaticamente 1x por dia às 3h da manhã (configurável via RETENTION_RUN_AT_HOUR)logs/{app}/{YYYYMM}/{DD}/
2. Identificação: Busca todos os logs com mais de 30 dias no OpenSearch
3. Arquivamento:
- Exporta logs mais antigos que 30 dias
- Compacta em formato ZIP
- Envia para Azure Blob Storage na estrutura
- Remove do OpenSearch após confirmação de upload bem-sucedido
A configuração de retenção é feita apenas no servidor azify-logger, no arquivo env/app.env:
`bash
RETENTION_DAYS=30 # Dias de logs mantidos no OpenSearch (padrão: 30)
RETENTION_RUN_AT_HOUR=3 # Horário de execução diária (0-23, padrão: 3h da manhã)
⚠️ As aplicações que usam a lib azify-logger não precisam configurar nada relacionado à retenção.
Para executar a retenção manualmente (útil para testes):
`bashExecutar uma vez
npm run retention -- --once
$3
Os arquivos são organizados da seguinte forma:
`
{container}/
└── logs/
└── {YYYYMM}/ (ex: 202512/)
└── log-YYYY-MM-DD-HH-MM-SS-UUID.zip
`Cada arquivo ZIP contém:
-
metadata.json: Metadados do índice (nome, data de exportação, contagem de documentos, dias de retenção)
- {indexName}-{timestamp}.json: Todos os documentos exportados em JSONO sistema sempre mantém os últimos 30 dias de logs disponíveis no OpenSearch/Grafana.
$3
#### Consulta e Validação de Blob Storage
`bash
Listar todos os arquivos no blob storage
npm run list:blobListar arquivos ZIP recentes (última hora)
npm run list:blob:recentBaixar um arquivo ZIP específico
npm run download:blob "logs/harmony/202512/05/log-2025-12-05-14-29-01.zip" ~/DownloadsBaixar todos os arquivos de uma pasta
npm run download:blob "logs/harmony/202512/05/*" ~/Downloads
`#### Reimportação de Logs
Para reimportar logs arquivados de volta para o OpenSearch (útil para análise de logs antigos):
`bash
Reimportar um arquivo ZIP específico
npm run reimport:logs ~/Downloads/log-2025-12-05-18-31-32.zipReimportar todos os ZIPs de uma pasta
npm run reimport:logs ~/Downloads/arquivos-exportados/
`Importante:
- Os logs serão reimportados no índice original
- Os timestamps originais são preservados
- A aplicação já deve estar configurada no Grafana (organização e datasource)
- Após a reimportação, os logs estarão disponíveis no Grafana imediatamente
⚠️ Preservação de Dados
IMPORTANTE: Logs do OpenSearch são armazenados em volume Docker persistente.
Comandos seguros (preservam dados):
`bash
docker compose stop
docker compose restart
`Comandos destrutivos (APAGAM logs):
`bash
docker compose down -v # ⚠️ APAGA VOLUMES!
``