Skip to content

MchLogToolkitGo - V3 roteia LogSubject por subject: levels via Graylog UDP, eventos de domínio em disco#18

Open
JVVeiga wants to merge 3 commits into
devfrom
feat/v3-subject-router
Open

MchLogToolkitGo - V3 roteia LogSubject por subject: levels via Graylog UDP, eventos de domínio em disco#18
JVVeiga wants to merge 3 commits into
devfrom
feat/v3-subject-router

Conversation

@JVVeiga
Copy link
Copy Markdown
Member

@JVVeiga JVVeiga commented May 20, 2026

Descrição

V3 hoje seleciona um destino único (file ou Graylog UDP). Quando UDP está ativo, todas as chamadas LogSubject vão por rede — inclusive subjects de domínio com payloads gordos que precisam de persistência (ex.: historico_posicao_taxi, log_posicao_alterada, trajeto_solicitacao, webhook_event_position). Esses payloads não cabem em UDP de forma confiável e historicamente vivem em disco.

Este PR introduz um router por subject dentro do V3:

  • Subjects "level-like" (test, debug, info, warn, error, fatal) — saída de Logger.Info/.Warn/.Error/... — vão para o destino de rede quando configurado.
  • Subjects de domínio (qualquer outra string) vão sempre para arquivo, no mesmo layout do V2.
  • Roteamento exclusivo (não tee), fail-loud (UDP dial falha → Initialize retorna erro), whitelist extensível via DestinationConfig.NetworkSubjects.

Mudanças por commit

  • 0298278 feat(mchlogcorev3)!: route LogSubject by subject (file + optional UDP)

    • mchlogcorev3/config.goProtocol/ProtocolFile/ProtocolGraylogUDP/Addr/Source/DisableGZIP removidos. Entrou Network *NetworkConfig{Type, Addr, Source, DisableGZIP} + NetworkSubjects []string. Zero value = file-only (mesmo comportamento do legacy ProtocolFile).
    • mchlogcorev3/router.go (novo) — routerDestination com whitelist hardcoded + extender, dispatch por subject, GetFileNameFromStreamName/Close per-subject.
    • mchlogcorev3/mchlogv3.goInitialize sempre constrói file impl + opcional network impl, embrulha em router. graylogUDP.cfg agora é NetworkConfig (não mais DestinationConfig).
    • mchlogcorev3/gelf.gobuildGELFMessage aceita NetworkConfig.
    • mchlogcorev3/router_test.go (novo) — matriz de dispatch (table-driven) + 3 cenários end-to-end loopback UDP + stress 20×20 goroutines.
    • Testes existentes migrados para nova shape, incluindo mchlogcore/v3_dispatch_test.go.
  • 546004c docs(mchlogcorev3): describe subject router model in README and facade

    • README.md — seção V3 reescrita: modelo router, tabela de campos, avisos sobre NetworkSubjects.
    • mchlogcore/mchlog.go — comentário de InitializeMchLog atualizado.

Tipo de Mudança

  • Nova Funcionalidade: roteamento por subject permite que serviços usem Graylog para level-logs sem perder persistência em disco para eventos de domínio.
  • Breaking Change: assinatura de DestinationConfig mudou. Callers que usam Protocol: ProtocolFile/ProtocolGraylogUDP não compilam mais.
  • Melhoria de Código: centraliza lógica de roteamento dentro do toolkit; callers não precisam alterar callsites de LogSubject.
  • Testes: matriz de dispatch + end-to-end loopback UDP + stress concorrente cobrindo race detector.

Checklist

  • Testei o código localmente
  • Revisei o código (self-review)
  • Comentei meu código, especialmente em áreas difíceis de entender
  • Fiz alterações correspondentes na documentação
  • Minhas alterações não geram novos warnings
  • Novos e existentes testes unitários passam localmente com minhas alterações
  • Chequei se o PR cumpre os critérios de aceitação da issue relacionada

Como testar as alterações

cd MchLogToolkitGo
go build ./...
go vet ./...
go test ./...           # 114 passed em 6 packages
go test -race ./...     # mesma matriz, sem race detector hits

Integration test opcional (precisa de Graylog real):

GRAYLOG_TEST_ADDR=localhost:12201 go test -tags=integration -v ./mchlogcorev3/...

Para validar o comportamento de routing manualmente:

  • Configure(DestinationConfig{}) (zero value) → arquivo-only, layout V2.
  • Configure(DestinationConfig{Network: &NetworkConfig{Type: NetworkGraylogUDP, Addr: ..., Source: ...}})LogSubject("info", ...) vai para UDP; LogSubject("meu_evento_dominio", ...) vai para <basePath>/<service>/meu_evento_dominio/meu_evento_dominio.log.
  • Acrescentar NetworkSubjects: []string{"meu_evento_dominio"} → o evento de domínio passa a ir para UDP em vez de arquivo (extender).

Impactos no Deploy

  • Breaking change na API: callers que importam mchlogcorev3 e usam Protocol/Addr/Source/DisableGZIP em DestinationConfig precisam migrar para Network *NetworkConfig{...}. Migração é mecânica.
  • Layout em disco e JSON shape do file impl inalterados (mesmo <basePath>/<service>/<subject>/<subject>.log do V2). Sem migração de dados.
  • mchtracker precisa de PR companheiro atualizando infra/logger/logger.go para a nova shape antes de bumpar a dependência.

Dependências

Sem mudanças em go.mod/go.sum. Continua usando github.com/Graylog2/go-gelf/gelf.

Issues

Observações Adicionais

  • V2 cache global: o file impl delega a mchlogcorev2, que mantém um sync.Map global de *zerolog.Logger por subject. Testes que escrevem o mesmo subject em t.TempDir() diferentes podem colidir (o cache mantém FD aberto contra arquivo já unlinked). O stress test usa subject único para evitar — comentário no router_test.go explica. Não é novo nesta PR, é design legado do V2.
  • Routing exclusivo: subject listado em NetworkSubjects vai 100% para UDP, sem tee em disco. Use com cautela — eventos críticos que precisam persistência local devem ficar fora dessa lista.
  • Healthchecks/probes que dependem de GetFileNameFromStreamName(subject) devolver um caminho de arquivo real devem usar subjects fora da whitelist (mantém comportamento atual).

JVVeiga added 2 commits May 20, 2026 14:25
V3 internally wraps every Initialize in a routerDestination that holds
a file impl (always) and an optional network impl. Level-like subjects
(test/debug/info/warn/error/fatal) — i.e., output from Logger.Info/.Warn/
.Error/... — go to the network impl when configured; everything else
(domain events) goes to file in the same V2 layout. Caller may extend
the level set via DestinationConfig.NetworkSubjects.

Configure shape reshaped: Protocol/ProtocolFile/ProtocolGraylogUDP/Addr/
Source/DisableGZIP replaced by Network *NetworkConfig{Type, Addr, Source,
DisableGZIP} + NetworkSubjects []string. Zero value keeps file-only
behavior (same as legacy ProtocolFile).

Initialize fails loud on UDP dial errors; routing is exclusive (no tee).
V3 README section rewritten around the router: explains level-vs-domain
routing, exclusive dispatch, fail-loud on UDP init, NetworkSubjects
extender semantics, and migration path. mchlogcore.InitializeMchLog
doc comment updated to reflect that V3 always has a file impl and
uses the path's last segment for service name on the network side.
@JVVeiga JVVeiga self-assigned this May 20, 2026
@JVVeiga JVVeiga added the enhancement New feature or request label May 20, 2026
gaudinho[bot]
gaudinho Bot previously approved these changes May 20, 2026
Copy link
Copy Markdown

@gaudinho gaudinho Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor sólido: router por subject preserva persistência em disco para eventos de domínio enquanto permite levels via UDP. Cobertura de testes excelente — matriz table-driven + 3 end-to-end loopback + stress 20×20 com race detector. Breaking change bem documentado e default zero-value mantém compatibilidade bit-a-bit com V2.

Comment thread mchlogcorev3/config.go Outdated
Comment thread mchlogcorev3/router.go
Comment thread mchlogcorev3/router.go
Comment thread mchlogcorev3/mchlogv3.go
Comment thread mchlogcorev3/router_test.go Outdated
- ActiveConfig now deep-copies Network ptr and NetworkSubjects slice,
  symmetric with Configure. Callers may mutate the result freely.
- defaultLevelSubjects comment documents case-sensitivity (Logger
  internal always emits lowercase).
- TestRouterConcurrentLogSubject doc + inline comment explain why the
  UDP datagram check accepts N > 0: loopback drops under bursts, exact
  total is validated via the domain-subject file (deterministic).
Copy link
Copy Markdown
Collaborator

@jfelipends jfelipends left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants