import threading from collections import deque from datetime import datetime _requests_lock = threading.Lock() _requests = deque(maxlen=500) def register_request(trace_id, client_ip, endpoint, request_body_summary=None): entry = { 'trace_id': trace_id, 'request_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'client_ip': client_ip or '-', 'endpoint': endpoint, 'status': 'running', 'response_status': None, 'elapsed_ms': None, 'request_summary': request_body_summary or {}, 'response_summary': None, 'warnings': [], 'error_message': None, } with _requests_lock: _requests.append(entry) return entry def update_request(trace_id, **fields): with _requests_lock: for entry in _requests: if entry['trace_id'] == trace_id: entry.update(fields) return entry return None def finish_request(trace_id, status, response_status=None, elapsed_ms=None, response_summary=None, warnings=None, error_message=None): return update_request( trace_id, status=status, response_status=response_status, elapsed_ms=elapsed_ms, response_summary=response_summary, warnings=warnings or [], error_message=error_message, ) def query_requests(status=None, keyword=None, limit=200): limit = max(1, min(int(limit or 200), 500)) keyword_lc = (keyword or '').lower().strip() items = [] with _requests_lock: snapshot = list(_requests) snapshot.reverse() for entry in snapshot: if status and entry.get('status') != status: continue if keyword_lc: hay = ' '.join(str(entry.get(k) or '') for k in ('trace_id', 'client_ip', 'endpoint')).lower() if keyword_lc not in hay: continue items.append(entry) if len(items) >= limit: break return items def get_request(trace_id): with _requests_lock: for entry in reversed(_requests): if entry['trace_id'] == trace_id: return entry return None