semantic markup update
This commit is contained in:
@@ -22,12 +22,19 @@ _enable_belief_state = True
|
||||
# [DEF:BeliefFormatter:Class]
|
||||
# @PURPOSE: Custom logging formatter that adds belief state prefixes to log messages.
|
||||
class BeliefFormatter(logging.Formatter):
|
||||
# [DEF:format:Function]
|
||||
# @PURPOSE: Formats the log record, adding belief state context if available.
|
||||
# @PRE: record is a logging.LogRecord.
|
||||
# @POST: Returns formatted string.
|
||||
# @PARAM: record (logging.LogRecord) - The log record to format.
|
||||
# @RETURN: str - The formatted log message.
|
||||
def format(self, record):
|
||||
msg = super().format(record)
|
||||
anchor_id = getattr(_belief_state, 'anchor_id', None)
|
||||
if anchor_id:
|
||||
msg = f"[{anchor_id}][Action] {msg}"
|
||||
return msg
|
||||
# [/DEF:format:Function]
|
||||
# [/DEF:BeliefFormatter:Class]
|
||||
|
||||
# Re-using LogEntry from task_manager for consistency
|
||||
@@ -42,8 +49,12 @@ class LogEntry(BaseModel):
|
||||
|
||||
# [/DEF:LogEntry:Class]
|
||||
|
||||
# [DEF:BeliefScope:Function]
|
||||
# [DEF:belief_scope:Function]
|
||||
# @PURPOSE: Context manager for structured Belief State logging.
|
||||
# @PARAM: anchor_id (str) - The identifier for the current semantic block.
|
||||
# @PARAM: message (str) - Optional entry message.
|
||||
# @PRE: anchor_id must be provided.
|
||||
# @POST: Thread-local belief state is updated and entry/exit logs are generated.
|
||||
@contextmanager
|
||||
def belief_scope(anchor_id: str, message: str = ""):
|
||||
# Log Entry if enabled
|
||||
@@ -71,9 +82,9 @@ def belief_scope(anchor_id: str, message: str = ""):
|
||||
# Restore old anchor
|
||||
_belief_state.anchor_id = old_anchor
|
||||
|
||||
# [/DEF:BeliefScope:Function]
|
||||
# [/DEF:belief_scope:Function]
|
||||
|
||||
# [DEF:ConfigureLogger:Function]
|
||||
# [DEF:configure_logger:Function]
|
||||
# @PURPOSE: Configures the logger with the provided logging settings.
|
||||
# @PRE: config is a valid LoggingConfig instance.
|
||||
# @POST: Logger level, handlers, and belief state flag are updated.
|
||||
@@ -115,7 +126,7 @@ def configure_logger(config):
|
||||
handler.setFormatter(BeliefFormatter(
|
||||
'[%(asctime)s][%(levelname)s][%(name)s] %(message)s'
|
||||
))
|
||||
# [/DEF:ConfigureLogger:Function]
|
||||
# [/DEF:configure_logger:Function]
|
||||
|
||||
# [DEF:WebSocketLogHandler:Class]
|
||||
# @SEMANTICS: logging, handler, websocket, buffer
|
||||
@@ -125,38 +136,59 @@ class WebSocketLogHandler(logging.Handler):
|
||||
A logging handler that stores log records and can be extended to send them
|
||||
over WebSockets.
|
||||
"""
|
||||
# [DEF:__init__:Function]
|
||||
# @PURPOSE: Initializes the handler with a fixed-capacity buffer.
|
||||
# @PRE: capacity is an integer.
|
||||
# @POST: Instance initialized with empty deque.
|
||||
# @PARAM: capacity (int) - Maximum number of logs to keep in memory.
|
||||
def __init__(self, capacity: int = 1000):
|
||||
super().__init__()
|
||||
self.log_buffer: deque[LogEntry] = deque(maxlen=capacity)
|
||||
with belief_scope("WebSocketLogHandler.__init__"):
|
||||
super().__init__()
|
||||
self.log_buffer: deque[LogEntry] = deque(maxlen=capacity)
|
||||
# In a real implementation, you'd have a way to manage active WebSocket connections
|
||||
# e.g., self.active_connections: Set[WebSocket] = set()
|
||||
# [/DEF:__init__:Function]
|
||||
|
||||
# [DEF:emit:Function]
|
||||
# @PURPOSE: Captures a log record, formats it, and stores it in the buffer.
|
||||
# @PRE: record is a logging.LogRecord.
|
||||
# @POST: Log is added to the log_buffer.
|
||||
# @PARAM: record (logging.LogRecord) - The log record to emit.
|
||||
def emit(self, record: logging.LogRecord):
|
||||
try:
|
||||
log_entry = LogEntry(
|
||||
level=record.levelname,
|
||||
message=self.format(record),
|
||||
context={
|
||||
"name": record.name,
|
||||
"pathname": record.pathname,
|
||||
"lineno": record.lineno,
|
||||
"funcName": record.funcName,
|
||||
"process": record.process,
|
||||
"thread": record.thread,
|
||||
}
|
||||
)
|
||||
self.log_buffer.append(log_entry)
|
||||
# Here you would typically send the log_entry to all active WebSocket connections
|
||||
# for real-time streaming to the frontend.
|
||||
# Example: for ws in self.active_connections: await ws.send_json(log_entry.dict())
|
||||
except Exception:
|
||||
self.handleError(record)
|
||||
with belief_scope("WebSocketLogHandler.emit"):
|
||||
try:
|
||||
log_entry = LogEntry(
|
||||
level=record.levelname,
|
||||
message=self.format(record),
|
||||
context={
|
||||
"name": record.name,
|
||||
"pathname": record.pathname,
|
||||
"lineno": record.lineno,
|
||||
"funcName": record.funcName,
|
||||
"process": record.process,
|
||||
"thread": record.thread,
|
||||
}
|
||||
)
|
||||
self.log_buffer.append(log_entry)
|
||||
# Here you would typically send the log_entry to all active WebSocket connections
|
||||
# for real-time streaming to the frontend.
|
||||
# Example: for ws in self.active_connections: await ws.send_json(log_entry.dict())
|
||||
except Exception:
|
||||
self.handleError(record)
|
||||
# [/DEF:emit:Function]
|
||||
|
||||
# [DEF:get_recent_logs:Function]
|
||||
# @PURPOSE: Returns a list of recent log entries from the buffer.
|
||||
# @PRE: None.
|
||||
# @POST: Returns list of LogEntry objects.
|
||||
# @RETURN: List[LogEntry] - List of buffered log entries.
|
||||
def get_recent_logs(self) -> List[LogEntry]:
|
||||
"""
|
||||
Returns a list of recent log entries from the buffer.
|
||||
"""
|
||||
return list(self.log_buffer)
|
||||
with belief_scope("WebSocketLogHandler.get_recent_logs"):
|
||||
"""
|
||||
Returns a list of recent log entries from the buffer.
|
||||
"""
|
||||
return list(self.log_buffer)
|
||||
# [/DEF:get_recent_logs:Function]
|
||||
|
||||
# [/DEF:WebSocketLogHandler:Class]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user