mirror of
https://github.com/exo-explore/exo.git
synced 2025-12-23 22:27:50 -05:00
feature: Simplest utilities for logging
This commit is contained in:
@@ -1,21 +1,48 @@
|
||||
import logging
|
||||
import logging.handlers
|
||||
from collections.abc import Sequence
|
||||
from collections.abc import Sequence, Set
|
||||
from enum import Enum
|
||||
from queue import Queue
|
||||
|
||||
from pydantic import BaseModel
|
||||
from rich.logging import RichHandler
|
||||
|
||||
|
||||
class LogEntryType(str, Enum):
|
||||
telemetry = "telemetry"
|
||||
metrics = "metrics"
|
||||
cluster = "cluster"
|
||||
|
||||
|
||||
class LogEntry(BaseModel):
|
||||
event_type: Set[LogEntryType]
|
||||
|
||||
|
||||
class LogFilterByType(logging.Filter):
|
||||
def __init__(self, log_types: Set[LogEntryType]):
|
||||
super().__init__()
|
||||
self.log_types = log_types
|
||||
|
||||
def filter(self, record: logging.LogRecord) -> bool:
|
||||
message = record.getMessage()
|
||||
LogEntry.model_validate_json(message)
|
||||
return True
|
||||
|
||||
|
||||
def configure_logger(
|
||||
logger_name: str,
|
||||
log_level: int = logging.INFO,
|
||||
effect_handlers: Sequence[logging.Handler] | None = None,
|
||||
) -> logging.Logger:
|
||||
existing_logger = logging.Logger.manager.loggerDict.get(logger_name)
|
||||
if existing_logger is not None:
|
||||
raise RuntimeError(f"Logger with name '{logger_name}' already exists.")
|
||||
|
||||
logger = logging.getLogger(logger_name)
|
||||
logger.setLevel(log_level)
|
||||
logger.propagate = False
|
||||
logging.raiseExceptions = True
|
||||
|
||||
# If the named logger already has handlers, we assume it has been configured.
|
||||
if logger.hasHandlers():
|
||||
return logger
|
||||
|
||||
@@ -33,13 +60,20 @@ def configure_logger(
|
||||
return logger
|
||||
|
||||
|
||||
def attach_to_queue(logger: logging.Logger, queue: Queue[logging.LogRecord]) -> None:
|
||||
logger.addHandler(logging.handlers.QueueHandler(queue))
|
||||
def attach_to_queue(
|
||||
logger: logging.Logger,
|
||||
filter_with: Sequence[logging.Filter],
|
||||
queue: Queue[logging.LogRecord],
|
||||
) -> None:
|
||||
handler = logging.handlers.QueueHandler(queue)
|
||||
for log_filter in filter_with:
|
||||
handler.addFilter(log_filter)
|
||||
logger.addHandler(handler)
|
||||
|
||||
|
||||
def create_queue_listener(
|
||||
log_queue: Queue[logging.LogRecord],
|
||||
effect_handlers: list[logging.Handler],
|
||||
effect_handlers: Sequence[logging.Handler],
|
||||
) -> logging.handlers.QueueListener:
|
||||
listener = logging.handlers.QueueListener(
|
||||
log_queue, *effect_handlers, respect_handler_level=True
|
||||
|
||||
@@ -10,7 +10,6 @@ dependencies = [
|
||||
"protobuf>=6.31.1",
|
||||
"pydantic>=2.11.7",
|
||||
"rich>=14.0.0",
|
||||
"structlog>=25.4.0",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
|
||||
11
uv.lock
generated
11
uv.lock
generated
@@ -141,7 +141,6 @@ dependencies = [
|
||||
{ name = "protobuf", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
||||
{ name = "pydantic", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
||||
{ name = "rich", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
||||
{ name = "structlog", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
||||
]
|
||||
|
||||
[package.dev-dependencies]
|
||||
@@ -156,7 +155,6 @@ requires-dist = [
|
||||
{ name = "protobuf", specifier = ">=6.31.1" },
|
||||
{ name = "pydantic", specifier = ">=2.11.7" },
|
||||
{ name = "rich", specifier = ">=14.0.0" },
|
||||
{ name = "structlog", specifier = ">=25.4.0" },
|
||||
]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
@@ -488,15 +486,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structlog"
|
||||
version = "25.4.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/79/b9/6e672db4fec07349e7a8a8172c1a6ae235c58679ca29c3f86a61b5e59ff3/structlog-25.4.0.tar.gz", hash = "sha256:186cd1b0a8ae762e29417095664adf1d6a31702160a46dacb7796ea82f7409e4", size = 1369138, upload-time = "2025-06-02T08:21:12.971Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/4a/97ee6973e3a73c74c8120d59829c3861ea52210667ec3e7a16045c62b64d/structlog-25.4.0-py3-none-any.whl", hash = "sha256:fe809ff5c27e557d14e613f45ca441aabda051d119ee5a0102aaba6ce40eed2c", size = 68720, upload-time = "2025-06-02T08:21:11.43Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tqdm"
|
||||
version = "4.67.1"
|
||||
|
||||
Reference in New Issue
Block a user