在应用程序使用中,日志输出对应用维护人员、开发人员判断程序的问题起重要作用。

那么在python中如何定义程序的日志输出? 推荐使用日志模块logging

需求:实现日志内容输出在文件中和控制器中

 import logging

 # 日志配置
logger = logging.getLogger("ys_monitor")
logger.setLevel(logging.DEBUG) # 全局
formatter = logging.Formatter('%(asctime)s - %(levelname)s -%(module)s: %(message)s') # 日志格式 fh = logging.FileHandler(filename_path) # 文件输出
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter) # 应用给文件
logger.addHandler(fh) # 把文件句柄交给logger接口执行 #ch = logging.StreamHandler() # 屏幕输出
#ch.setLevel(logging.DEBUG)
#ch.setFormatter(formatter) # 应用给屏幕
#logger.addHandler(ch) # 把屏幕句柄交给logger接口执行

模块级函数
logging.getLogger([name]):返回一个logger对象,如果没有指定名字将返回root logger
logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical():设定root logger的日志级别
Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高

Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别

Formatters

Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S,下面是Formatter常用的一些信息

%(name)s

Logger的名字

%(levelno)s

数字形式的日志级别

%(levelname)s

文本形式的日志级别

%(pathname)s

调用日志输出函数的模块的完整路径名,可能没有

%(filename)s

调用日志输出函数的模块的文件名

%(module)s

调用日志输出函数的模块名

%(funcName)s

调用日志输出函数的函数名

%(lineno)d

调用日志输出函数的语句所在的代码行

%(created)f

当前时间,用UNIX标准的表示时间的浮 点数表示

%(relativeCreated)d

输出日志信息时的,自Logger创建以 来的毫秒数

%(asctime)s

字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒

%(thread)d

线程ID。可能没有

%(threadName)s

线程名。可能没有

%(process)d

进程ID。可能没有

%(message)s

用户输出的消息

需求:对于文件日志输出,随着时间的增长,日志内容越来越多,文件越来越大,不利于以后的查看。需要将文件按时间分割。

配置文件

 ###############################################
[loggers]
keys=root,wj [logger_root]
level=DEBUG
handlers=hand01 [logger_wj]
handlers=hand02
qualname=wj
propagate=0 ###############################################
[handlers]
keys=hand01,hand02 [handler_hand01]
class=StreamHandler
level=DEBUG
formatter=formatter02
args=(sys.stdout,) [handler_hand02]
class=handlers.TimedRotatingFileHandler
level=DEBUG
formatter=formatter02
args=('./log/mixh5monitor.log','midnight',1,30) ###############################################
[formatters]
keys=formatter01,formatter02 [formatter_formatter01]
format=%(asctime)s - %(process)d - %(module)s - %(levelname)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S [formatter_formatter02]
format=%(asctime)s - %(process)d - %(module)s - %(levelname)s - %(message)s
datefmt=

引入配置文件代码,单独放入一个log_config.py文件

 import logging
import logging.config LOGCONF_FILENAME = "./etc/logging.conf"
logging.config.fileConfig(LOGCONF_FILENAME)
logger = logging.getLogger('wj')

logging.handlers.RotatingFileHandler

个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建
一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把

文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建
chat.log,继续输出日志信息。它的构造函数是:
RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中filename和mode两个参数和FileHandler一样。
maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。

logging.handlers.TimedRotatingFileHandler

个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就
自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:
TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
interval是时间间隔。
when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
S 秒
M 分
H 小时
D 天
W 每星期(interval==0时代表星期一)
midnight 每天凌晨

其它py文件引入log_config.py文件写日志方法

 import log_config

 log_config.logger.debug('debug')
log_config.logger.info('info')

Python多进程log日志切分错误的解决方案

 #修改后的代码,从30行开始引用文件锁,保证进程间的原子性。
import time
import os
import fcntl
import struct from logging.handlers import TimedRotatingFileHandler class MultiProcessTimedRotatingFileHandler(TimedRotatingFileHandler): def doRollover(self):
"""
do a rollover; in this case, a date/time stamp is appended to the filename
when the rollover happens. However, you want the file to be named for the
start of the interval, not the current time. If there is a backup count,
then we have to get a list of matching filenames, sort them and remove
the one with the oldest suffix.
"""
#if self.stream:
# self.stream.close()
# get the time that this sequence started at and make it a TimeTuple
t = self.rolloverAt - self.interval
if self.utc:
timeTuple = time.gmtime(t)
else:
timeTuple = time.localtime(t)
dfn = self.baseFilename + "." + time.strftime(self.suffix, timeTuple)
#if os.path.exists(dfn):
# os.remove(dfn)
lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)
fcntl.fcntl(self.stream, fcntl.F_SETLKW, lockdata)
if not os.path.exists(dfn) and os.path.exists(self.baseFilename):
os.rename(self.baseFilename, dfn)
with open(self.baseFilename, 'a'):
pass
if self.backupCount > 0:
# find the oldest log file and delete it
#s = glob.glob(self.baseFilename + ".20*")
#if len(s) > self.backupCount:
# s.sort()
# os.remove(s[0])
for s in self.getFilesToDelete():
os.remove(s)
#print "%s -> %s" % (self.baseFilename, dfn)
if self.stream:
self.stream.close()
self.mode = 'a'
self.stream = self._open()
currentTime = int(time.time())
newRolloverAt = self.computeRollover(currentTime)
while newRolloverAt <= currentTime:
newRolloverAt = newRolloverAt + self.interval
#If DST changes and midnight or weekly rollover, adjust for this.
if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc:
dstNow = time.localtime(currentTime)[-1]
dstAtRollover = time.localtime(newRolloverAt)[-1]
if dstNow != dstAtRollover:
if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour
newRolloverAt = newRolloverAt - 3600
else: # DST bows out before next rollover, so we need to add an hour
newRolloverAt = newRolloverAt + 3600
self.rolloverAt = newRolloverAt

参考:

http://my.oschina.net/leejun2005/blog/126713

http://blog.sina.com.cn/s/blog_3fe961ae01016upf.html

http://lightthewoods.me/2013/11/18/Python%E5%A4%9A%E8%BF%9B%E7%A8%8Blog%E6%97%A5%E5%BF%97%E5%88%87%E5%88%86%E9%94%99%E8%AF%AF%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/

http://www.jianshu.com/p/d615bf01e37b#

日志模块logging使用心得的更多相关文章

  1. python日志模块logging

    python日志模块logging   1. 基础用法 python提供了一个标准的日志接口,就是logging模块.日志级别有DEBUG.INFO.WARNING.ERROR.CRITICAL五种( ...

  2. 加密模块hashlib+日志模块logging

    目录 1.hashlib 加密模块 1.hashlib模块基本使用 1.2 详细操作 ①md5加密模式 ②sha256复杂加密模式 ③加盐操作(普通加盐) ④加盐操作(动态加盐) 2.logging ...

  3. Python 日志模块 logging通过配置文件方式使用

    vim logger_config.ini[loggers]keys=root,infoLogger,errorlogger [logger_root]level=DEBUGhandlers=info ...

  4. Python(2.7.6) 标准日志模块 - Logging Handler

    Python 标准日志模块使用 Handler 控制日志消息写到不同的目的地,如文件.流.邮件.socket 等.除了StreamHandler. FileHandler 和 NullHandler ...

  5. python 重要的日志模块logging

    一,logging模块简介 logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等:相比print,具备如下优点: 可以通过设置不同 ...

  6. 【python】【logging】python日志模块logging常用功能

    logging模块:应用程序的灵活事件日志系统,可以打印并自定义日志内容 logging.getLogger 创建一个log对象 >>> log1=logging.getLogger ...

  7. Python 日志模块logging

    logging模块: logging是一个日志记录模块,可以记录我们日常的操作. logging日志文件写入默认是gbk编码格式的,所以在查看时需要使用gbk的解码方式打开. logging日志等级: ...

  8. Python日志模块logging用法

    1.日志级别 日志一共分成5个等级,从低到高分别是:DEBUG INFO WARNING ERROR CRITICAL. DEBUG:详细的信息,通常只出现在诊断问题上 INFO:确认一切按预期运行 ...

  9. Python日志模块logging&JSON

    日志模块的用法 json部分 先开一段测试代码:注意  str可以直接处理字典   eval可以直接将字符串转成字典的形式 dic={'key1':'value1','key2':'value2'} ...

随机推荐

  1. [BZOJ3696][FJSC2014]化合物(异或规则下的母函数)

    题目:http://hzwer.com/3708.html 分析: 类似树分治思想,设f[x][i]表示以x为根的子树的所有点中,与x的距离为i的点有多少个,这个可以预处理出来 然后我们考虑每颗子树对 ...

  2. java list随机打乱

    java list随机打乱package arrlist; import java.util.ArrayList; import java.util.Collections; import java. ...

  3. IOS -- 获取本地图片和网络图片的大小size

    // 获取图片的size CGSize size = [UIImage imageNamed:@"regStep2_sex"].size; 获取网络图片的尺寸: // 根据图片ur ...

  4. 11-cp 命令总结

  5. 关于web前端的学习路线

    第一阶段: HTML+CSS:HTML进阶.CSS进阶.div+css布局.HTML+css整站开发. JavaScript基础:Js基础教程.js内置对象常用方法.常见DOM树操作大全.ECMAsc ...

  6. Oracle SQL Developer 添加SQLServer 和Sybase 连接

    来源于: http://blog.csdn.net/kk185800961/article/details/8602306 1. 开始只有Oracle 和access 连接 2. 打开Oracle S ...

  7. 评价指标ROC,PR

    之前实习的时候一直见公司里面的人说什么AUC, 实际AUC就是ROC曲线的面积 PR是precise和recall曲线,和ROC的区别是,当测试集中的正负样本分布变化的时候,ROC曲线能够保持不变,而 ...

  8. python安装失败0x80240017

    安装KB2999226更新补丁后, 可以正常安装python3.5. 此更新包在vs2015的patch包里有.Microsoft下载中心也有,这里列出的适用于win7x86: Windows 7 更 ...

  9. HTTPS基本原理

    HTTPS基本原理 Xcode7上,默认采用的传输协议就是HTTPS,大家都知道HTTPS = HTTP + SSL,利用HTTPS协议传输的数据是加密的,更加安全.在此对概念性知识不再介绍.直接介绍 ...

  10. for循环 打印菱形 空 和 实

    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><?ph ...