From 03b75b699b384cae2399e3be814e8b479b8b29b3 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 25 Aug 2025 20:57:31 -0300 Subject: [PATCH 1/6] fix: update logger configuration to use environment variable for log level --- src/backend/base/langflow/logging/logger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/base/langflow/logging/logger.py b/src/backend/base/langflow/logging/logger.py index 87e6ab12dbe0..725087eeef66 100644 --- a/src/backend/base/langflow/logging/logger.py +++ b/src/backend/base/langflow/logging/logger.py @@ -366,4 +366,4 @@ def emit(self, record: logging.LogRecord) -> None: # Initialize logger - will be reconfigured when configure() is called # Set it to critical level logger: structlog.BoundLogger = structlog.get_logger() -configure(log_level="CRITICAL", disable=True) +configure(log_level=os.getenv("LANGFLOW_LOG_LEVEL", "INFO")) From 87de8ba0d63c27a7691e1275f8afc1dd4e7b0d40 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 25 Aug 2025 21:02:25 -0300 Subject: [PATCH 2/6] fix: remove default log level configuration and set logger initialization --- src/backend/base/langflow/logging/logger.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/backend/base/langflow/logging/logger.py b/src/backend/base/langflow/logging/logger.py index 725087eeef66..7e6b55c121ec 100644 --- a/src/backend/base/langflow/logging/logger.py +++ b/src/backend/base/langflow/logging/logger.py @@ -364,6 +364,4 @@ def emit(self, record: logging.LogRecord) -> None: # Initialize logger - will be reconfigured when configure() is called -# Set it to critical level logger: structlog.BoundLogger = structlog.get_logger() -configure(log_level=os.getenv("LANGFLOW_LOG_LEVEL", "INFO")) From 91cd69289b5b07a54d78108f58b4cc10963268e8 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 25 Aug 2025 21:15:36 -0300 Subject: [PATCH 3/6] fix: enhance logger configuration to prevent redundant setup and improve cache handling --- src/backend/base/langflow/logging/logger.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/backend/base/langflow/logging/logger.py b/src/backend/base/langflow/logging/logger.py index 7e6b55c121ec..44920dd05883 100644 --- a/src/backend/base/langflow/logging/logger.py +++ b/src/backend/base/langflow/logging/logger.py @@ -208,10 +208,19 @@ def configure( log_env: str | None = None, log_format: str | None = None, log_rotation: str | None = None, + cache: bool | None = None, ) -> None: """Configure the logger.""" + # If is_configured AND the numeric_level set in the wrapper_class is the same as the log_level + cfg = structlog.get_config() + wrapper_class = cfg["wrapper_class"] + wrapper_class_name = wrapper_class.__name__ if wrapper_class else "None" if os.getenv("LANGFLOW_LOG_LEVEL", "").upper() in VALID_LOG_LEVELS and log_level is None: log_level = os.getenv("LANGFLOW_LOG_LEVEL") + + if structlog.is_configured() and (log_level and log_level.lower() in wrapper_class_name.lower()): + return + if log_level is None: log_level = "ERROR" @@ -268,7 +277,7 @@ def configure( logger_factory=structlog.PrintLoggerFactory(file=sys.stdout) if not log_file else structlog.stdlib.LoggerFactory(), - cache_logger_on_first_use=True, + cache_logger_on_first_use=cache or True, ) # Set up file logging if needed @@ -364,4 +373,6 @@ def emit(self, record: logging.LogRecord) -> None: # Initialize logger - will be reconfigured when configure() is called +# Set it to critical level logger: structlog.BoundLogger = structlog.get_logger() +configure(log_level="CRITICAL", cache=False) From ea038ac0cbac2e7d642eff5dabddb955354b029e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 26 Aug 2025 08:17:40 -0300 Subject: [PATCH 4/6] fix: improve cache handling in logger configuration to prevent unintended defaults --- src/backend/base/langflow/logging/logger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/base/langflow/logging/logger.py b/src/backend/base/langflow/logging/logger.py index 44920dd05883..aea8dcb4154d 100644 --- a/src/backend/base/langflow/logging/logger.py +++ b/src/backend/base/langflow/logging/logger.py @@ -277,7 +277,7 @@ def configure( logger_factory=structlog.PrintLoggerFactory(file=sys.stdout) if not log_file else structlog.stdlib.LoggerFactory(), - cache_logger_on_first_use=cache or True, + cache_logger_on_first_use=cache if cache is not None else True, ) # Set up file logging if needed From dae0ca2534bebe677949ff9cd62789ba1af3ac15 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 26 Aug 2025 10:20:12 -0300 Subject: [PATCH 5/6] fix: enhance logger configuration to prevent redundant setup and improve early-exit logic --- src/backend/base/langflow/logging/logger.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/backend/base/langflow/logging/logger.py b/src/backend/base/langflow/logging/logger.py index aea8dcb4154d..c84442c27a13 100644 --- a/src/backend/base/langflow/logging/logger.py +++ b/src/backend/base/langflow/logging/logger.py @@ -211,14 +211,18 @@ def configure( cache: bool | None = None, ) -> None: """Configure the logger.""" - # If is_configured AND the numeric_level set in the wrapper_class is the same as the log_level - cfg = structlog.get_config() - wrapper_class = cfg["wrapper_class"] - wrapper_class_name = wrapper_class.__name__ if wrapper_class else "None" + # Early-exit only if structlog is configured AND current min level matches the requested one. + # Be defensive: get_config() may not contain 'wrapper_class' yet. + cfg = structlog.get_config() if structlog.is_configured() else {} + wrapper_class = cfg.get("wrapper_class") + current_min_level = getattr(wrapper_class, "min_level", None) if os.getenv("LANGFLOW_LOG_LEVEL", "").upper() in VALID_LOG_LEVELS and log_level is None: log_level = os.getenv("LANGFLOW_LOG_LEVEL") - if structlog.is_configured() and (log_level and log_level.lower() in wrapper_class_name.lower()): + requested_min_level = LOG_LEVEL_MAP.get( + (log_level or os.getenv("LANGFLOW_LOG_LEVEL", "ERROR")).upper(), logging.ERROR + ) + if current_min_level == requested_min_level: return if log_level is None: @@ -269,10 +273,14 @@ def configure( # Get numeric log level numeric_level = LOG_LEVEL_MAP.get(log_level.upper(), logging.ERROR) + # Create wrapper class and attach the min level for later comparison + wrapper_class = structlog.make_filtering_bound_logger(numeric_level) + wrapper_class.min_level = numeric_level + # Configure structlog structlog.configure( processors=processors, - wrapper_class=structlog.make_filtering_bound_logger(numeric_level), + wrapper_class=wrapper_class, context_class=dict, logger_factory=structlog.PrintLoggerFactory(file=sys.stdout) if not log_file From 03e852282c9f325174c669d2ff7954b852a7c874 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 26 Aug 2025 10:20:33 -0300 Subject: [PATCH 6/6] fix: remove defensive comment in logger configuration for clarity --- src/backend/base/langflow/logging/logger.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/base/langflow/logging/logger.py b/src/backend/base/langflow/logging/logger.py index c84442c27a13..0ce8cff37235 100644 --- a/src/backend/base/langflow/logging/logger.py +++ b/src/backend/base/langflow/logging/logger.py @@ -212,7 +212,6 @@ def configure( ) -> None: """Configure the logger.""" # Early-exit only if structlog is configured AND current min level matches the requested one. - # Be defensive: get_config() may not contain 'wrapper_class' yet. cfg = structlog.get_config() if structlog.is_configured() else {} wrapper_class = cfg.get("wrapper_class") current_min_level = getattr(wrapper_class, "min_level", None)