gordon-watcher

module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2025 License: MIT

README

🎯 Gordon Watcher

Production-ready file system monitoring and processing pipeline with enterprise-grade observability

Go Version License Docker RabbitMQ Prometheus Jaeger

Gordon Watcher Logo

📖 Overview

Gordon Watcher é um sistema robusto de monitoramento de sistema de arquivos, projetado para detectar, processar e enfileirar arquivos de forma confiável e escalável. Ideal para pipelines de processamento de documentos, integração de sistemas, ETL e automação de workflows.

🌟 Principais Características
  • 🔍 Monitoramento em Tempo Real: Detecta novos arquivos instantaneamente usando fsnotify
  • 🚀 Alta Performance: Worker pool concorrente com rate limiting configurável
  • 🛡️ Resiliência Total: Circuit breaker, retry automático e reconciliação de órfãos
  • 📊 Observabilidade Completa: Métricas Prometheus, tracing OTLP/Jaeger e logs estruturados
  • 🔒 Idempotência: Previne processamento duplicado com hashing SHA256
  • 🐰 Message Queue: Integração RabbitMQ com Dead Letter Queue (DLQ)
  • 🔴 Distributed Locks: Redis para coordenação em ambientes multi-instância
  • 🐳 Cloud Native: Docker, Kubernetes-ready, health checks e graceful shutdown

🎨 Arquitetura

graph LR
    A[📁 Incoming] -->|fsnotify| B[🔍 Watcher]
    B -->|Stability Check| C[⚡ Worker Pool]
    C -->|Hash + Lock| D[🔴 Redis]
    C -->|Process| E[📦 Processing]
    E -->|Success| F[🐰 RabbitMQ]
    E -->|Failure| G[❌ Failed]
    F -->|DLQ| H[☠️ Dead Letter Queue]
    F -->|Worker| I[✅ Processed]
    
    B -.->|Metrics| J[📊 Prometheus]
    B -.->|Traces| K[🔍 Jaeger]
📂 Fluxo de Processamento
  1. 📥 Detecção: Arquivos são detectados na pasta incoming
  2. ⏱️ Estabilização: Aguarda até o arquivo parar de ser escrito
  3. 🔐 Hash: Calcula SHA256 para idempotência
  4. 🔒 Lock: Adquire lock distribuído no Redis
  5. 📦 Movimentação: Move para processing
  6. 🐰 Enfileiramento: Publica no RabbitMQ com retry + circuit breaker
  7. ✅ Finalização: Arquivo fica em processing até o worker externo processar

🚀 Quick Start

Pré-requisitos
  • 🐳 Docker & Docker Compose
  • 🐹 Go 1.21+ (para desenvolvimento)
🏃 Rodando com Docker Compose
# 1. Clone o repositório
git clone https://github.com/fabyo/gordon-watcher.git
cd gordon-watcher

# 2. Configure o ambiente
cp .env.example .env
cp docker-compose.override.yml.example docker-compose.override.yml

# 3. Descubra o IP do servidor (para Samba)
make discover-ip
# Anote o "IP do WSL" que aparecer

# 4. Suba o stack completo
docker compose up -d

# 5. Verifique o status
docker compose ps

# 6. Abra o Dashboard no navegador
open web/dashboard.html
# Ou: firefox web/dashboard.html
# Ou: google-chrome web/dashboard.html

# 7. Monitore os logs
docker compose logs -f watcher
🪟 Acesso Windows (Samba)

O Docker Compose já inclui compartilhamento Samba para você jogar arquivos do Windows!

1. Descobrir o IP do Servidor

No Linux/WSL, rode:

make discover-ip

Saída esperada:

🔍 Descobrindo IPs...

📍 IP do WSL (Docker): 172.24.123.45
🪟 IP do Windows: 192.168.1.100

Para conectar do Windows ao Samba:
  \\172.24.123.45\incoming

Credenciais:
  Usuário: gordon
  Senha: (definida no .env)
2. Conectar do Windows

Opção A: Acesso Direto

  1. Abra o Explorador de Arquivos
  2. Digite na barra de endereço:
    \\172.24.123.45\incoming
    
    (Use o IP que apareceu no make discover-ip)
  3. Digite as credenciais:
    • Usuário: gordon
    • Senha: (definida no .env)

Opção B: Mapear Unidade de Rede (Recomendado)

  1. Abra o Explorador de Arquivos

  2. Clique com botão direito em "Este Computador"

  3. Selecione "Mapear unidade de rede"

  4. Escolha a letra Z: (ou outra disponível)

  5. Pasta: \\172.24.123.45\incoming

  6. Marque "Reconectar ao fazer logon"

  7. Marque "Conectar usando credenciais diferentes"

  8. Clique em "Concluir"

  9. Digite:

    • Usuário: gordon (ou conforme definido no .env)
    • Senha: (definida no .env)

    Exemplo de acesso via Windows: Pressione Win + R e digite: \\172.24.123.45\incoming

    Ou mapeie via comando:

    net use Z: \\172.24.123.45\incoming /user:gordon * /persistent:yes
    

    (O Windows pedirá a senha)

3. Usar

Agora você pode jogar XMLs direto na unidade Z: do Windows! 🎉

Os arquivos serão processados automaticamente pelo Gordon Watcher.

🎯 Testando
# Coloque um arquivo na pasta monitorada
echo "Hello Gordon!" > /opt/gordon-watcher/data/incoming/test.xml

# Acompanhe o processamento
docker compose logs -f watcher

# Verifique as métricas
curl http://localhost:9100/metrics | grep gordon_watcher

📊 Observabilidade

📈 Dashboard de Métricas

Visualize TUDO em tempo real!

O Gordon Watcher inclui um dashboard HTML pratico e funcional que mostra todas as métricas importantes.

🚀 Como Abrir

O dashboard é servido automaticamente pelo Docker na porta 8080.

Acesse no seu navegador: 👉 http://localhost:8080

Dica: Se a porta 8080 estiver ocupada, você pode alterá-la facilmente:

DASHBOARD_PORT=9090 docker compose up --build -d

Dashboard Preview

📊 O Que Você Vê

O dashboard mostra 8 cards principais com atualização automática a cada 5 segundos:

Arquivos:

  • 📥 Detectados: Total de arquivos encontrados pelo watcher
  • Enviados: Processados com sucesso e enfileirados no RabbitMQ
  • 🔄 Duplicados: Já processados anteriormente (idempotência funcionando!)
  • Rejeitados: Padrão ou tamanho inválido
  • 🚫 Ignorados: Arquivos ignorados por regras de exclusão

Sistema:

  • Goroutines: Threads ativas (para detectar memory leaks)
  • 👷 Workers Ativos: Quantos workers estão processando agora
  • 📦 Fila de Workers: Arquivos aguardando processamento

Taxa de Processamento:

  • 📈 Percentual de sucesso
  • 📊 Total processado

O dashboard inclui botões para acessar:

  • 📊 Métricas Prometheus (dados brutos)
  • 🏥 Health Check (status do serviço)
  • 🐰 RabbitMQ Management (filas e mensagens)
  • 🔍 Jaeger Tracing (rastreamento distribuído via OTLP)
💡 Exemplo de Uso
  1. Abra o dashboard
  2. Jogue um XML na pasta compartilhada (Samba)
  3. Veja em tempo real:
    • "Detectados" aumenta (+1)
    • "Enviados" aumenta (+1) após processamento
    • "Workers Ativos" mostra 1 durante o processamento
  4. Se jogar o mesmo arquivo de novo:
    • "Duplicados" aumenta (+1)
    • Arquivo não é reprocessado (idempotência!)

Atualização automática a cada 5 segundos! 🔄

🏥 Health Checks
# Liveness (está vivo?)
curl http://localhost:8081/health

# Readiness (está pronto para receber tráfego?)
curl http://localhost:8081/ready
📈 Métricas Prometheus

Endpoint: http://localhost:9100/metrics

Métrica Tipo Descrição
gordon_watcher_files_detected_total Counter Total de arquivos detectados
gordon_watcher_files_sent_total Counter Arquivos enviados para fila
gordon_watcher_files_duplicated_total Counter Arquivos duplicados (já processados)
gordon_watcher_files_rejected_total Counter Arquivos rejeitados (padrão/tamanho)
gordon_watcher_queue_errors_total Counter Erros ao publicar no RabbitMQ
gordon_watcher_goroutines Gauge Número de goroutines ativas
gordon_watcher_worker_pool_queue_size Gauge Tamanho da fila de workers
gordon_watcher_file_processing_seconds Histogram Tempo de processamento
🔍 Distributed Tracing (Jaeger)

UI: http://localhost:16686

Visualize o fluxo completo de cada arquivo:

  • Detecção → Estabilização → Hash → Lock → Queue → Worker

Nota: Usa OpenTelemetry Protocol (OTLP) para enviar traces. Compatible com Jaeger, Tempo, Zipkin, etc.

🐰 RabbitMQ Management

UI: http://localhost:15672
Credenciais: gordon / (senha do .env)

  • Monitore filas e exchanges
  • Visualize mensagens na DLQ
  • Acompanhe throughput

⚙️ Configuração

📝 Arquivo de Configuração

Edite configs/config.yaml:

watcher:
  paths:
    - /opt/gordon-watcher/data/incoming
  
  file_patterns:
    - "*.xml"
    - "*.pdf"
    - "*.json"
  
  exclude_patterns:
    - ".*"           # Arquivos ocultos
    - "*.tmp"        # Temporários
    - "*Zone.Identifier"  # Windows WSL
  
  min_file_size: 100          # bytes
  max_file_size: 104857600    # 100MB
  
  max_workers: 10
  max_files_per_second: 100
🔐 Variáveis de Ambiente

Veja .env.example para todas as opções disponíveis.


🛡️ Resiliência e Segurança

🔄 Retry com Backoff Exponencial
// Configuração padrão
MaxAttempts:   3
InitialDelay:  1s
MaxDelay:      30s
Multiplier:    2.0
⚡ Circuit Breaker

Protege contra falhas em cascata:

  • Threshold: 5 falhas consecutivas
  • Timeout: 30 segundos
  • Estados: Closed → Open → Half-Open
🔒 Idempotência
  • Hash SHA256 de cada arquivo
  • Verificação no Redis antes de processar
  • Previne duplicação mesmo em multi-instância
🧹 Reconciliação de Órfãos

Na inicialização, arquivos órfãos em processing são movidos de volta para incoming.

🚨 Dead Letter Queue (DLQ)

Mensagens que falharem após todas as tentativas vão para gordon.files.dlq para análise manual.


🎯 Casos de Uso

📄 Processamento de Documentos XML
watcher:
  paths:
    - /data/xml/incoming
  file_patterns:
    - "*.xml"
  max_workers: 20
  max_files_per_second: 200
📊 ETL de Arquivos CSV
watcher:
  paths:
    - /data/exports/incoming
  file_patterns:
    - "*.csv"
    - "*.tsv"
  min_file_size: 1024  # Ignora CSVs vazios
🖼️ Processamento de Imagens
watcher:
  paths:
    - /data/uploads/incoming
  file_patterns:
    - "*.jpg"
    - "*.png"
    - "*.webp"
  max_file_size: 52428800  # 50MB
📦 Integração de Sistemas (EDI)
watcher:
  paths:
    - /data/edi/incoming
  file_patterns:
    - "*.edi"
    - "*.x12"
  stable_attempts: 10      # Arquivos grandes
  stable_delay: 500ms

🐳 Deploy

Docker
# Build
docker build -t gordon-watcher:latest -f docker/Dockerfile .

# Run
docker run -d \
  -v /opt/gordon-watcher/data:/opt/gordon-watcher/data \
  -p 8081:8081 \
  -p 9100:9100 \
  gordon-watcher:latest
Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gordon-watcher
spec:
  replicas: 3
  selector:
    matchLabels:
      app: gordon-watcher
  template:
    metadata:
      labels:
        app: gordon-watcher
    spec:
      containers:
      - name: watcher
        image: gordon-watcher:latest
        ports:
        - containerPort: 8081
          name: health
        - containerPort: 9100
          name: metrics
        volumeMounts:
        - name: data
          mountPath: /opt/gordon-watcher/data
        livenessProbe:
          httpGet:
            path: /health
            port: 8081
        readinessProbe:
          httpGet:
            path: /ready
            port: 8081
Ansible
cd ansible
ansible-playbook -i inventory/development.yml deploy.yml

🔧 Desenvolvimento

📦 Instalação
# Clone
git clone https://github.com/fabyo/gordon-watcher.git
cd gordon-watcher

# Instale dependências
go mod download

# Build
make build

# Run
./bin/gordon-watcher
🧪 Testing
# Run all unit tests
make test

# Run unit tests with coverage
make test-coverage

# Run integration tests
make test-integration

# Run all tests (unit + integration)
go test -v ./...
go test -v -tags=integration ./tests/integration/...

# Run specific test
go test -v -run TestCircuitBreaker ./internal/watcher/...

# Generate coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
Test Coverage

Unit Tests:

  • ✅ Circuit Breaker (6 tests)
  • ✅ Stability Checker (5 tests)
  • ✅ Worker Pool (7 tests)
  • ✅ Cleaner (6 tests)
  • ✅ Retry Logic (8 tests)

Integration Tests:

  • ✅ File Detection & Processing
  • ✅ ZIP Extraction
  • ✅ Duplicate Handling
  • ✅ Rate Limiting
  • ✅ Stability Checker
  • ✅ Non-matching Files
CI/CD

GitHub Actions roda automaticamente em PRs e pushes:

  • ✅ Unit & Integration Tests
  • ✅ golangci-lint
  • ✅ Multi-platform builds (Linux, macOS, Windows)
  • ✅ Docker build & push
  • ✅ Security scanning (Trivy)
📝 Makefile Targets
make build          # Compila o binário
make test           # Roda testes
make lint           # Roda linter
make docker-build   # Build Docker image
make docker-up      # Sobe stack completo
make docker-down    # Para stack
make clean          # Limpa binários

❓ Troubleshooting

🛑 Parar o Watcher Forçadamente

Se o watcher travar ou você precisar matá-lo rapidamente (especialmente durante testes):

pkill -f gordon-watcher

Isso vai encerrar qualquer processo que tenha "gordon-watcher" no nome.


🔒 Segurança

✅ Boas Práticas Implementadas
  • Usuário não-root: Container roda como gordon (UID 1000)
  • Imagem mínima: Alpine Linux (< 20MB)
  • Secrets externos: Credenciais via env vars, nunca hardcoded
  • Health checks: Liveness e readiness probes
  • Graceful shutdown: Finaliza processamento antes de parar
  • Rate limiting: Previne sobrecarga
  • Input validation: Valida tamanho e padrões de arquivo
🔐 Recomendações para Produção
  1. TLS/SSL: Use AMQPS para RabbitMQ
  2. Autenticação: Configure Redis com senha
  3. Network Policies: Isole pods no Kubernetes
  4. Resource Limits: Defina CPU/Memory limits
  5. Secrets Management: Use Vault ou Kubernetes Secrets
  6. Audit Logs: Habilite logs estruturados em JSON

📚 Documentação Adicional


🤝 Contribuindo

Contribuições são bem-vindas! Por favor:

  1. Fork o projeto
  2. Crie uma branch (git checkout -b feature/amazing)
  3. Commit suas mudanças (git commit -m 'Add amazing feature')
  4. Push para a branch (git push origin feature/amazing)
  5. Abra um Pull Request

📄 Licença

Este projeto está licenciado sob a MIT License - veja o arquivo LICENSE para detalhes.


👨‍💻 Autor

Fabyo
📧 fabyo.php@gmail.com
🐙 GitHub


🚀 Stacks


⭐ Se este projeto foi útil, deixe uma estrela! ⭐

Made with ❤️ and ☕ by Fabyo

Directories

Path Synopsis
cmd
watcher command
examples
consumer command
internal
watcher
internal/watcher/circuitbreaker.go (NOVO ARQUIVO!)
internal/watcher/circuitbreaker.go (NOVO ARQUIVO!)
tests

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL