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

网友投稿 657 2022-05-29

使用 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 Turial、Advanced 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):

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

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)。

华为云

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:数据湖探索DLI“三箭齐发”,关于数据分析的这些技术你了解吗?
下一篇:MapReduce Service转售版本学习材料
相关文章