RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Eruo Fredoline
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /How-to
  5. /How to Implement Logging for Agent Debugging
HOW-TO · RAG

How to Implement Logging for Agent Debugging

intermediate·15 min·By Eruo Fredoline
Target environment
Ubuntu 24.04 · Ollama 0.4.x
PREREQUISITES

Agent system running, logging library (structlog, loguru), Python 3.10+

What this does

Structured logging captures agent decisions, LLM inputs/outputs, tool calls, errors, and timing — providing a searchable record for debugging incorrect agent behavior.

Steps

  • Set up structured logging with structlog.
import structlog

structlog.configure(
    processors=[
        structlog.stdlib.add_log_level,
        structlog.dev.ConsoleRenderer()
    ],
    context_class=dict,
)

log = structlog.get_logger()
  • Log agent lifecycle events. Every step of the agent loop should produce a log entry.
def agent_step(task: str, turn: int) -> str:
    log.info("agent.step.start", task=task, turn=turn)

    log.info("agent.llm.call", prompt_length=len(task))
    response = llm.invoke(task)
    log.info("agent.llm.response", finish_reason=response.finish_reason, token_count=len(response.content))

    if response.tool_calls:
        for tc in response.tool_calls:
            log.info("agent.tool.call",
                tool=tc.function.name,
                args=tc.function.arguments,
                tool_call_id=tc.id
            )
            result = execute_tool(tc.function.name, json.loads(tc.function.arguments))
            log.info("agent.tool.result", tool=tc.function.name, success="error" not in result)

    log.info("agent.step.complete", turn=turn)
    return response.content
  • Add JSON logging for production. Switch to JSON renderer for log aggregation.
structlog.configure(
    processors=[
        structlog.stdlib.add_log_level,
        structlog.processors.TimeStamper(fmt="iso"),
        structlog.processors.JSONRenderer()
    ]
)
  • Log with correlation IDs. Trace requests across multiple turns.
import uuid

def run_agent(user_input: str):
    correlation_id = str(uuid.uuid4())
    log = structlog.get_logger().bind(correlation_id=correlation_id)

    log.info("agent.session.start", input=user_input)
    result = agent_loop(user_input)
    log.info("agent.session.end", result=result)
    return result
  • Configure exception logging. Capture full tracebacks for errors.
import traceback

try:
    result = execute_tool(tool_name, args)
except Exception as e:
    log.error("agent.tool.error",
        tool=tool_name,
        error=str(e),
        traceback=traceback.format_exc()
    )
  • Set log levels per module. Reduce noise from third-party libraries.
import logging

logging.getLogger("httpx").setLevel(logging.WARNING)
logging.getLogger("openai").setLevel(logging.WARNING)
# Agent logs stay at DEBUG

Verification

python -c "
import structlog
log = structlog.get_logger()
log.info('test.message', key='value')
print('Logging works')
# Expected: 2026-05-29 ... test.message key=value  OR  Logging works (JSON output)
"

Common failures

  • Sensitive data in logs. LLM inputs may contain PII. Add a processor that redacts emails, API keys, and personal names before logging.
  • Log noise. Logging every token or every retry attempt produces gigabytes per hour. Use DEBUG level for verbose events and INFO for decisions.
  • Async context loss. Coroutine logs may lose the correlation_id binding. Use structlog.threadlocal.bind_threadlocal() or pass the logger explicitly.
  • Version mismatch - The installed package or runtime differs from the command shown; check the version first and rerun the smallest verification command.
  • Local environment drift - Another service, virtual environment, model, or path is being used; print the active binary path and configuration before changing the guide steps.

Related guides

  • How to Set Up Agent Observability and Tracing
  • How to Debug Agent Reasoning and Tool Selection
← All how-to guidesCourses →