feat: enhance logging configuration and add request logging context
This commit is contained in:
@@ -10,6 +10,7 @@ from fastapi import HTTPException, status
|
||||
from sqlmodel import col
|
||||
|
||||
from app.core.auth import AuthContext
|
||||
from app.core.logging import TRACE_LEVEL
|
||||
from app.core.time import utcnow
|
||||
from app.db import crud
|
||||
from app.models.activity_events import ActivityEvent
|
||||
@@ -256,7 +257,7 @@ class GatewayAdminLifecycleService(OpenClawDBService):
|
||||
action: str = "provision",
|
||||
) -> Agent:
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"gateway.main_agent.ensure.start gateway_id=%s action=%s",
|
||||
gateway.id,
|
||||
action,
|
||||
@@ -331,7 +332,7 @@ class GatewayAdminLifecycleService(OpenClawDBService):
|
||||
auth: AuthContext,
|
||||
) -> GatewayTemplatesSyncResult:
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"gateway.templates.sync.start gateway_id=%s include_main=%s",
|
||||
gateway.id,
|
||||
query.include_main,
|
||||
|
||||
@@ -12,6 +12,7 @@ from fastapi import HTTPException, status
|
||||
from sqlmodel import col, select
|
||||
|
||||
from app.core.config import settings
|
||||
from app.core.logging import TRACE_LEVEL
|
||||
from app.core.time import utcnow
|
||||
from app.models.agents import Agent
|
||||
from app.models.boards import Board
|
||||
@@ -172,7 +173,7 @@ class GatewayCoordinationService(AbstractGatewayMessagingService):
|
||||
) -> None:
|
||||
trace_id = GatewayDispatchService.resolve_trace_id(correlation_id, prefix="coord.nudge")
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"gateway.coordination.nudge.start trace_id=%s board_id=%s actor_agent_id=%s "
|
||||
"target_agent_id=%s",
|
||||
trace_id,
|
||||
@@ -252,7 +253,7 @@ class GatewayCoordinationService(AbstractGatewayMessagingService):
|
||||
) -> str:
|
||||
trace_id = GatewayDispatchService.resolve_trace_id(correlation_id, prefix="coord.soul.read")
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"gateway.coordination.soul_read.start trace_id=%s board_id=%s target_agent_id=%s",
|
||||
trace_id,
|
||||
board.id,
|
||||
@@ -322,7 +323,7 @@ class GatewayCoordinationService(AbstractGatewayMessagingService):
|
||||
correlation_id, prefix="coord.soul.write"
|
||||
)
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"gateway.coordination.soul_write.start trace_id=%s board_id=%s target_agent_id=%s "
|
||||
"actor_agent_id=%s",
|
||||
trace_id,
|
||||
@@ -418,7 +419,7 @@ class GatewayCoordinationService(AbstractGatewayMessagingService):
|
||||
payload.correlation_id, prefix="coord.ask_user"
|
||||
)
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"gateway.coordination.ask_user.start trace_id=%s board_id=%s actor_agent_id=%s",
|
||||
trace_id,
|
||||
board.id,
|
||||
@@ -563,7 +564,7 @@ class GatewayCoordinationService(AbstractGatewayMessagingService):
|
||||
payload.correlation_id, prefix="coord.lead_message"
|
||||
)
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"gateway.coordination.lead_message.start trace_id=%s board_id=%s actor_agent_id=%s",
|
||||
trace_id,
|
||||
board_id,
|
||||
@@ -652,7 +653,7 @@ class GatewayCoordinationService(AbstractGatewayMessagingService):
|
||||
payload.correlation_id, prefix="coord.lead_broadcast"
|
||||
)
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"gateway.coordination.lead_broadcast.start trace_id=%s actor_agent_id=%s",
|
||||
trace_id,
|
||||
actor_agent.id,
|
||||
|
||||
@@ -6,9 +6,11 @@ OpenClaw services without adding new architectural layers.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from logging import Logger
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from app.core.logging import get_logger
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
|
||||
@@ -19,7 +21,7 @@ class OpenClawDBService:
|
||||
def __init__(self, session: AsyncSession) -> None:
|
||||
self._session = session
|
||||
# Use the concrete subclass module for logger naming.
|
||||
self._logger = logging.getLogger(self.__class__.__module__)
|
||||
self._logger = get_logger(self.__class__.__module__)
|
||||
|
||||
@property
|
||||
def session(self) -> AsyncSession:
|
||||
@@ -30,11 +32,11 @@ class OpenClawDBService:
|
||||
self._session = value
|
||||
|
||||
@property
|
||||
def logger(self) -> logging.Logger:
|
||||
def logger(self) -> Logger:
|
||||
return self._logger
|
||||
|
||||
@logger.setter
|
||||
def logger(self, value: logging.Logger) -> None:
|
||||
def logger(self, value: Logger) -> None:
|
||||
self._logger = value
|
||||
|
||||
async def add_commit_refresh(self, model: object) -> None:
|
||||
|
||||
@@ -10,6 +10,7 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
from time import perf_counter
|
||||
from typing import Any
|
||||
from urllib.parse import urlencode, urlparse, urlunparse
|
||||
from uuid import uuid4
|
||||
@@ -17,7 +18,10 @@ from uuid import uuid4
|
||||
import websockets
|
||||
from websockets.exceptions import WebSocketException
|
||||
|
||||
from app.core.logging import TRACE_LEVEL, get_logger
|
||||
|
||||
PROTOCOL_VERSION = 3
|
||||
logger = get_logger(__name__)
|
||||
|
||||
# NOTE: These are the base gateway methods from the OpenClaw gateway repo.
|
||||
# The gateway can expose additional methods at runtime via channel plugins.
|
||||
@@ -165,6 +169,11 @@ def _build_gateway_url(config: GatewayConfig) -> str:
|
||||
return str(urlunparse(parsed._replace(query=query)))
|
||||
|
||||
|
||||
def _redacted_url_for_log(raw_url: str) -> str:
|
||||
parsed = urlparse(raw_url)
|
||||
return str(urlunparse(parsed._replace(query="", fragment="")))
|
||||
|
||||
|
||||
async def _await_response(
|
||||
ws: websockets.ClientConnection,
|
||||
request_id: str,
|
||||
@@ -172,6 +181,12 @@ async def _await_response(
|
||||
while True:
|
||||
raw = await ws.recv()
|
||||
data = json.loads(raw)
|
||||
logger.log(
|
||||
TRACE_LEVEL,
|
||||
"gateway.rpc.recv request_id=%s type=%s",
|
||||
request_id,
|
||||
data.get("type"),
|
||||
)
|
||||
|
||||
if data.get("type") == "res" and data.get("id") == request_id:
|
||||
ok = data.get("ok")
|
||||
@@ -199,6 +214,13 @@ async def _send_request(
|
||||
"method": method,
|
||||
"params": params or {},
|
||||
}
|
||||
logger.log(
|
||||
TRACE_LEVEL,
|
||||
"gateway.rpc.send method=%s request_id=%s params_keys=%s",
|
||||
method,
|
||||
request_id,
|
||||
sorted((params or {}).keys()),
|
||||
)
|
||||
await ws.send(json.dumps(message))
|
||||
return await _await_response(ws, request_id)
|
||||
|
||||
@@ -229,7 +251,11 @@ async def _ensure_connected(
|
||||
first_message = first_message.decode("utf-8")
|
||||
data = json.loads(first_message)
|
||||
if data.get("type") != "event" or data.get("event") != "connect.challenge":
|
||||
pass
|
||||
logger.warning(
|
||||
"gateway.rpc.connect.unexpected_first_message type=%s event=%s",
|
||||
data.get("type"),
|
||||
data.get("event"),
|
||||
)
|
||||
connect_id = str(uuid4())
|
||||
response = {
|
||||
"type": "req",
|
||||
@@ -249,6 +275,12 @@ async def openclaw_call(
|
||||
) -> object:
|
||||
"""Call a gateway RPC method and return the result payload."""
|
||||
gateway_url = _build_gateway_url(config)
|
||||
started_at = perf_counter()
|
||||
logger.debug(
|
||||
"gateway.rpc.call.start method=%s gateway_url=%s",
|
||||
method,
|
||||
_redacted_url_for_log(gateway_url),
|
||||
)
|
||||
try:
|
||||
async with websockets.connect(gateway_url, ping_interval=None) as ws:
|
||||
first_message = None
|
||||
@@ -257,8 +289,19 @@ async def openclaw_call(
|
||||
except TimeoutError:
|
||||
first_message = None
|
||||
await _ensure_connected(ws, first_message, config)
|
||||
return await _send_request(ws, method, params)
|
||||
payload = await _send_request(ws, method, params)
|
||||
logger.debug(
|
||||
"gateway.rpc.call.success method=%s duration_ms=%s",
|
||||
method,
|
||||
int((perf_counter() - started_at) * 1000),
|
||||
)
|
||||
return payload
|
||||
except OpenClawGatewayError:
|
||||
logger.warning(
|
||||
"gateway.rpc.call.gateway_error method=%s duration_ms=%s",
|
||||
method,
|
||||
int((perf_counter() - started_at) * 1000),
|
||||
)
|
||||
raise
|
||||
except (
|
||||
TimeoutError,
|
||||
@@ -267,6 +310,12 @@ async def openclaw_call(
|
||||
ValueError,
|
||||
WebSocketException,
|
||||
) as exc: # pragma: no cover - network/protocol errors
|
||||
logger.error(
|
||||
"gateway.rpc.call.transport_error method=%s duration_ms=%s error_type=%s",
|
||||
method,
|
||||
int((perf_counter() - started_at) * 1000),
|
||||
exc.__class__.__name__,
|
||||
)
|
||||
raise OpenClawGatewayError(str(exc)) from exc
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from app.core.logging import TRACE_LEVEL
|
||||
from app.models.board_onboarding import BoardOnboardingSession
|
||||
from app.models.boards import Board
|
||||
from app.services.openclaw.coordination_service import AbstractGatewayMessagingService
|
||||
@@ -25,7 +26,7 @@ class BoardOnboardingMessagingService(AbstractGatewayMessagingService):
|
||||
correlation_id, prefix="onboarding.start"
|
||||
)
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"gateway.onboarding.start_dispatch.start trace_id=%s board_id=%s",
|
||||
trace_id,
|
||||
board.id,
|
||||
@@ -83,7 +84,7 @@ class BoardOnboardingMessagingService(AbstractGatewayMessagingService):
|
||||
correlation_id, prefix="onboarding.answer"
|
||||
)
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"gateway.onboarding.answer_dispatch.start trace_id=%s board_id=%s onboarding_id=%s",
|
||||
trace_id,
|
||||
board.id,
|
||||
|
||||
@@ -22,6 +22,7 @@ from sqlmodel import col, select
|
||||
from sse_starlette.sse import EventSourceResponse
|
||||
|
||||
from app.core.agent_tokens import verify_agent_token
|
||||
from app.core.logging import TRACE_LEVEL
|
||||
from app.core.time import utcnow
|
||||
from app.db import crud
|
||||
from app.db.pagination import paginate
|
||||
@@ -983,7 +984,7 @@ class AgentLifecycleService(OpenClawDBService):
|
||||
raise_gateway_errors: bool,
|
||||
) -> None:
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"agent.provision.start action=%s agent_id=%s target_main=%s",
|
||||
action,
|
||||
agent.id,
|
||||
@@ -1471,7 +1472,7 @@ class AgentLifecycleService(OpenClawDBService):
|
||||
actor: ActorContextLike,
|
||||
) -> AgentRead:
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"agent.create.start actor_type=%s board_id=%s",
|
||||
actor.actor_type,
|
||||
payload.board_id,
|
||||
@@ -1523,7 +1524,12 @@ class AgentLifecycleService(OpenClawDBService):
|
||||
payload: AgentUpdate,
|
||||
options: AgentUpdateOptions,
|
||||
) -> AgentRead:
|
||||
self.logger.log(5, "agent.update.start agent_id=%s force=%s", agent_id, options.force)
|
||||
self.logger.log(
|
||||
TRACE_LEVEL,
|
||||
"agent.update.start agent_id=%s force=%s",
|
||||
agent_id,
|
||||
options.force,
|
||||
)
|
||||
agent = await Agent.objects.by_id(agent_id).first(self.session)
|
||||
if agent is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||
@@ -1573,7 +1579,10 @@ class AgentLifecycleService(OpenClawDBService):
|
||||
actor: ActorContextLike,
|
||||
) -> AgentRead:
|
||||
self.logger.log(
|
||||
5, "agent.heartbeat.start agent_id=%s actor_type=%s", agent_id, actor.actor_type
|
||||
TRACE_LEVEL,
|
||||
"agent.heartbeat.start agent_id=%s actor_type=%s",
|
||||
agent_id,
|
||||
actor.actor_type,
|
||||
)
|
||||
agent = await Agent.objects.by_id(agent_id).first(self.session)
|
||||
if agent is None:
|
||||
@@ -1599,7 +1608,7 @@ class AgentLifecycleService(OpenClawDBService):
|
||||
actor: ActorContextLike,
|
||||
) -> AgentRead:
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"agent.heartbeat_or_create.start actor_type=%s name=%s board_id=%s",
|
||||
actor.actor_type,
|
||||
payload.name,
|
||||
@@ -1644,7 +1653,7 @@ class AgentLifecycleService(OpenClawDBService):
|
||||
agent_id: str,
|
||||
ctx: OrganizationContext,
|
||||
) -> OkResponse:
|
||||
self.logger.log(5, "agent.delete.start agent_id=%s", agent_id)
|
||||
self.logger.log(TRACE_LEVEL, "agent.delete.start agent_id=%s", agent_id)
|
||||
agent = await Agent.objects.by_id(agent_id).first(self.session)
|
||||
if agent is None:
|
||||
return OkResponse()
|
||||
|
||||
@@ -9,6 +9,7 @@ from uuid import UUID
|
||||
|
||||
from fastapi import HTTPException, status
|
||||
|
||||
from app.core.logging import TRACE_LEVEL
|
||||
from app.models.boards import Board
|
||||
from app.schemas.gateway_api import (
|
||||
GatewayResolveQuery,
|
||||
@@ -88,7 +89,7 @@ class GatewaySessionService(OpenClawDBService):
|
||||
user: User | None = None,
|
||||
) -> tuple[Board | None, GatewayClientConfig, str | None]:
|
||||
self.logger.log(
|
||||
5,
|
||||
TRACE_LEVEL,
|
||||
"gateway.resolve.start board_id=%s gateway_url=%s",
|
||||
params.board_id,
|
||||
params.gateway_url,
|
||||
|
||||
Reference in New Issue
Block a user