Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

loguru support standout logging with json and csv #2415

Merged
merged 10 commits into from
Jul 1, 2024
88 changes: 51 additions & 37 deletions src/backend/base/langflow/utils/logger.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import os
import sys
from pathlib import Path
from typing import Optional

Expand All @@ -11,7 +12,7 @@
VALID_LOG_LEVELS = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]


def serialize(record):
def serialize_log(record):
subset = {
"timestamp": record["time"].timestamp(),
"message": record["message"],
Expand All @@ -22,54 +23,67 @@ def serialize(record):


def patching(record):
record["extra"]["serialized"] = serialize(record)
record["extra"]["serialized"] = serialize_log(record)


def configure(log_level: Optional[str] = None, log_file: Optional[Path] = None, disable: Optional[bool] = False):
def configure(
log_level: Optional[str] = None,
log_file: Optional[Path] = None,
disable: Optional[bool] = False,
log_env: Optional[str] = None,
):
if disable and log_level is None and log_file is None:
logger.disable("langflow")
if os.getenv("LANGFLOW_LOG_LEVEL", "").upper() in VALID_LOG_LEVELS and log_level is None:
log_level = os.getenv("LANGFLOW_LOG_LEVEL")
if log_level is None:
log_level = "ERROR"
# Human-readable
log_format = (
"<green>{time:YYYY-MM-DD HH:mm:ss}</green> - <level>"
"{level: <8}</level> - {module} - <level>{message}</level>"
)

# log_format = log_format_dev if log_level.upper() == "DEBUG" else log_format_prod
if log_env is None:
log_env = os.getenv("LANGFLOW_LOG_ENV", "")

logger.remove() # Remove default handlers
logger.patch(patching)
# Configure loguru to use RichHandler
logger.configure(
handlers=[
{
"sink": RichHandler(rich_tracebacks=True, markup=True),
"format": log_format,
"level": log_level.upper(),
}
]
)

if not log_file:
cache_dir = Path(user_cache_dir("langflow"))
logger.debug(f"Cache directory: {cache_dir}")
log_file = cache_dir / "langflow.log"
logger.debug(f"Log file: {log_file}")
try:
log_file = Path(log_file)
log_file.parent.mkdir(parents=True, exist_ok=True)

logger.add(
sink=str(log_file),
level=log_level.upper(),
format=log_format,
rotation="10 MB", # Log rotation based on file size
serialize=True,
if log_env.lower() == "container" or log_env.lower() == "container_json":
logger.add(sys.stdout, format="{message}", serialize=True)
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>"
)

# Configure loguru to use RichHandler
logger.configure(
handlers=[
{
"sink": RichHandler(rich_tracebacks=True, markup=True),
"format": log_format,
"level": log_level.upper(),
}
]
)
except Exception as exc:
logger.error(f"Error setting up log file: {exc}")

if not log_file:
cache_dir = Path(user_cache_dir("langflow"))
logger.debug(f"Cache directory: {cache_dir}")
log_file = cache_dir / "langflow.log"
logger.debug(f"Log file: {log_file}")
try:
log_file = Path(log_file)
log_file.parent.mkdir(parents=True, exist_ok=True)

logger.add(
sink=str(log_file),
level=log_level.upper(),
format=log_format,
rotation="10 MB", # Log rotation based on file size
serialize=True,
)
except Exception as exc:
logger.error(f"Error setting up log file: {exc}")

logger.debug(f"Logger set up with log level: {log_level}")

Expand Down