Improve logging setup and add error prefixes for LLM functions

- Move logger init to top of file
- Add console handler by default
- Prefix LLM errors with "[LLM func]"
- Update timeout log messages
- Comment out pypinyin success log
This commit is contained in:
yangdx 2025-08-29 14:19:13 +08:00
parent 925e631a9a
commit d7e0701b63

View file

@ -27,17 +27,31 @@ from lightrag.constants import (
DEFAULT_MAX_FILE_PATH_LENGTH,
)
# Initialize logger with basic configuration
logger = logging.getLogger("lightrag")
logger.propagate = False # prevent log message send to root logger
logger.setLevel(logging.INFO)
# Add console handler if no handlers exist
if not logger.handlers:
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
formatter = logging.Formatter("%(levelname)s: %(message)s")
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
# Set httpx logging level to WARNING
logging.getLogger("httpx").setLevel(logging.WARNING)
# Global import for pypinyin with startup-time logging
try:
import pypinyin
_PYPINYIN_AVAILABLE = True
logger = logging.getLogger("lightrag")
logger.info("pypinyin loaded successfully for Chinese pinyin sorting")
# logger.info("pypinyin loaded successfully for Chinese pinyin sorting")
except ImportError:
pypinyin = None
_PYPINYIN_AVAILABLE = False
logger = logging.getLogger("lightrag")
logger.warning(
"pypinyin is not installed. Chinese pinyin sorting will use simple string sorting."
)
@ -121,15 +135,6 @@ def set_verbose_debug(enabled: bool):
statistic_data = {"llm_call": 0, "llm_cache": 0, "embed_call": 0}
# Initialize logger
logger = logging.getLogger("lightrag")
logger.propagate = False # prevent log message send to root loggger
# Let the main application configure the handlers
logger.setLevel(logging.INFO)
# Set httpx logging level to WARNING
logging.getLogger("httpx").setLevel(logging.WARNING)
class LightragPathFilter(logging.Filter):
"""Filter for lightrag logger to filter out frequent path access logs"""
@ -626,9 +631,9 @@ def priority_limit_async_func_call(
# Log dynamic timeout configuration
timeout_info = []
if llm_timeout is not None:
timeout_info.append(f"LLM: {llm_timeout}s")
timeout_info.append(f"Func: {llm_timeout}s")
if max_execution_timeout is not None:
timeout_info.append(f"Execution: {max_execution_timeout}s")
timeout_info.append(f"Worker: {max_execution_timeout}s")
if max_task_duration is not None:
timeout_info.append(f"Health Check: {max_task_duration}s")
@ -636,7 +641,7 @@ def priority_limit_async_func_call(
f" (Timeouts: {', '.join(timeout_info)})" if timeout_info else ""
)
logger.info(
f"limit_async: {workers_needed} new workers initialized with dynamic timeout handling{timeout_str}"
f"limit_async: {workers_needed} new workers initialized {timeout_str}"
)
async def shutdown():
@ -1661,7 +1666,14 @@ async def use_llm_func_with_cache(
if max_tokens is not None:
kwargs["max_tokens"] = max_tokens
res: str = await use_llm_func(safe_input_text, **kwargs)
try:
res: str = await use_llm_func(safe_input_text, **kwargs)
except Exception as e:
# Add [LLM func] prefix to error message
error_msg = f"[LLM func] {str(e)}"
# Re-raise with the same exception type but modified message
raise type(e)(error_msg) from e
res = remove_think_tags(res)
if llm_response_cache.global_config.get("enable_llm_cache_for_entity_extract"):
@ -1689,8 +1701,14 @@ async def use_llm_func_with_cache(
if max_tokens is not None:
kwargs["max_tokens"] = max_tokens
logger.info(f"Call LLM function with query text length: {len(safe_input_text)}")
res = await use_llm_func(safe_input_text, **kwargs)
try:
res = await use_llm_func(safe_input_text, **kwargs)
except Exception as e:
# Add [LLM func] prefix to error message
error_msg = f"[LLM func] {str(e)}"
# Re-raise with the same exception type but modified message
raise type(e)(error_msg) from e
return remove_think_tags(res)