Wrapper do loguru com 3 modos de saida para o motor e-commerce: - Texto (default): console colorido + arquivos rotacionados em /root/ecommerce/logs/, retencao 30/90 dias, compressao gzip - JSON padrao (M5_LOG_JSON=1): mesmo formato de arquivo, com serialize=True do loguru - JSON clean (M5_LOG_JSON_CLEAN=1): sink customizado sem campo 'text' e com exception.traceback_str como string unica, otimizado para ingestao em Loki/Elastic/n8n API publica: - get_logger(name) -> logger bindado com module + context - bind_context(**kwargs) -> context manager para request_id/agent - log_exception(log, message, **kwargs) -> captura traceback estruturado - configure() -> idempotente, controla os 3 modos via env vars Acompanha example_usage.py com 4 cenarios reais: 1. Sync marketplace (com bind_context por SKU) 2. Agente async (Telegram -> Amazon sync) 3. Pedido com erro de NF-e (log_exception com sefaz_status) 4. Job batch Black Friday (progresso a cada N SKUs) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
147 lines
4.2 KiB
Python
147 lines
4.2 KiB
Python
"""
|
|
Exemplo de uso real do logger M5 em diferentes cenarios.
|
|
|
|
Cobre os 4 casos que vao aparecer no motor e-commerce:
|
|
1. Script de sincronizacao com marketplace
|
|
2. Agente async com contexto de execucao
|
|
3. Worker de pedido com tratamento de erro
|
|
4. Job batch com progresso
|
|
|
|
Rodar:
|
|
/root/ecommerce/scripts/venv/bin/python utils/example_usage.py
|
|
M5_LOG_JSON=1 /root/ecommerce/scripts/venv/bin/python utils/example_usage.py
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import time
|
|
from utils.m5log import get_logger, bind_context, log_exception, configure
|
|
|
|
|
|
def cenario_1_sync_marketplace() -> None:
|
|
"""Sync pontual de produtos para um marketplace (ex: TikTok Shop)."""
|
|
log = get_logger(__name__)
|
|
|
|
log.info("Iniciando sincronizacao com marketplace", marketplace="tiktok_shop")
|
|
time.sleep(0.05)
|
|
|
|
produtos = [
|
|
{"sku": "SKU-001", "preco": 99.90, "estoque": 12},
|
|
{"sku": "SKU-002", "preco": 149.00, "estoque": 0},
|
|
{"sku": "SKU-003", "preco": 49.90, "estoque": 200},
|
|
]
|
|
|
|
for p in produtos:
|
|
if p["estoque"] == 0:
|
|
log.warning("Produto sem estoque, pulando", sku=p["sku"])
|
|
continue
|
|
|
|
with bind_context(sku=p["sku"], marketplace="tiktok_shop"):
|
|
log.info(
|
|
"Produto sincronizado",
|
|
preco=p["preco"],
|
|
estoque=p["estoque"],
|
|
)
|
|
|
|
log.info("Sincronizacao concluida", total=len(produtos), enviados=2)
|
|
|
|
|
|
def cenario_2_agente_async() -> None:
|
|
"""Agente do Telegram processando comando do usuario."""
|
|
log = get_logger(__name__)
|
|
|
|
comando = {"user_id": 5511999999999, "texto": "/sync amazon"}
|
|
|
|
log.info("Comando recebido", **comando)
|
|
|
|
with bind_context(
|
|
agent="amazon-sync",
|
|
user_id=comando["user_id"],
|
|
request_id="req-7f3a2b",
|
|
):
|
|
log.info("Delegando para agente especializado")
|
|
|
|
for step in ["auth", "catalog", "pricing", "stock"]:
|
|
log.info("Etapa concluida", step=step)
|
|
time.sleep(0.02)
|
|
|
|
log.info("Agente finalizou")
|
|
|
|
|
|
def cenario_3_pedido_com_erro() -> None:
|
|
"""Processamento de pedido com erro de NF-e (deve gerar log estruturado)."""
|
|
log = get_logger(__name__)
|
|
|
|
pedido_id = "PED-2026-00042"
|
|
with bind_context(pedido_id=pedido_id, canal="mercado_livre"):
|
|
log.info("Pedido recebido")
|
|
|
|
try:
|
|
nota = {"numero": None, "serie": "1"}
|
|
if nota["numero"] is None:
|
|
raise ValueError("NF-e sem numero atribuido pela SEFAZ")
|
|
|
|
log.info("NF-e emitida", **nota)
|
|
|
|
except Exception:
|
|
log_exception(
|
|
log,
|
|
"Falha ao emitir NF-e",
|
|
sefaz_status="rejeitado",
|
|
tentativa=1,
|
|
)
|
|
|
|
log.info("Pedido finalizado com erro registrado")
|
|
|
|
|
|
def cenario_4_job_batch() -> None:
|
|
"""Job em lote com progresso (ex: recálculo de preços Black Friday)."""
|
|
log = get_logger(__name__)
|
|
|
|
log.info("Job batch iniciado", evento="black_friday_2026")
|
|
|
|
with bind_context(job="recalcular_precos", batch_id="bf-2026-1"):
|
|
total_skus = 250
|
|
processados = 0
|
|
erros = 0
|
|
|
|
for i in range(1, total_skus + 1):
|
|
try:
|
|
if i % 47 == 0:
|
|
raise ConnectionError("API do marketplace timeout")
|
|
processados += 1
|
|
except Exception:
|
|
erros += 1
|
|
log_exception(log, "Falha ao recalcular preco", sku=f"SKU-{i:05d}")
|
|
|
|
if i % 50 == 0:
|
|
log.info(
|
|
"Progresso",
|
|
processados=processados,
|
|
erros=erros,
|
|
percentual=round(i / total_skus * 100, 1),
|
|
)
|
|
|
|
log.info(
|
|
"Job batch finalizado",
|
|
total=total_skus,
|
|
sucessos=processados,
|
|
erros=erros,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
configure()
|
|
|
|
print("\n--- 1. Sync marketplace ---\n")
|
|
cenario_1_sync_marketplace()
|
|
|
|
print("\n--- 2. Agente async ---\n")
|
|
cenario_2_agente_async()
|
|
|
|
print("\n--- 3. Pedido com erro ---\n")
|
|
cenario_3_pedido_com_erro()
|
|
|
|
print("\n--- 4. Job batch ---\n")
|
|
cenario_4_job_batch()
|
|
|
|
print("\n--- FIM ---\n") |