Skip to content

datarobot_genai.crewai.logging_events

logging_events

Real-time logging of CrewAI agent/task/tool lifecycle events.

CrewAI's per-step detail (which agent, which tool, with what args and result) never reaches the Python logger on its own, so a dragent run shows little more than a stream of LiteLLM calls. This listener subscribes to the CrewAI event bus and logs that lifecycle as it happens.

CrewAILoggingEventListener

Logs the CrewAI agent/task/tool lifecycle for dragent observability.

Source code in datarobot_genai/crewai/logging_events.py
class CrewAILoggingEventListener:
    """Logs the CrewAI agent/task/tool lifecycle for dragent observability."""

    def setup_listeners(self, crewai_event_bus: CrewAIEventsBus) -> None:
        def _register(event_type: Any, render: Any) -> None:
            @crewai_event_bus.on(event_type)
            def _handler(_: Any, event: Any) -> None:
                # CrewAI's bus already isolates handler exceptions; swallow here too so a
                # malformed payload logs at DEBUG instead of the bus's error level.
                try:
                    render(event)
                except Exception:
                    logger.debug("CrewAI logging handler error", exc_info=True)

        _register(
            CrewKickoffStartedEvent,
            lambda e: logger.debug("crew kickoff: inputs=%s", _truncate(getattr(e, "inputs", ""))),
        )
        _register(
            AgentExecutionStartedEvent,
            lambda e: logger.info("[%s] agent started", _role(e)),
        )
        _register(
            TaskStartedEvent,
            lambda e: logger.info("[%s] task started: %s", _role(e), _truncate(_task_name(e))),
        )
        _register(
            TaskCompletedEvent,
            lambda e: logger.info(
                "[%s] task completed: %s", _role(e), _truncate(getattr(e, "output", ""))
            ),
        )
        _register(
            TaskFailedEvent,
            lambda e: logger.warning(
                "[%s] task failed: %s", _role(e), _truncate(getattr(e, "error", ""))
            ),
        )
        _register(
            ToolUsageStartedEvent,
            lambda e: logger.info(
                "[%s] tool call: %s(%s) attempt=%s",
                _role(e),
                getattr(e, "tool_name", ""),
                _truncate(getattr(e, "tool_args", "")),
                getattr(e, "run_attempts", ""),
            ),
        )
        _register(
            ToolUsageFinishedEvent,
            lambda e: logger.info(
                "[%s] tool %s -> %s",
                _role(e),
                getattr(e, "tool_name", ""),
                _truncate(getattr(e, "output", "")),
            ),
        )
        _register(
            ToolUsageErrorEvent,
            lambda e: logger.warning(
                "[%s] tool %s error: %s",
                _role(e),
                getattr(e, "tool_name", ""),
                _truncate(getattr(e, "error", "")),
            ),
        )
        _register(
            AgentReasoningStartedEvent,
            lambda e: logger.debug("[%s] reasoning started", _role(e)),
        )
        _register(
            AgentReasoningCompletedEvent,
            lambda e: logger.debug("[%s] reasoning completed", _role(e)),
        )
        _register(
            AgentReasoningFailedEvent,
            lambda e: logger.debug("[%s] reasoning failed", _role(e)),
        )