feat: make log format configurable (#4851)
* made logformat configurable * [autofix.ci] apply automated fixes * documentation of log format env var * log stuff at one place in documentation * added documentation of log environment * check for log format * [autofix.ci] apply automated fixes * just load log format on custom logenv * [autofix.ci] apply automated fixes * no more invalid whitespaces * fixed br s with escape * logging error in case of invalid format string --------- Co-authored-by: Kraxner Thomas <thomas.kraxner@illwerkevkw.at> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
2de119b8d5
commit
1e6ada3a3a
2 changed files with 38 additions and 5 deletions
|
|
@ -20,6 +20,10 @@ from typing_extensions import NotRequired
|
|||
from langflow.settings import DEV
|
||||
|
||||
VALID_LOG_LEVELS = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
||||
# Human-readable
|
||||
DEFAULT_LOG_FORMAT = (
|
||||
"<green>{time:YYYY-MM-DD HH:mm:ss}</green> - <level>" "{level: <8}</level> - {module} - <level>{message}</level>"
|
||||
)
|
||||
|
||||
|
||||
class SizedLogBuffer:
|
||||
|
|
@ -147,6 +151,7 @@ class LogConfig(TypedDict):
|
|||
log_file: NotRequired[Path]
|
||||
disable: NotRequired[bool]
|
||||
log_env: NotRequired[str]
|
||||
log_format: NotRequired[str]
|
||||
|
||||
|
||||
class AsyncFileSink(AsyncSink):
|
||||
|
|
@ -166,12 +171,37 @@ class AsyncFileSink(AsyncSink):
|
|||
await asyncio.to_thread(self._sink.write, message)
|
||||
|
||||
|
||||
def is_valid_log_format(format_string) -> bool:
|
||||
"""Validates a logging format string by attempting to format it with a dummy LogRecord.
|
||||
|
||||
Args:
|
||||
format_string (str): The format string to validate.
|
||||
|
||||
Returns:
|
||||
bool: True if the format string is valid, False otherwise.
|
||||
"""
|
||||
record = logging.LogRecord(
|
||||
name="dummy", level=logging.INFO, pathname="dummy_path", lineno=0, msg="dummy message", args=None, exc_info=None
|
||||
)
|
||||
|
||||
formatter = logging.Formatter(format_string)
|
||||
|
||||
try:
|
||||
# Attempt to format the record
|
||||
formatter.format(record)
|
||||
except (KeyError, ValueError, TypeError):
|
||||
logger.error("Invalid log format string passed, fallback to default")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def configure(
|
||||
*,
|
||||
log_level: str | None = None,
|
||||
log_file: Path | None = None,
|
||||
disable: bool | None = False,
|
||||
log_env: str | None = None,
|
||||
log_format: str | None = None,
|
||||
async_file: bool = False,
|
||||
) -> None:
|
||||
if disable and log_level is None and log_file is None:
|
||||
|
|
@ -195,11 +225,11 @@ def configure(
|
|||
elif log_env.lower() == "container_csv":
|
||||
logger.add(sys.stdout, format="{time:YYYY-MM-DD HH:mm:ss.SSS} {level} {file} {line} {function} {message}")
|
||||
else:
|
||||
# Human-readable
|
||||
log_format = (
|
||||
"<green>{time:YYYY-MM-DD HH:mm:ss}</green> - <level>"
|
||||
"{level: <8}</level> - {module} - <level>{message}</level>"
|
||||
)
|
||||
if os.getenv("LANGFLOW_LOG_FORMAT") and log_format is None:
|
||||
log_format = os.getenv("LANGFLOW_LOG_FORMAT")
|
||||
|
||||
if log_format is None or not is_valid_log_format(log_format):
|
||||
log_format = DEFAULT_LOG_FORMAT
|
||||
|
||||
# Configure loguru to use RichHandler
|
||||
logger.configure(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue