Files
disknext/pkg/log/log.py
2025-07-17 19:33:48 +08:00

155 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from rich import print
from rich.console import Console
from rich.markdown import Markdown
from typing import Literal, Optional, Dict, Union
from enum import Enum
import time
import os
import inspect
class LogLevelEnum(str, Enum):
DEBUG = 'debug'
INFO = 'info'
WARNING = 'warning'
ERROR = 'error'
SUCCESS = 'success'
# 默认日志级别
LogLevel = LogLevelEnum.INFO
def set_log_level(level: Union[str, LogLevelEnum]) -> None:
"""设置日志级别"""
global LogLevel
if isinstance(level, str):
try:
LogLevel = LogLevelEnum(level.lower())
except ValueError:
print(f"[bold red]无效的日志级别: {level},使用默认级别: {LogLevel}[/bold red]")
else:
LogLevel = level
def truncate_path(full_path: str, marker: str = "HeyAuth") -> str:
"""截断路径只保留从marker开始的部分"""
try:
marker_index = full_path.find(marker)
if marker_index != -1:
return '.' + full_path[marker_index + len(marker):]
return full_path
except Exception:
return full_path
def get_caller_info(depth: int = 2) -> tuple:
"""获取调用者信息"""
try:
frame = inspect.currentframe()
# 向上查找指定深度的调用帧
for _ in range(depth):
if frame.f_back is None:
break
frame = frame.f_back
filename = frame.f_code.co_filename
lineno = frame.f_lineno
return truncate_path(filename), lineno
except Exception:
return "<unknown>", 0
finally:
# 确保引用被释放
del frame
def log(level: str = 'debug', message: str = ''):
"""
输出日志
---
通过传入的`level`和`message`参数,输出不同级别的日志信息。<br>
`level`参数为日志级别,支持`红色error`、`紫色info`、`绿色success`、`黄色warning`、`淡蓝色debug`。<br>
`message`参数为日志信息。<br>
"""
level_colors: Dict[str, str] = {
'debug': '[bold cyan][DEBUG][/bold cyan]',
'info': '[bold blue][INFO][/bold blue]',
'warning': '[bold yellow][WARN][/bold yellow]',
'error': '[bold red][ERROR][/bold red]',
'success': '[bold green][SUCCESS][/bold green]'
}
level_value = level.lower()
lv = level_colors.get(level_value, '[bold magenta][UNKNOWN][/bold magenta]')
# 获取调用者信息
filename, lineno = get_caller_info(3) # 考虑lambda调用和包装函数深度为3
timestamp = time.strftime('%Y/%m/%d %H:%M:%S %p', time.localtime())
log_message = f"{lv}\t{timestamp} [bold]From {filename}, line {lineno}[/bold] {message}"
# 根据日志级别判断是否输出
global LogLevel
should_log = False
if level_value == 'debug' and LogLevel == LogLevelEnum.DEBUG:
should_log = True
elif level_value == 'info' and LogLevel in [LogLevelEnum.DEBUG, LogLevelEnum.INFO]:
should_log = True
elif level_value == 'warning' and LogLevel in [LogLevelEnum.DEBUG, LogLevelEnum.INFO, LogLevelEnum.WARNING]:
should_log = True
elif level_value == 'error':
should_log = True
elif level_value == 'success':
should_log = False
if should_log:
print(log_message)
# 便捷日志函数
debug = lambda message: log('debug', message)
info = lambda message: log('info', message)
warning = lambda message: log('warn', message)
error = lambda message: log('error', message)
success = lambda message: log('success', message)
def title(title: str = '海枫授权系统 HeyAuth', size: Optional[Literal['h1', 'h2', 'h3', 'h4', 'h5']] = 'h1'):
"""
输出标题
---
通过传入的`title`参数,输出一个整行的标题。<br>
`title`参数为标题内容。<br>
"""
try:
console = Console()
markdown_sizes = {
'h1': '# ',
'h2': '## ',
'h3': '### ',
'h4': '#### ',
'h5': '##### '
}
markdown_tag = markdown_sizes.get(size, '# ')
console.print(Markdown(markdown_tag + title))
except Exception as e:
error(f"输出标题失败: {e}")
finally:
if 'console' in locals():
del console
if True:
pass
if __name__ == '__main__':
# 测试代码
title('海枫授权系统 日志组件测试', 'h1')
title('测试h2标题', 'h2')
title('测试h3标题', 'h3')
title('测试h4标题', 'h4')
title('测试h5标题', 'h5')
print("\n默认日志级别(INFO)测试:")
debug('这是一个debug日志') # 不会显示
info('这是一个info日志')
warning('这是一个warning日志')
error('这是一个error日志')
success('这是一个success日志')
print("\n设置为DEBUG级别测试:")
set_log_level(LogLevelEnum.DEBUG)
debug('这是一个debug日志') # 现在会显示