fix: resolve CI failures from workflow rewrite
All checks were successful
API Endpoint Tests / test-api-endpoints (push) Successful in 29s
Integration Tests / test-service-integration (push) Successful in 44s
Package Tests / test-python-packages (map[name:aitbc-agent-sdk path:packages/py/aitbc-agent-sdk]) (push) Successful in 35s
Package Tests / test-python-packages (map[name:aitbc-core path:packages/py/aitbc-core]) (push) Successful in 24s
Package Tests / test-python-packages (map[name:aitbc-crypto path:packages/py/aitbc-crypto]) (push) Successful in 21s
Package Tests / test-python-packages (map[name:aitbc-sdk path:packages/py/aitbc-sdk]) (push) Successful in 25s
Package Tests / test-javascript-packages (map[name:aitbc-sdk-js path:packages/js/aitbc-sdk]) (push) Successful in 20s
Package Tests / test-javascript-packages (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Successful in 30s
Python Tests / test-python (push) Successful in 1m18s
Systemd Sync / sync-systemd (push) Successful in 2s
Security Scanning / security-scan (push) Successful in 1m14s
All checks were successful
API Endpoint Tests / test-api-endpoints (push) Successful in 29s
Integration Tests / test-service-integration (push) Successful in 44s
Package Tests / test-python-packages (map[name:aitbc-agent-sdk path:packages/py/aitbc-agent-sdk]) (push) Successful in 35s
Package Tests / test-python-packages (map[name:aitbc-core path:packages/py/aitbc-core]) (push) Successful in 24s
Package Tests / test-python-packages (map[name:aitbc-crypto path:packages/py/aitbc-crypto]) (push) Successful in 21s
Package Tests / test-python-packages (map[name:aitbc-sdk path:packages/py/aitbc-sdk]) (push) Successful in 25s
Package Tests / test-javascript-packages (map[name:aitbc-sdk-js path:packages/js/aitbc-sdk]) (push) Successful in 20s
Package Tests / test-javascript-packages (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Successful in 30s
Python Tests / test-python (push) Successful in 1m18s
Systemd Sync / sync-systemd (push) Successful in 2s
Security Scanning / security-scan (push) Successful in 1m14s
Fixes based on first CI run results: Workflow fixes: - python-tests.yml: Add pytest-timeout and click to pip install (--timeout=30 unrecognized, conftest.py needs click) - integration-tests.yml: Add click, pytest-timeout to pip install Fix systemctl status capture (multiline output in subshell) - systemd-sync.yml: Fix printf output — $(cmd || echo) captures multiline; use $(cmd) || var=fallback instead - test_api_endpoints.py: Count 404/405 as reachable in perf test (APIs return 404 on root but are running) Missing module fixes: - aitbc-agent-sdk: Create compute_consumer.py and platform_builder.py (__init__.py imported them but files didn't exist) - aitbc-core: Create logging.py module with StructuredLogFormatter, setup_logger, get_audit_logger (tests existed but module was missing) Fix __init__.py duplicate imports
This commit is contained in:
@@ -2,10 +2,6 @@
|
||||
AITBC Core Utilities
|
||||
"""
|
||||
|
||||
from . import logging
|
||||
|
||||
__all__ = ["logging"]
|
||||
|
||||
from . import logging
|
||||
from . import logging # noqa: F811 — aitbc.logging submodule, not stdlib
|
||||
|
||||
__all__ = ["logging"]
|
||||
|
||||
87
packages/py/aitbc-core/src/aitbc/logging.py
Normal file
87
packages/py/aitbc-core/src/aitbc/logging.py
Normal file
@@ -0,0 +1,87 @@
|
||||
"""
|
||||
AITBC Structured Logging Module
|
||||
|
||||
Provides JSON-formatted structured logging for all AITBC services.
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class StructuredLogFormatter(logging.Formatter):
|
||||
"""JSON structured log formatter for AITBC services."""
|
||||
|
||||
def __init__(self, service_name: str, env: str = "production"):
|
||||
super().__init__()
|
||||
self.service_name = service_name
|
||||
self.env = env
|
||||
|
||||
def format(self, record: logging.LogRecord) -> str:
|
||||
log_data = {
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"service": self.service_name,
|
||||
"env": self.env,
|
||||
"level": record.levelname,
|
||||
"logger": record.name,
|
||||
"message": record.getMessage(),
|
||||
}
|
||||
|
||||
if record.exc_info and record.exc_info[0] is not None:
|
||||
log_data["exception"] = self.formatException(record.exc_info)
|
||||
|
||||
# Include extra fields
|
||||
skip_fields = {
|
||||
"name", "msg", "args", "created", "relativeCreated",
|
||||
"exc_info", "exc_text", "stack_info", "lineno", "funcName",
|
||||
"pathname", "filename", "module", "levelno", "levelname",
|
||||
"msecs", "thread", "threadName", "process", "processName",
|
||||
"taskName", "message",
|
||||
}
|
||||
for key, value in record.__dict__.items():
|
||||
if key not in skip_fields and not key.startswith("_"):
|
||||
try:
|
||||
json.dumps(value)
|
||||
log_data[key] = value
|
||||
except (TypeError, ValueError):
|
||||
log_data[key] = str(value)
|
||||
|
||||
return json.dumps(log_data)
|
||||
|
||||
|
||||
def setup_logger(
|
||||
name: str,
|
||||
service_name: str,
|
||||
env: str = "production",
|
||||
level: int = logging.INFO,
|
||||
log_file: Optional[str] = None,
|
||||
) -> logging.Logger:
|
||||
"""Set up a structured logger for an AITBC service."""
|
||||
logger = logging.getLogger(name)
|
||||
logger.setLevel(level)
|
||||
|
||||
# Remove existing handlers to avoid duplicates
|
||||
logger.handlers.clear()
|
||||
|
||||
formatter = StructuredLogFormatter(service_name=service_name, env=env)
|
||||
|
||||
# Console handler (stdout)
|
||||
console_handler = logging.StreamHandler(sys.stdout)
|
||||
console_handler.setFormatter(formatter)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
# Optional file handler
|
||||
if log_file:
|
||||
file_handler = logging.FileHandler(log_file)
|
||||
file_handler.setFormatter(formatter)
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
return logger
|
||||
|
||||
|
||||
def get_audit_logger(service_name: str, env: str = "production") -> logging.Logger:
|
||||
"""Get or create an audit logger for a service."""
|
||||
audit_name = f"{service_name}.audit"
|
||||
return setup_logger(name=audit_name, service_name=service_name, env=env)
|
||||
Reference in New Issue
Block a user