FwLogger e o framework de logging moderno do Protheus (TLPP). Substitui ConOut/MemoWrite com niveis, handlers, e formato JSON estruturado.
Niveis
| Nivel | Quando usar |
| DEBUG | Detalhes pra debug (dev only) |
| INFO | Eventos normais relevantes |
| WARN | Anomalia que nao bloqueia |
| ERROR | Erro recuperavel |
| FATAL | Erro 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
- Filtrar antes:
If FwLogger():IsDebugEnabled() ... EndIf evita string concat desnecessario.
- Handlers HTTP assincronos: nao espere resposta — fire-and-forget.
- Buffer/batch: acumule 100 eventos antes de enviar ao ELK.
- Fallback local: se handler remoto falhar, persiste em arquivo.
Retencao
| Nivel | Retencao tipica |
| DEBUG | 7 dias (alto volume) |
| INFO | 30 dias |
| WARN | 90 dias |
| ERROR/FATAL | 1 ano (compliance) |
Comparacao FwLogger vs ConOut
| Aspecto | FwLogger | ConOut |
| Niveis | 5 niveis | Nenhum |
| Estruturado (JSON) | Sim | Nao |
| Handlers customizados | Sim | Nao |
| Filtro dinamico | Sim | Nao |
| Performance em verbose | Otimo | Bom |
| Disponivel em | TLPP | AdvPL e TLPP |
Pegadinhas
- Em AdvPL puro: FwLogger nao disponivel — use ConOut + helper proprio.
- Log de PII em INFO: cuidado LGPD — emails, CPF nao deveriam estar em log nivel comum.
- Estouro de log: em loop com nivel DEBUG, pode gerar GB/hora. Use logger condicional.