Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions src/lightspeed_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from utils import schema_dumper
from constants import LIGHTSPEED_STACK_LOG_LEVEL_ENV_VAR, DEFAULT_LOG_LEVEL

FORMAT = "%(message)s"
# Read log level from environment variable with validation
log_level_str = os.environ.get(LIGHTSPEED_STACK_LOG_LEVEL_ENV_VAR, DEFAULT_LOG_LEVEL)
log_level = getattr(logging, log_level_str.upper(), None)
Expand All @@ -29,9 +28,24 @@
file=sys.stderr,
)
log_level = getattr(logging, DEFAULT_LOG_LEVEL)
logging.basicConfig(
level=log_level, format=FORMAT, datefmt="[%X]", handlers=[RichHandler()], force=True
)

# RichHandler's columnar layout produces very narrow log output in containers
# without a TTY (Rich falls back to 80 columns, columns consume ~40 of those).
# Use a plain format when there's no terminal attached.
if sys.stderr.isatty():
logging.basicConfig(
level=log_level,
format="%(message)s",
datefmt="[%X]",
handlers=[RichHandler()],
force=True,
)
else:
logging.basicConfig(
level=log_level,
format="%(asctime)s %(levelname)-8s %(name)s:%(lineno)d %(message)s",
force=True,
)

logger = get_logger(__name__)

Expand Down
22 changes: 18 additions & 4 deletions src/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import logging
import os
import sys

from rich.logging import RichHandler

from constants import LIGHTSPEED_STACK_LOG_LEVEL_ENV_VAR, DEFAULT_LOG_LEVEL
Expand All @@ -24,12 +26,24 @@ def get_logger(name: str) -> logging.Logger:
"""
logger = logging.getLogger(name)

# Skip reconfiguration if logger already has a RichHandler from a prior call
if any(isinstance(h, RichHandler) for h in logger.handlers):
# Skip reconfiguration if logger already has handlers from a prior call
if logger.handlers:
return logger

# Attach RichHandler before any log calls so warnings use consistent formatting
logger.handlers = [RichHandler()]
# RichHandler's columnar layout (timestamp, level, right-aligned filename) assumes
# a real terminal. In containers without a TTY, Rich falls back to 80 columns and
# the columns consume most of that width, leaving ~40 chars for the actual message.
# Tracebacks become nearly unreadable. Use a plain StreamHandler when there's no TTY.
if sys.stderr.isatty():
logger.handlers = [RichHandler()]
else:
handler = logging.StreamHandler()
handler.setFormatter(
logging.Formatter(
"%(asctime)s %(levelname)-8s %(name)s:%(lineno)d %(message)s"
)
)
logger.handlers = [handler]
logger.propagate = False

# Read log level from environment variable with default fallback
Expand Down
Loading