loguru在工程日志中的应用

1.Python的logging模块中的error和exception区别**

共同点:

logging模块有6个级别,由低到高为NOTSET>>DEBUG>>INFO>>WARNING>>ERROR>>CRITICAL,其实无论是error还是exception,它们的错误等级都是ERROR级别。

from loguru import logger
try:
    port, minimum = 10, 12
    assert port >= minimum
except Exception as e:
    logger.error(e)
    logger.exception(e)

运行结果为:

2022-03-04 23:52:13.925 | ERROR    | __main__:<module>:11 - 
2022-03-04 23:52:13.927 | ERROR    | __main__:<module>:12 - 

我们可以看到日志信息中,错误等级都是ERROR

不同点:

error级别的只输出错误的异常信息,而没有具体的错误堆栈信息,如果想要排查具体异常仅通过上面的异常message内容是远远不够的

exception级别的则不但会输出错误的异常信息,还会显示具体的错误堆栈信息,使得我们在排查问题的时候有更加明确的方向

2.assert与raise的区别

assert 的意义是在测试关键词后的条件(condition)为False时,程序自动崩溃并抛出AssertionError的异常。常用形式为:

assert expression等同于以下代码:

if _debug_:
    if not expression:
        raise AssertionError

assert expression1, expression2等同于以下代码:

 if _debug_:
    if not expression1:
        raise AssertionError(expression2)

以上两段代码中的_debug_和AssertionError都代表的是Python中内建的变量。通常在Python中_debug_在普通情况下均为True。只有在python启动时加上-o选项(生成优化后的*.pyo文件),_debug_为False。所以当程序以优化模式编译后,assert声明并不会被执行。

以下两段代码,大家可以仔细体会下他们的区别:

assert写法

from loguru import logger

try:

    port, minimum = 10, 12

    assert port >= minimum
    
except Exception as e:
    
    logger.error(e)
    logger.exception(e)

返回结果为:

2022-03-05 00:10:45.255 | ERROR    | __main__:<module>:11 - 
2022-03-05 00:10:45.256 | ERROR    | __main__:<module>:12 - 
Traceback (most recent call last):

  File "/Users/lijinze/anaconda3/envs/py36/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
                └ ModuleSpec(name='ipykernel_launcher', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7fb5d873f828>, origin='...
  
    *****
    
    assert port >= minimum
           │       └ 12
           └ 10

AssertionError: assert port >= minimum

raise写法

from loguru import logger

try:

    port, minimum = 10, 12

    if port < minimum:
        
        raise RuntimeError('出错了')
#         raise ValueError('出错了')
    
except Exception as e:
    logger.error(e)
    logger.exception(e)

返回结果为:

2022-03-05 00:10:45.255 | ERROR    | __main__:<module>:11 - 
2022-03-05 00:10:45.256 | ERROR    | __main__:<module>:12 - 
Traceback (most recent call last):

  File "/Users/lijinze/anaconda3/envs/py36/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
                └ ModuleSpec(name='ipykernel_launcher', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7fb5d873f828>, origin='...
  
    *****
    
    assert port >= minimum
           │       └ 12
           └ 10

RuntimeError: 出错了

区别: assert 是用来确保程序的正确性,而不是用来矫正或者指示一些不可预知的错误的发生。简单来说是程序员debug的工具,有无这段程序,不应影响程序的功能执行,但对程序正确性有影响。 raise 是用来检查用户输入是否正确,指示程序违反了预设的条件。

python文件的格式除了.py还有.pyc/.pyo,后两张需要经过编译再运行,其中.pyo是经过优化后编译的二进制文件,可以增加程序的稳定性,隐藏源码。而在.pyo格式的版本中是不对assert进行编译的,这也是不用assert 作为检查输入参数合法性的原因之一。

Tips:

RuntimeError,ValueErrorAssertionError都是error类

3.多线程异常处理模板

def exception_warpper(func):
    functools.wraps(func)
    def inner(*args, **kwargs):
        func_name = ''
        ret = None
        try:
            func_name = func.__name__
            ret = func(*args, **kwargs)
        except Exception as e:
            logger.exception(e)
            Alarm.msg('exception, {}'.format(func_name))
        return ret
    return inner
    
# 多线程业务逻辑模块
crawler_dir = os.path.join(spider_dir, 'crawler', 'crawler_*.py')
        with ThreadPoolExecutor(max_workers=self.max_worker) as pool:
            futures = set()
            for cls_path in glob.glob(crawler_dir):
                imp_cls = self._load_class(
                    cls_path,
                    'spider.crawler',
                    'CrawlerImpl'
                )
                if imp_cls is not None:
                    cls_obj = imp_cls()
                    job = pool.submit(exception_warpper(cls_obj.crawl))
                    futures.add(job)
                else:
                    logger.error('spider:{} load fail!', cls_path)
            for job in as_completed(futures):
                result = job.result()
                if result:
                    self.crawler_result_list.append(result)
                    logger.info('crawl:{}, {}', result.name, result.url)
                else:
                    logger.warning('crawl_result is null')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值