Python中logging日志模块在多进程环境下的使用教程

前言

相信每位程序员应该都知道,在使用 Python 来写后台任务时,时常需要使用输出日志来记录程序运行的状态,并在发生错误时将错误的详细信息保存下来,以别调试和分析。Python 的 logging 模块就是这种情况下的好帮手。

logging 模块可以指定日志的级别,DEBUG、INFO、WARNING、ERROR、CRITICAL,例如可以在开发和调试时,把 DEBUG 以上级别的日志都输出,而在生产环境下,只输出 INFO 级别。(如果不特别指定,默认级别是 warning)

logging 还可以指定输出到命令行或者文件,还可以按时间或大小分割日志文件。

关于 logging 的详细使用,这里就不再细说,可以参考官方文档,或者这里的介绍。

logging 的配置

通常情况下,我们需要将日志保存到文件中,并期望能自动分割文件,避免日志文件太大。下面给出了一个 logging 的配置例子。

importlogging.config

  

logging.config.dictConfig({

 'version':1,

 'disable_existing_loggers':True,

 'formatters': {

  'verbose': {

   'format':"[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",

   'datefmt':"%Y-%m-%d %H:%M:%S"

  },

  'simple': {

   'format':'%(levelname)s %(message)s'

  },

 },

 'handlers': {

  'null': {

   'level':'DEBUG',

   'class':'logging.NullHandler',

  },

  'console': {

   'level':'DEBUG',

   'class':'logging.StreamHandler',

   'formatter':'verbose'

  },

  'file': {

   'level':'DEBUG',

   'class':'logging.RotatingFileHandler',

   # 当达到10MB时分割日志

   'maxBytes':1024*1024*10,

   # 最多保留50份文件

   'backupCount':50,

   # If delay is true,

   # then file opening is deferred until the first call to emit().

   'delay':True,

   'filename':'logs/mysite.log',

   'formatter':'verbose'

  }

 },

 'loggers': {

  '': {

   'handlers': ['file'],

   'level':'info',

  },

 }

})

我们在一个模块内,就可以这么使用来记录日志

importlogging

logger=logging.getLogger(__name__)

  

if__name__=='__main__':

 logger.info('log info')

多进程环境下的使用

按照官方文档的介绍,logging 是线程安全的,也就是说,在一个进程内的多个线程同时往同一个文件写日志是安全的。但是(对,这里有个但是)多个进程往同一个文件写日志不是安全的。官方的说法是这样的:

Because there is no standard way to serialize access to a single file across multiple processes in Python. If you need to log to a single file from multiple processes, one way of doing this is to have all the processes log to a SocketHandler, and have a separate process which implements a socket server which reads from the socket and logs to file. (If you prefer, you can dedicate one thread in one of the existing processes to perform this function.)

有的人会说,那我不用多进程不就可以了。但是 Python 有一个 GIL 的大锁(关于 GIL 的纠葛可以看这里),使用多线程是没法利用到多核 CPU 的,大部分情况下会改用多进程来利用多核 CPU,因此我们还是绕不开不开多进程下日志的问题。

为了解决这个问题,可以使用 ConcurrentLogHandler,ConcurrentLogHandler 可以在多进程环境下安全的将日志写入到同一个文件,并且可以在日志文件达到特定大小时,分割日志文件。在默认的 logging 模块中,有个 TimedRotatingFileHandler 类,可以按时间分割日志文件,可惜 ConcurrentLogHandler 不支持这种按时间分割日志文件的方式。

重新修改下 handlers 中的 class。

logging.config.dictConfig({

 ...

 'handlers': {

  'file': {

   'level':'DEBUG',

   # 如果没有使用并发的日志处理类,在多实例的情况下日志会出现缺失

   'class':'cloghandler.ConcurrentRotatingFileHandler',

   # 当达到10MB时分割日志

   'maxBytes':1024*1024*10,

   # 最多保留50份文件

   'backupCount':50,

   # If delay is true,

   # then file opening is deferred until the first call to emit().

   'delay':True,

   'filename':'logs/mysite.log',

   'formatter':'verbose'

  }

 },

 ...

})

运行后可以发现,会自动创建一个.lock文件,通过锁的方式来安全的写日志文件。

时间: 2024-10-27 12:51:43

Python中logging日志模块在多进程环境下的使用教程的相关文章

Python中的日志模块logging

  这篇文章主要介绍了Python中的日志模块logging,包括Python下的日志级别以及模块内常用方法的使用,需要的朋友可以参考下 许多应用程序中都会有日志模块,用于记录系统在运行过程中的一些关键信息,以便于对系统的运行状况进行跟踪.在.NET平台中,有非常著名的第三方开源日志组件log4net,c++中,有人们熟悉的log4cpp,而在python中,我们不需要第三方的日志组件,因为它已经为我们提供了简单易用.且功能强大的日志模块:logging.logging模块支持将日志信息保存到不

在Python中封装GObject模块进行图形化程序编程的教程_python

Python 是用于编码图形界面的极佳语言.由于可以迅速地编写工作代码并且不需要费时的编译周期, 所以可以立即使界面启动和运行起来,并且不久便可使用这些界面. 将这一点与 Python 易于链接本机库的能力结合起来,就可以形成一个出色的环境. gnome-python 是为 Python 封装 GNOME 及其相关库的软件包. 这使您能够用 Python 编写外观与核心 GNOME 应用程序完全相同的应用程序,而所花的时间只是用 C 编写该应用程序所花的一部分. 然而,不用 C 进行编程会有一个

在Python中编写数据库模块的教程

  这篇文章主要介绍了在Python中编写数据库模块的教程,本文代码基于Python2.x版本,需要的朋友可以参考下 在一个Web App中,所有数据,包括用户信息.发布的日志.评论等,都存储在数据库中.在awesome-python-app中,我们选择MySQL作为数据库. Web App里面有很多地方都要访问数据库.访问数据库需要创建数据库连接.游标对象,然后执行SQL语句,最后处理异常,清理资源.这些访问数据库的代码如果分散到各个函数中,势必无法维护,也不利于代码复用. 此外,在一个Web

在Python中使用zlib模块进行数据压缩的教程

  这篇文章主要介绍了在Python中使用zlib模块进行数据压缩的教程,是Python入门学习中的基础知识,需要的朋友可以参考下 Python标准模块中,有多个模块用于数据的压缩与解压缩,如zipfile,gzip, bz2等等.上次介绍了zipfile模块,今天就来讲讲zlib模块. zlib.compress(string[, level]) zlib.decompress(string[, wbits[, bufsize]]) zlib.compress用于压缩流数据.参数string指

Python中的zipfile模块使用详解

  这篇文章主要介绍了Python中的zipfile模块使用详解,zipfile模块是用来操作zip文件,需要的朋友可以参考下 zip文件格式是通用的文档压缩标准,在ziplib模块中,使用ZipFile类来操作zip文件,下面具体介绍一下: class zipfile.ZipFile(file[, mode[, compression[, allowZip64]]]) 创建一个ZipFile对象,表示一个zip文件.参数file表示文件的路径或类文件对象(file-like object);参

在Python中使用glob模块查找文件路径的方法

  这篇文章主要介绍了在Python中使用glob模块查找文件路径的方法,使用模块其中的iglob方法实现起来非常简单,需要的朋友可以参考下 glob模块是最简单的模块之一,内容非常少.用它可以查找符合特定规则的文件路径名.跟使用windows下的文件搜索差不多.查找文件只用到三个匹配符:"*", "?", "[]"."*"匹配0个或多个字符;"?"匹配单个字符;"[]"匹配指定范围内的

给Python中的MySQLdb模块添加超时功能的教程

  这篇文章主要介绍了给Python中的MySQLdb模块添加超时功能的教程,timeout功能在服务器的运维当中非常有用,需要的朋友可以参考下 使用Python操作MySQL数据库的时候常使用MySQLdb这个模块. 今天在开发的过程发现MySQLdb.connect有些参数没法设置.通过这个页面我们可以看到在connect的时候,可以设置的option和client_flags和MySQL c api相比差不少. 一个很重要的参数 MYSQL_OPT_READ_TIMEOUT没法设置,这个参

在Python中使用mechanize模块模拟浏览器功能

  这篇文章主要介绍了在Python中使用mechanize模块模拟浏览器功能,包括使用cookie和设置代理等功能的实现,需要的朋友可以参考下 知道如何快速在命令行或者python脚本中实例化一个浏览器通常是非常有用的. 每次我需要做任何关于web的自动任务时,我都使用这段python代码去模拟一个浏览器. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import mechanize import cookielib # Br

在Python中使用PIL模块对图片进行高斯模糊处理的教程

  这篇文章主要介绍了在Python中使用PIL模块对图片进行高斯模糊处理的教程,这个无图形界面的脚本代码非常简单,需要的朋友可以参考下 从一篇文章中看到,PIL 1.1.5 已经内置了高斯模糊,但是并没有在文档中提及,而且PIL的高斯模糊中 radius 是硬编码, 虽然构造方法中有传入 radius 参数,但压根就没有用到 (看这里),所以需要自己进行改造,当然,知道了原因, 修改起来自然非常简单了. 结合帖子中的需求,对局部进行高斯模糊,所以还需要结合使用 crop 和 paste 方法实