【Free Style】华为云之Python实践(二)

举报
yd_79585289 发表于 2017/11/24 07:46:51 2017/11/24
【摘要】 使用 python 的标准日志模块那么,怎么样记录日志才是正确的呢?其实非常简单,使用 python 的标准日志模块。多亏 python 社区将日志做成了一个标准模块。它非常简单易用且十分灵活。你可以像这样使用日志系统:Python12345678910111213import logginglogging.basicConfig(level=logging.INFO)logger = loggi

使用 python 的标准日志模块

那么,怎么样记录日志才是正确的呢?其实非常简单,使用 python 的标准日志模块。多亏 python 社区将日志做成了一个标准模块。它非常简单易用且十分灵活。你可以像这样使用日志系统:

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

import logging

logging.basicConfig(level=logging.INFO)

logger = logging.getLogger(__name__)

 

logger.info('Start reading database')

# read database here

 

records = {'john': 55, 'tom': 66}

logger.debug('Records: %s', records)

logger.info('Updating records ...')

# update records here

 

logger.info('Finish updating records')

运行的时候就可看到:

Python

1

2

3

INFO:__main__:Start reading database

INFO:__main__:Updating records ...

INFO:__main__:Finish updating records

你可能会问这与使用 print 有什么不同呢。它有以下的优势:

  • 你可以控制消息的级别,过滤掉那些并不重要的消息。

  • 你可决定输出到什么地方,以及怎么输出。

有许多的重要性别级可供选择,debug、info、warning、error 以及 critical。通过赋予 logger 或者 handler 不同的级别,你就可以只输出错误消息到特定的记录文件中,或者在调试时只记录调试信息。让我们把 logger 的级别改成 DEBUG 再看一下输出结果:

Python

1

logging.basicConfig(level=logging.DEBUG)

输出变成了:

Python

1

2

3

4

INFO:__main__:Start reading database

DEBUG:__main__:Records: {'john': 55, 'tom': 66}

INFO:__main__:Updating records ...

INFO:__main__:Finish updating records

正如看到的那样,我们把 logger 的等级改为 DEBUG 后,调试记录就出现在了输出当中。你也可以选择怎么处理这些消息。例如,你可以使用 FileHandler 把记录写进文件中:

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

import logging

 

logger = logging.getLogger(__name__)

logger.setLevel(logging.INFO)

 

# create a file handler

 

handler = logging.FileHandler('hello.log')

handler.setLevel(logging.INFO)

 

# create a logging format

 

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

handler.setFormatter(formatter)

 

# add the handlers to the logger

 

logger.addHandler(handler)

 

logger.info('Hello baby')

标准库模块中提供了许多的 handler ,你可以将记录发送到邮箱甚至发送到一个远程的服务器。你也可以实现自己的记录 handler 。这里将不具体讲述实现的细节,你可以参考官方文档:Basci TurialAdvanced Tutorial 与 Logging Cookbook

以合适的等级输出日志记录

有了灵活的日志记录模块后,你可以按适当的等级将日志记录输出到任何地方然后配置它们。那么你可能会问,什么是合适的等级呢?在这儿我将分享一些我的经验。

大多数的情况下,你都不想阅读日志中的太多细节。因此,只有你在调试过程中才会使用 DEBUG 等级。我只使用 DEBUG 获取详细的调试信息,特别是当数据量很大或者频率很高的时候,比如算法内部每个循环的中间状态。

Python

1

2

3

4

5

def complex_algorithm(items):

    for i, item in enumerate(items):

        # do some complex algorithm computation

 

        logger.debug('%s iteration, item=%s', i, item)

在处理请求或者服务器状态变化等日常事务中,我会使用 INFO 等级。

Python

1

2

3

4

5

6

7

8

9

10

11

def handle_request(request):

    logger.info('Handling request %s', request)

    # handle request here

 

    result = 'result'

    logger.info('Return result: %s', result)

 

def start_service():

    logger.info('Starting service at port %s ...', port)

    service.start()

    logger.info('Service is started')

当发生很重要的事件,但是并不是错误时,我会使用 WARNING 。比如,当用户登录密码错误时,或者连接变慢时。

Python

1

2

3

4

5

def authenticate(user_name, password, ip_address):

    if user_name != USER_NAME and password != PASSWORD:

        logger.warn('Login attempt to %s from IP %s', user_name, ip_address)

        return False

    # do authentication here

有错误发生时肯定会使用 ERROR 等级了。比如抛出异常,IO 操作失败或者连接问题等。

Python

1

2

3

4

5

6

def get_user_by_id(user_id):

    user = db.read_user(user_id)

    if user is None:

        logger.error('Cannot find user with user_id=%s', user_id)

        return user

    return user

我很少使用 CRITICAL 。当一些特别糟糕的事情发生时,你可以使用这个级别来记录。比方说,内存耗尽,磁盘满了或者核危机(希望永远别发生 :S)。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。