Logging estruturado com FwLogger

Como usar FwLogger pra log estruturado em producao: niveis, handlers customizados, integracao com ELK/Datadog, retencao.

FwLogger e o framework de logging moderno do Protheus (TLPP). Substitui ConOut/MemoWrite com niveis, handlers, e formato JSON estruturado.

Niveis

NivelQuando usar
DEBUGDetalhes pra debug (dev only)
INFOEventos normais relevantes
WARNAnomalia que nao bloqueia
ERRORErro recuperavel
FATALErro grave

Uso basico

#include "tlpp-core.th"

User Function ProcessaPedido()
    FwLogger():Info("Iniciando processamento")

    try
        U_GravaPedido()
        FwLogger():Info("Pedido gravado com sucesso")
    catch e
        FwLogger():Error("Falha ao gravar pedido: " + e:getDescription())
        Return .F.
    endtry
Return .T.

Log estruturado com contexto

// Em vez de strings concatenadas, passe contexto
FwLogger():Info("Pedido criado", {;
    "numero":  cNumPed, ;
    "cliente": cCliente, ;
    "valor":   nValor   ;
})

// Output em formato JSON estruturado:
// {"ts":"2026-05-13T14:32:18","level":"INFO","msg":"Pedido criado","ctx":{"numero":"...","cliente":"...","valor":1234.56}}

Configurar nivel minimo

// Em dev: verbose
FwLogger():SetLevel("DEBUG")

// Em producao: filtrar ruido
FwLogger():SetLevel("WARN")

Handlers customizados — enviar log pra ELK/Splunk

// Handler que posta no Elasticsearch
class ElkLogHandler from FwLoggerHandler
    method handle(oEvento) class ElkLogHandler
        Local oHttp := FwHttpClient():New()
        oHttp:SetHeader("Content-Type", "application/json")

        Local oPayload := JsonObject():New()
        oPayload["@timestamp"] := oEvento:getTimestamp()
        oPayload["level"]      := oEvento:getLevel()
        oPayload["msg"]        := oEvento:getMessage()
        oPayload["host"]       := GetEnvServer()
        oPayload["service"]    := "protheus"

        oHttp:Post("https://elk.empresa.com.br/protheus/_doc", oPayload:ToJson())
    endmethod
endclass

// Registrar
FwLogger():AddHandler(ElkLogHandler():New())

Estrutura de log recomendada

FwLogger():Info("event", {;
    "entity":     "pedido",   ; // tipo de entidade
    "action":     "create",    ; // acao
    "id":         cNumPed,     ; // ID
    "user":       RetCodUsr(), ; // quem
    "filial":     cFilAnt,     ; // onde
    "duration_ms": nDur        ; // performance
})

Performance — log nao deve travar producao

Retencao

NivelRetencao tipica
DEBUG7 dias (alto volume)
INFO30 dias
WARN90 dias
ERROR/FATAL1 ano (compliance)

Comparacao FwLogger vs ConOut

AspectoFwLoggerConOut
Niveis5 niveisNenhum
Estruturado (JSON)SimNao
Handlers customizadosSimNao
Filtro dinamicoSimNao
Performance em verboseOtimoBom
Disponivel emTLPPAdvPL e TLPP

Pegadinhas

Veja também