Source code for langgoap.tracing.logging

"""Stdlib-``logging``-backed :class:`~langgoap.tracing.PlanningTracer`."""

from __future__ import annotations

# ``import logging`` resolves to the stdlib module via Python 3's absolute
# import semantics; this file's name shadows nothing at the top level.
import logging
from typing import Any

logger = logging.getLogger("langgoap.tracing")


[docs] class LoggingTracer: """Tracer that routes every event through stdlib ``logging``. Useful for quick local debugging without setting up OTel or LangSmith. Each hook logs at ``INFO`` level to the ``langgoap.tracing`` logger. """ def on_plan_start(self, goal: Any, state: Any, strategy_name: str) -> None: logger.info("plan_start strategy=%s goal=%r", strategy_name, goal) def on_plan_complete(self, plan: Any, duration_ms: float) -> None: logger.info("plan_complete duration_ms=%.2f plan=%r", duration_ms, plan) def on_plan_failed(self, reason: str, duration_ms: float) -> None: logger.info("plan_failed reason=%s duration_ms=%.2f", reason, duration_ms) def on_action_start(self, action: Any, state: Any) -> None: name = getattr(action, "name", repr(action)) logger.info("action_start name=%s", name) def on_action_complete(self, result: Any) -> None: logger.info("action_complete result=%r", result) def on_action_retry( self, action: Any, attempt: int, exception: BaseException, backoff_ms: float, ) -> None: name = getattr(action, "name", repr(action)) logger.info( "action_retry name=%s attempt=%d backoff_ms=%.2f exc=%s: %s", name, attempt, backoff_ms, type(exception).__name__, exception, ) def on_strategy_chosen(self, strategy_name: str) -> None: logger.info("strategy_chosen name=%s", strategy_name) def on_replan(self, reason: str, new_plan: Any) -> None: logger.info("replan reason=%s new_plan=%r", reason, new_plan) def on_goal_achieved(self, final_state: Any) -> None: logger.info("goal_achieved final_state=%r", final_state) def on_sensor_complete(self, sensor_name: str, updates: Any) -> None: logger.info("sensor_complete name=%s updates=%r", sensor_name, updates) async def aon_plan_start(self, goal: Any, state: Any, strategy_name: str) -> None: self.on_plan_start(goal, state, strategy_name) async def aon_plan_complete(self, plan: Any, duration_ms: float) -> None: self.on_plan_complete(plan, duration_ms) async def aon_plan_failed(self, reason: str, duration_ms: float) -> None: self.on_plan_failed(reason, duration_ms) async def aon_action_start(self, action: Any, state: Any) -> None: self.on_action_start(action, state) async def aon_action_complete(self, result: Any) -> None: self.on_action_complete(result) async def aon_action_retry( self, action: Any, attempt: int, exception: BaseException, backoff_ms: float, ) -> None: self.on_action_retry(action, attempt, exception, backoff_ms) async def aon_strategy_chosen(self, strategy_name: str) -> None: self.on_strategy_chosen(strategy_name) async def aon_replan(self, reason: str, new_plan: Any) -> None: self.on_replan(reason, new_plan) async def aon_goal_achieved(self, final_state: Any) -> None: self.on_goal_achieved(final_state) async def aon_sensor_complete(self, sensor_name: str, updates: Any) -> None: self.on_sensor_complete(sensor_name, updates) def on_search_expand( self, node_id: int, state: Any, g: float, h: float, f: float, parent_id: int | None, action_name: str | None, ) -> None: logger.info( "search_expand node=%d parent=%s g=%.3f h=%.3f f=%.3f action=%s", node_id, parent_id, g, h, f, action_name, ) def on_search_dead_end(self, reason: str, detail: dict[str, Any]) -> None: logger.info("search_dead_end reason=%s detail=%r", reason, detail) def on_search_complete( self, nodes_explored: int, duration_ms: float, found: bool ) -> None: logger.info( "search_complete nodes_explored=%d duration_ms=%.2f found=%s", nodes_explored, duration_ms, found, ) async def aon_search_expand( self, node_id: int, state: Any, g: float, h: float, f: float, parent_id: int | None, action_name: str | None, ) -> None: self.on_search_expand(node_id, state, g, h, f, parent_id, action_name) async def aon_search_dead_end(self, reason: str, detail: dict[str, Any]) -> None: self.on_search_dead_end(reason, detail) async def aon_search_complete( self, nodes_explored: int, duration_ms: float, found: bool ) -> None: self.on_search_complete(nodes_explored, duration_ms, found)
__all__ = ["LoggingTracer"]