记录代码出错的位置
def f2(b, a):
print(b - a)
def f1(a, b):
return f2(b, a)
def try_log(func, *args, **kwargs):
from time import strftime
from traceback import format_exc
try:
func(*args, **kwargs)
except:
error = format_exc()
print('\033[031m', error, '\033[0m', sep='\n')
with open('%s.log' % strftime('%Y-%m-%d'), 'a', encoding='utf-8') as f:
f.write('%s\n' % error)
if __name__ == '__main__':
try_log(f1, 1, b='2')
分日期保存文件
def write_log(*args):
from time import strftime
ymd = strftime('%Y%m%d')
with open('%s.log' % ymd, 'a', encoding='utf-8') as f:
for i in args:
f.write('%r\n' % i)
f.write('\n')
traceback+写文件
import os
from traceback import format_exc
from time import strftime
_path = os.path.dirname(__file__)
_get_abs_path = lambda path: os.path.normpath(os.path.join(_path, path))
def write_log(*args, **kwargs):
fname = kwargs.pop('fname') if 'fname' in kwargs else'log.txt'
with open(fname, 'a', encoding='utf-8') as f:
for i in args:
f.write('{}\n'.format(i))
print('\033[031m', i, '\033[0m')
for i in kwargs.items():
f.write('{} {}\n'.format(*i))
print('\033[031m', *i, '\033[0m')
f.write('\n')
def traceback_func(func, *args, **kwargs):
try:
value = func(*args, **kwargs)
return value
except:
error = format_exc() # 在线程中失效
write_log(error, *args, **kwargs)
def remove():
"""清空日志,谨慎启动"""
for fname in os.listdir(_path):
if '.txt' in fname:
abs_fname = _get_abs_path(fname)
print(abs_fname)
os.remove(abs_fname)
if __name__ == '__main__':
remove()
traceback+装饰器
from traceback import format_exc
def write_log(*args, **kwargs):
fname = kwargs.pop('fname') if 'fname' in kwargs else'log.txt'
with open(fname, 'a', encoding='utf-8') as f:
for i in args:
f.write('{}\n'.format(i))
print('\033[031m', i, '\033[0m')
for i in kwargs.items():
f.write('{} {}\n'.format(*i))
print('\033[031m', *i, '\033[0m')
f.write('\n')
def traceback_func(fn):
def function_timer(*args, **kwargs):
try:
result = fn(*args, **kwargs)
return result
except:
error = format_exc().strip() # 在线程中失效
write_log(error, *args, **kwargs)
return function_timer
def f1(a):
print(int(a))
@traceback_func
def f2(a, *args, **kwargs):
f1(a)
if __name__ == '__main__':
f2('a', fname='a.txt', k='v')

logging模块
| format | 中文解释 | remark |
|---|---|---|
| %(message)s | 日志信息 | 必要 |
| %(asctime)s | 时间 | 常用 |
| %(pathname)s | 绝对路径:sys.argv[0] | 常用 |
| %(lineno)d | 行号 | 常用 |
| %(funcName)s | 函数名 | 常用 |
| %(module)s | 模块名 | 有用 |
| %(filename)s | 文件名 | 有用 |
| %(relativeCreated)d | 导入logging后的相对时间(毫秒级) | 有用 |
| %(created)f | 当前时间:time.time() | 少用 |
| %(levelname)s | 日志级别名称,DEBUG、INFO、ERROR…… | 少用 |
| %(levelno)s | 日志级别(10, 20, 30, 40, 50) | 少用 |
| %(name)s | 日志器名称,默认root | 少用 |
| %(process)s | 进程ID | 不用 |
| %(processName)s | 进程名称 | 不用 |
| %(thread)s | 线程ID | 不用 |
| %(thread)s | 线程名称 | 不用 |
| %(msecs)d | asctime时间的毫秒部分 | 不用 |
"""
message | %(message)s | 日志信息 | 必要
asctime | %(asctime)s | 时间 | 常用
pathname | %(pathname)s | 绝对路径:sys.argv[0] | 常用
lineno | %(lineno)d | 行号 | 常用
funcName | %(funcName)s | 函数名 | 常用
module | %(module)s | 模块名 | 有用
filename | %(filename)s | 文件名 | 有用
relativeCreated | %(relativeCreated)d | 导入logging后的相对时间(毫秒级) |有用
created | %(created)f | 当前时间:time.time() | 少用
levelname | %(levelname)s | 日志级别名称,DEBUG、INFO、ERROR…… | 少用
levelno | %(levelno)s | 日志级别(10, 20, 30, 40, 50) | 少用
name | %(name)s | 日志器名称,默认root | 少用
process | %(process)s | 进程ID | 不用
processName | %(processName)s | 进程名称 | 不用
thread | %(thread)s | 线程ID | 不用
threadName | %(thread)s | 线程名称 | 不用
msecs | %(msecs)d | asctime时间的毫秒部分 | 不用
"""
import logging, time
logging.basicConfig(level=logging.DEBUG, format=__doc__) # 配置
# logging.info('msg')
time.sleep(.5) # 检验relativeCreated
logger = logging.getLogger('a1')
logger.debug('msg')
打印结果
message | msg | 日志信息 | 必要
asctime | 2020-02-13 16:21:34,550 | 时间 | 常用
pathname | E:/PycharmProjects/anaconda/logger/__init__.py | 绝对路径:sys.argv[0] | 常用
lineno | 25 | 行号 | 常用
funcName | <module> | 函数名 | 常用
module | __init__ | 模块名 | 有用
filename | __init__.py | 文件名 | 有用
relativeCreated | 501 | 导入logging后的相对时间(毫秒级) |有用
created | 1581582094.550740 | 当前时间:time.time() | 少用
levelname | DEBUG | 日志级别名称,DEBUG、INFO、ERROR…… | 少用
levelno | 10 | 日志级别(10, 20, 30, 40, 50) | 少用
name | a1 | 日志器名称,默认root | 少用
process | 4608 | 进程ID | 不用
processName | MainProcess | 进程名称 | 不用
thread | 14292 | 线程ID | 不用
threadName | 14292 | 线程名称 | 不用
msecs | 550 | asctime时间的毫秒部分 | 不用
路径引用示例

日志等级
| 日志级别名称 | 描述 | 日志级别 |
|---|---|---|
| DEBUG | 调试,最详细的日志信息 | 10 |
| INFO | 基本信息(如,打印时间、进度、中间结果、最终结果…) | 20 |
| WARNING | 预警信息(如,磁盘可用空间较低),此时应用程序仍正常运行 | 30 |
| ERROR | 错误信息,程序某功能不能运行 | 40 |
| CRITICAL | 严重错误信息,程序不能运行 | 50 |
- CRITICAL > ERROR > WARNING > INFO > DEBUG
- 默认级别为WARNING(输出大于等于WARNING级别的日志)
四大组件
| 组件名称 | 对应类名 | 功能描述 |
|---|---|---|
| 日志器 | Logger | 提供了应用程序可一直使用的接口 |
| 处理器 | Handler | 将logger创建的日志记录发送到合适的目的输出 |
| 过滤器 | Filter | 提供了更细粒度的控制工具来决定输出哪条日志,丢弃哪条日志 |
| 格式器 | Formatter | 决定日志记录的最终输出格式 |
-
常用Logger方法
- Logger.addHandler() 常用Handler
-
logging.StreamHandler:日志打印
logging.FileHandler:日志写入文件
常用Formater参数
-
fmt:格式
datefmt:时间格式
写文件
import logging
# logger对象
logger = logging.getLogger()
# Handler加入
sh = logging.StreamHandler() # 打印
fh = logging.FileHandler('log.txt', encoding='utf-8') # 写文件
logger.addHandler(sh)
logger.addHandler(fh)
# 日志等级
logger.setLevel(logging.DEBUG)
sh.setLevel(logging.INFO)
fh.setLevel(logging.WARNING)
# 日志格式
fmt = logging.Formatter('%(message)s\n%(asctime)s\n%(pathname)s\n%(lineno)d\n')
sh.setFormatter(fmt)
fh.setFormatter(fmt)
# 日志过滤
class Filter(logging.Filter):
def filter(self, record):
if record.msg is not None:
return True
logger.addFilter(Filter())
if __name__ == '__main__':
logger.info('info') # 只打印
logger.warning('警告') # 既打印也写文件
logger.error(None) # 过滤空值
1390

被折叠的 条评论
为什么被折叠?



