Skip to content

Commit 7740723

Browse files
authored
Add experimental option to use the rich logging handler (#1810)
1 parent d63e183 commit 7740723

File tree

1 file changed

+71
-4
lines changed

1 file changed

+71
-4
lines changed

src/oumi/utils/logging.py

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def configure_logger(
7878

7979
device_rank = _detect_rank()
8080

81-
formatter = logging.Formatter(
81+
default_formatter = logging.Formatter(
8282
"[%(asctime)s][%(name)s]"
8383
f"[rank{device_rank}]"
8484
"[pid:%(process)d][%(threadName)s]"
@@ -87,8 +87,12 @@ def configure_logger(
8787

8888
# Add a console handler to the logger for only global leader.
8989
if device_rank == 0:
90-
console_handler = logging.StreamHandler(sys.stdout)
91-
console_handler.setFormatter(formatter)
90+
if _should_use_rich_logging():
91+
console_handler = _configure_rich_handler(device_rank, level)
92+
else:
93+
console_handler = logging.StreamHandler(sys.stdout)
94+
console_handler.setFormatter(default_formatter)
95+
9296
console_handler.setLevel(level.upper())
9397
logger.addHandler(console_handler)
9498

@@ -98,13 +102,76 @@ def configure_logger(
98102
log_dir.mkdir(parents=True, exist_ok=True)
99103

100104
file_handler = logging.FileHandler(log_dir / f"rank_{device_rank:04d}.log")
101-
file_handler.setFormatter(formatter)
105+
file_handler.setFormatter(default_formatter)
102106
file_handler.setLevel(level.upper())
103107
logger.addHandler(file_handler)
104108

105109
logger.propagate = False
106110

107111

112+
def _should_use_rich_logging() -> bool:
113+
"""Determines if rich logging should be used based on environment variables.
114+
115+
Note: Rich logging is experimental, and may be removed in the future.
116+
Currently it is disabled by default.
117+
"""
118+
# Check if explicitly disabled
119+
if os.environ.get("OUMI_ENABLE_RICH_LOGGING", "").lower() in (
120+
"1",
121+
"yes",
122+
"on",
123+
"true",
124+
"y",
125+
):
126+
return sys.stdout.isatty() # is in a terminal
127+
128+
return False
129+
130+
131+
def _configure_rich_handler(
132+
device_rank: int,
133+
level: str,
134+
) -> logging.Handler:
135+
"""Configures a rich logging handler."""
136+
try:
137+
from rich.console import Console
138+
from rich.logging import RichHandler
139+
from rich.traceback import install
140+
except ImportError:
141+
raise ImportError(
142+
"Rich logging is not installed. Please install it with `pip install rich`."
143+
)
144+
145+
use_detailed_logging = level.upper() == "DEBUG"
146+
147+
if use_detailed_logging:
148+
# Add extra logging for debugging
149+
install(show_locals=True, suppress=[])
150+
151+
console = Console()
152+
console_handler = RichHandler(
153+
console=console,
154+
show_time=True,
155+
show_level=True,
156+
show_path=True,
157+
enable_link_path=True,
158+
markup=False,
159+
rich_tracebacks=use_detailed_logging,
160+
tracebacks_show_locals=use_detailed_logging,
161+
locals_max_length=20,
162+
locals_max_string=80,
163+
)
164+
165+
if use_detailed_logging:
166+
rich_formatter = logging.Formatter(
167+
f"[rank-{device_rank}][pid-%(process)d][%(threadName)s] %(message)s"
168+
)
169+
else:
170+
rich_formatter = logging.Formatter(f"[rank-{device_rank}] %(message)s")
171+
console_handler.setFormatter(rich_formatter)
172+
return console_handler
173+
174+
108175
def update_logger_level(name: str, level: str = "info") -> None:
109176
"""Updates the log level of the logger.
110177

0 commit comments

Comments
 (0)