Configuração de Logs do RUB
O RUB possui um sistema de logs que armazena em disco mensagens de diagnósticos, todas as consultas ao banco de dados e todas as alterações de dados, bem como as ações dos usuários no sistema.
1. Categorias e Armazenamento
Os logs são divididos em 6 categorias principais:
| Categoria | Sufixo do Arquivo | Descrição |
|---|---|---|
| MAIN | _main.log | Logs gerais do sistema. |
| SYNC | _sync.log | Sincronização entre loja e central (arquitetura remota). |
| INTF | _intf.log | Processamento de integrações entre sistemas. |
| DATA | _data.log | Operações de banco de dados (Insert/Update/Delete). |
| ANA | _ana.log | Logs referentes ao ETL para análises. |
| ERRO | _erro.log | Logs específicos para mensagens de nível erro. |
1.1 Diretório de Logs
Os logs são armazenados no subdiretório log dentro do diretório de instalação do RUB.
Em servidores Linux, recomenda-se utilizar links simbólicos (symlinks) para armazenar os logs em partições dedicadas (
ex: /var/log/rub):
cd /opt/rub
ln -s /var/log/rub log
2. Formato dos Logs
Os arquivos de logs seguem o padrão definido na classe RuBLogWriter. O formato básico de cada linha é:
DATAHORA NÍVEL [MDC] ORIGEM: MENSAGEM
*DATAHORA: Carimbo de data e hora em que a mensagem foi gerada (AAAA-MM-DD HH:mm:ss).
*NÍVEL: Nome do nível de log com 5 caracteres (ex: INFO, DEBUG, WARN, ERROR). Note o espaço à esquerda
para alinhar níveis com 4 letras.
*MDC (Mapped Diagnostic Context): Conjunto de informações contextuais entre colchetes, essencial para
rastreabilidade:
* [main]: Nome da categoria do log (LogKind).
* [TID: 490]: ID da Thread que gerou o log.
* [EXEC_ID]: Um UUID único para cada execução/requisição (ex: 66623dcc-be76-4cfd-8716-37f039f1c2c7). Permite
filtrar todas as linhas de uma mesma operação.
* [CONTEXT_ID]: ID do contexto atual, como o código da loja ou empresa (ex: [loja999]). Fundamental para
troubleshooting em ambientes multiloja.
*ORIGEM: Local onde o log foi gerado. Pode ser simplificado (Arquivo.java:Linha) ou expandido (
pacote.Classe.metodo(Arquivo.java:Linha)), dependendo da chave log.src.full.
*MENSAGEM: O conteúdo descritivo do log.
Exemplo de linha de log (Real):
2026-06-19 03:34:07 INFO [main] [TID: 490] [66623dcc-be76-4cfd-8716-37f039f1c2c7] [loja999] AbstractSubDBAuditoria.java:122: SQL Time: 2ms queryEx select ...
2.1 Identificação de Categorias (log.mdc.logKind)
Quando a chave log.mdc.logKind está ativa (padrão true), o primeiro campo do MDC identifica a categoria do log. Isso
permite saber a qual categoria a mensagem pertence mesmo quando os logs são visualizados de forma unificada (como no
journalctl ou stdout de containers).
Exemplos de MDC por categoria:
*Logs Gerais: [main]
*Sincronização: [sync]
*Banco de Dados: [data]
*Interfaces: [intf]
*Analytics: [ana]
*Erros: [erro]
Exemplo de log de Sincronização:
2026-06-19 03:35:10 INFO [sync] [TID: 512] [88d3e2...] [loja3] SyncPlan.java:88: Sincronização concluída com sucesso.
2.2 Utilidade do MDC em Ambientes Multiloja
Em instâncias que atendem diversas lojas simultaneamente, o MDC permite filtrar logs de uma loja específica utilizando
comandos como grep:
# Filtrar todos os logs da loja 999
tail -f log/20260619_main.log | grep "[loja999]"
# Rastrear uma execução específica pelo seu UUID
grep "66623dcc-be76-4cfd-8716-37f039f1c2c7" log/20260619_main.log
3. Manutenção e Rotação
3.1 Retenção (Dias)
Os arquivos de log são mantidos pelo sistema pela quantidade de dias definida em configuração avançada.O valor padrão para todas as categorias é de 15 dias.
| Chave de Configuração | Padrão | Descrição |
|---|---|---|
tempoDeRegistroDeLogMain | 15 | Dias de retenção para logs gerais (MAIN). |
tempoDeRegistroDeLogSync | 15 | Dias de retenção para logs de sincronização (SYNC). |
tempoDeRegistroDeLogIntf | 15 | Dias de retenção para logs de interface (INTF). |
tempoDeRegistroDeLogData | 15 | Dias de retenção para logs de banco de dados (DATA). |
tempoDeRegistroDeLogAna | 15 | Dias de retenção para logs de analytics (ANA). |
tempoDeRegistroDeLogErro | 15 | Dias de retenção para logs de erro (ERRO). |
Os logs gerados há mais dias do que o configurado serão apagados automaticamente.
3.2 Rotação por Tamanho e Data
Os logs são rotacionados por dia ou tamanho para economia de disco.
*tamanhoMaximoLog: Determina o tamanho máximo (em MB) do log descompactado antes de rotacionar (Padrão: 2048 MB).
*maximoArquivosRotacionadosDia: Indica a quantidade máxima por dia de arquivos rotacionados que o sistema irá
manter (0 para ilimitado).
Ao mudar o dia ou atingir o tamanho máximo, o RUB compacta os logs anteriores em formatogzip. Arquivos compactados
por tamanho possuem o seguinte formato de nome:
AAAAMMDD_TIPO.N.log.gz
Onde N é o sequencial de arquivos compactados no mesmo dia, iniciado em 0 (zero).
4. Ligar e Desligar Logs (Arquivo e Saída Padrão)
O RUB permite controlar individualmente se cada categoria de log deve ser gravada em arquivo (archive) ou enviada para
a saída padrão (sysout).
Estas configurações são feitas diretamente no arquivo config.ini.
4.1 Chaves de Configuração
Substitua {suffix} pelo sufixo da categoria desejada (main, sync, intf, data, ana, erro).
| Chave | Valores | Descrição |
|---|---|---|
log.archive.{suffix} | true / false | Se false, o RUB para de gravar logs desta categoria em arquivos no disco. |
log.sysout.{suffix} | true / false | Se false, o RUB para de enviar logs desta categoria para a saída padrão (console). |
4.2 Exemplos Práticos
Desligar logs de Banco de Dados (_data.log) no arquivo:
log.archive.data=false
Desligar todos os logs de saída padrão para economizar recursos:
log.sysout.main=false
log.sysout.sync=false
log.sysout.intf=false
log.sysout.data=false
log.sysout.ana=false
Ligar log de erro na saída padrão (por padrão é desativado):
log.sysout.erro=true
5. Configurações Avançadas de Formatação
Estas chaves no config.ini permitem personalizar o conteúdo do MDC e da Origem no log:
| Chave | Padrão | Descrição |
|---|---|---|
log.mdc.logKind | true | Inclui o nome da categoria no início do MDC (ex: [main]). |
log.mdc.tid | true | Inclui o ID da thread (ex: [TID: 42]). |
log.mdc.execId | true | Inclui o ID de execução único (UUID). |
log.mdc.contextId | true | Inclui o ID do contexto atual (ex: loja ou empresa). Se indefinido, mostra [undefined]. |
log.src.full | false | Se true, expande a origem para incluir pacote, classe e método. Se false, mostra apenas Arquivo:Linha. |
6. Regras de Filtragem (.logrules)
O RUB permite criar regras de filtragem finas para permitir ou negar mensagens específicas. Cada categoria de log possui
seu próprio arquivo de regras no diretório configuration/.
6.1 Nomes dos Arquivos de Regras
*MAIN: configuration/default.logrules
*ANA: configuration/ana_default.logrules
*DATA: configuration/data_default.logrules
*ERRO: configuration/erro_default.logrules
*INTF: configuration/intf_default.logrules
*SYNC: configuration/sync_default.logrules
6.2 Formato das Regras
As regras são lidas sequencialmente, e as linhas inferiores têm prioridade sobre as superiores. O formato é:
ACAO NIVEL ORIGEM TEXTO
*ACAO: allow (permite) ou deny (nega).
*NIVEL: Combinação de níveis (D, I, W, E) ou * para todos os níveis.
*ORIGEM: Classe ou pacote que emitiu o log. Use * para todas as origens. A regra se aplica se o texto informado
estiver contido no nome do método/classe.
*TEXTO(Opcional): Se informado, a regra só será aplicada se a mensagem contiver este texto.
6.3 Exemplos de Regras
Desabilitar todos os logs de uma categoria:
deny IDWE *
Desabilitar apenas logs de DEBUG:
deny D *
Desabilitar logs específicos de operações de banco de dados:
deny IDWE *.logInsert
deny IDWE *.logUpdate
deny IDWE *.logDelete
Desabilitar logs de um pacote específico:
deny IDWE com.gicbrasil.rub.ressup.analiseconsumo
Desabilitar logs que contenham um texto específico (ex: tempo de SQL):
deny IDWE * "SQL Time:"
Permitir logs de erro mesmo em classes silenciadas:
deny IDW com.gicbrasil.rub.SuaClasse *
allow E com.gicbrasil.rub.SuaClasse *
Filtragem condicional (Deny geral, exceto para um usuário):
deny IDWE *.logInsert
allow IDWE * ID_USUARIO_ESPECIFICO
7. Integração com systemd (Observabilidade)
Quando o RUB roda como um serviço no Linux via systemd, o objetivo principal de utilizar a saída padrão (sysout) é a
Observabilidade. Ao centralizar os logs no journald, facilitamos a coleta por agentes comoPromtail(Grafana
Loki) ouFluent-bit, permitindo a criação de dashboards e alertas no Grafana.
7.1 Por que separar os logs?
Utilizar um SyslogIdentifier único (ex: rub) é fundamental para que as ferramentas de coleta consigam:
1.Filtragem Eficiente: Isolar as mensagens do RUB de outras mensagens do sistema (como SSH ou kernel).
2.Rotulagem (Labeling): Atribuir rótulos automáticos como {job="rub"} no Loki, facilitando buscas complexas.
3.Performance: Evitar o processamento de logs irrelevantes pelo agente de coleta.
7.2 Preparação no RUB
Certifique-se de que o envio para a saída padrão está ligado para as categorias operacionais no config.ini:
log.sysout.main=true
log.sysout.sync=true
log.sysout.intf=true
log.sysout.data=false # Opcional: Desligado pelo alto volume (erros de SQL já saem no MAIN/SYNC)
log.sysout.erro=false # Desligado pois erros já estão no main/sync
7.3 Exemplo de Arquivo de Serviço (rub.service)
Utilize o SyslogIdentifier para dar um nome único aos logs do RUB, facilitando a separação.
[Unit]
Description=Serviço RUB
After=network.target postgresql.service
[Service]
Type=simple
User=rub
WorkingDirectory=/home/rub/app
ExecStart=/home/rub/app/gradlew run
Restart=always
# Identificador para o log
SyslogIdentifier=rub
# Redireciona a saída para o journal
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
7.4 Visualizando Logs Separados
Com o SyslogIdentifier configurado, você pode filtrar os logs do RUB sem ver as mensagens normais do sistema:
# Ver apenas logs do RUB em tempo real
journalctl -u rub.service -f
# Ver logs do RUB filtrando pelo identificador
journalctl -t rub -f
7.5 Rotação e Retenção Curta no systemd
Ao utilizar ferramentas de observabilidade externa (Loki/Grafana), os logs no journald tornam-se efêmeros (apenas um
buffer).Recomenda-se manter tempos e tamanhos de retenção pequenospara economizar recursos do servidor:
Crie uma configuração em /etc/systemd/journald.conf.d/rub.conf:
[Journal]
# Limite de tamanho total dos logs (buffer para o coletor)
SystemMaxUse=200M
# Mantém logs locais por pouco tempo (já estarão no Grafana)
MaxRetentionSec=2day
Para descartar logs (não salvar no disco) e manter apenas na memória:
[Journal]
Storage=volatile
RuntimeMaxUse=100M
7.6 Separando em um Arquivo Físico com rsyslog (Opcional)
Para evitar que os logs do RUB poluam o /var/log/syslog ou /var/log/messages, crie um arquivo de configuração no
rsyslog (ex: /etc/rsyslog.d/rub.conf):
# Redireciona logs com identificador "rub" para um arquivo separado
if $programname == 'rub' then /var/log/rub-sysout.log
# Opcional: Para de processar esses logs para que não caiam no syslog geral
& stop
Após criar o arquivo, reinicie o rsyslog: sudo systemctl restart rsyslog.
7.7 Exemplo de Coleta para Grafana (Promtail)
Exemplo de configuração do Promtail para ler logs do RUB via journal:
scrape_configs:
- job_name: rub_service
journal:
max_age: 12h
path: /var/log/journal
labels:
job: rub
relabel_configs:
- source_labels: [ '__journal__syslog_identifier' ]
target_label: 'syslog_identifier'
# Filtra para pegar apenas o que identificamos como 'rub'
- source_labels: [ 'syslog_identifier' ]
regex: 'rub'
action: keep
8. Coleta de Logs em Containers (Docker/Kubernetes)
Em ambientes de container, a saída padrão é o meio oficial de coleta para ferramentas de Observabilidade.
8.1 Configuração Recomendada (Eficiência)
Para dashboards no Grafana, o ideal é ter logs limpos e sem duplicidade:
Em containers, a prática recomendada é ativar a saída padrão (sysout) para as categorias operacionais edesativar
a categoria ERRO.
Por que desativar o sysout de ERRO?
No RUB, a categoria ERRO contém apenas mensagens de nível ERROR. No entanto, essas mesmas mensagensjá são
enviadaspara suas respectivas categorias de origem (como MAIN, SYNC ou DATA). Habilitar o sysout para ERRO
resultaria em logs duplicados no coletor (Docker/Kubernetes), dificultando a análise e aumentando o volume de dados
desnecessariamente.
Exemplo de configuração no config.ini para coleta completa e eficiente:
# Habilita categorias principais (erros já inclusos nestas)
log.sysout.main=true
log.sysout.sync=true
log.sysout.intf=true
log.sysout.ana=true
# Desabilita categoria de erro redundante
log.sysout.erro=false
# Opcional: Logs de banco de dados costumam ser volumosos,
# avalie se realmente são necessários no sysout
log.sysout.data=false
# Desabilitar arquivamento em disco para evitar consumo de armazenamento efêmero
log.archive.main=false
log.archive.sync=false
log.archive.intf=false
log.archive.data=false
log.archive.ana=false
log.archive.erro=false
8.2 Outros Serviços
A mesma lógica de evitar logs redundantes de erro deve ser aplicada a outros serviços e módulos que compõem o ecossistema do RUB. Sempre priorize a coleta da categoria funcional (que dá contexto ao erro) em vez de uma categoria genérica de erros que apenas duplica a informação.
8.3 Visualizando Logs
Os logs capturados podem ser visualizados diretamente via comando do orquestrador:
# Docker
docker logs -f nome_do_container
# Kubernetes
kubectl logs -f nome_do_pod -c nome_do_container
8.4 Rotação e Retenção no Container
Em containers, os logs de stdout também devem ter retenção curta se estiverem sendo exportados para o Grafana:
docker-compose.yml:
services:
rub:
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "2"
8.5 Exemplo de Coleta (Loki via Docker Driver)
Você pode configurar o Docker para enviar logs diretamente ao Loki:
logging:
driver: loki
options:
loki-url: "http://loki:3100/loki/api/v1/push"
loki-external-labels: "container_name={{.Name}},job=rub"
9. Estratégia Recomendada: Observabilidade vs. Logs Locais
A escolha da estratégia de log depende da infraestrutura disponível:
9.1 Com Infraestrutura de Observabilidade (Recomendado)
Se você utiliza Grafana, Loki, ELK ou Datadog:
*Use sysout: Ligue log.sysout.* (exceto erro).
*Desligue archive: Defina log.archive.*=false para não gastar IOPS e disco local.
*Retenção Local Curta: Mantenha apenas 1 ou 2 dias de log no journald ou Docker como fallback.
9.2 Sem Infraestrutura de Observabilidade
Se você faz troubleshooting acessando o servidor via SSH:
*Use Logs em Disco (Seção 1): Mantenha log.archive.*=true.
*Aproveite a Organização: Os logs do RUB já são separados por categoria (_data.log, _sync.log), o que facilita
muito a análise manual com grep, tail e less.
*Gestão de Retenção: Ajuste as configurações avançadas (tempoDeRegistroDeLog...) para definir o tempo de retenção
ideal no disco, garantindo histórico suficiente para auditoria manual sem esgotar o armazenamento.
*Desligue sysout: Pode desligar log.sysout.*=false para reduzir o ruído no console do sistema.