python自定义windowsr日志支持文件分割
妙音
posted @ 2021年1月20日 13:48
in python
, 1210 阅读
描述
python自带的RotatingFileHandler,在windows中运行, 分割文件rename时会出问题。因为windows不支持rename正在使用的文件
解决办法
自定义handler, 按大小和日期切割文件
原理: handler写文件时调用emit, 其中shouldRollover判断是否要分割, doRollover进行分割. 重写这个两个函数就可以
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class BaseRotatingHandler(logging.FileHandler): def emit( self , record): """ Emit a record. Output the record to the file, catering for rollover as described in doRollover(). """ try : if self .shouldRollover(record): self .doRollover() logging.FileHandler.emit( self , record) except Exception: self .handleError(record) |
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | import os import time import datetime import logging from logging.handlers import RotatingFileHandler from pathlib import Path class AutumnRotatingFileHandler(RotatingFileHandler): """ 日志+大小+支持windows """ def __init__( self , filename, mode = 'a' , maxBytes = 0 , backupCount = 99 , encoding = None , delay = False , backupDayCount = 30 ): filename = str (filename) self .date_format = "%Y%m%d" self .create_date = self ._now_date() self .backupCount = backupCount # 保存原始文件名 self .filename = str (Path(filename).absolute()) self .backupDayCount = backupDayCount RotatingFileHandler.__init__( self , self .last_file_name(filename), mode = mode, maxBytes = maxBytes, backupCount = backupCount, encoding = encoding, delay = delay) def _now_date( self ): return time.strftime( self .date_format, time.localtime()) def doRollover( self ): """ Do a rollover, as described in __init__(). """ # 关闭当前文件 if self .stream: self .stream.close() self .stream = None # 生成最新文件名 suffix = "." + self ._now_date() self .baseFilename = str ( self .filename) + suffix if self .backupCount > 0 : for i in range ( 0 , self .backupCount): number_suffix = "{:0>2d}" . format (i) sfn = "." .join([ self .baseFilename, number_suffix]) if os.path.exists(sfn): continue else : break number_suffix = "{:0>2d}" . format (i) self .baseFilename = "." .join([ self .baseFilename, number_suffix]) # 删除过期文件 self .deleteExpiredFiles() # 打开 self .stream = self ._open() self .create_date = self ._now_date() def shouldRollover( self , record): """ Determine if rollover should occur. Basically, see if the supplied record would cause the file to exceed the size limit we have. """ # 文件分割条件1: 日期变化 if self ._now_date() ! = self .create_date: return 1 if self .stream is None : # delay was set... self .stream = self ._open() # 文件分割条件1: 文件大小超过限制 if self .maxBytes > 0 : # are we rolling over? msg = "%s\n" % self . format (record) self .stream.seek( 0 , 2 ) #due to non-posix-compliant Windows feature if self .stream.tell() + len (msg) > = self .maxBytes: return 1 return 0 def deleteExpiredFiles( self ): """ 删除过期文件 """ dead_datetime = datetime.datetime.now() - datetime.timedelta(days = self .backupDayCount) filenames = [] for i in range ( 1 , 3 ): date = dead_datetime - datetime.timedelta(days = 1 ) date_str = date.strftime( self .date_format) base_name = "%s.%s" % ( self .filename, date_str) filenames.append(base_name) for j in range ( 1 , self .backupCount): sfn = "%s.%d" % (base_name, j) filenames.append(sfn) # delete file for filename in filenames: if os.path.exists(filename): try : os.remove(sfn) except : pass def last_file_name( self , filename): """ 文件名 """ suffix = "." + self ._now_date() base_filename = str (filename) + suffix if self .backupCount > 0 : for i in reversed ( range ( 0 , self .backupCount)): number_suffix = "{:0>2d}" . format (i) sfn = "." .join([base_filename, number_suffix]) # 最近存在的文件 if os.path.exists(sfn): break else : continue number_suffix = "{:0>2d}" . format (i) base_filename = "." .join([base_filename, number_suffix]) return base_filename |
2024年1月17日 15:34
https://m.goaloo88.com/
https://www.goaloo88.com/
Goaloo covers 2000+ soccer/football and basketball leagues, cups and tournaments (English Premier League/EPL, and UEFA Champions League, NBA etc.).
2024年1月17日 15:34
https://m.goaloo88.com/
https://www.goaloo88.com/
Goaloo covers 2000+ soccer/football and basketball leagues, cups and tournaments (English Premier League/EPL, and UEFA Champions League, NBA etc.).
2024年11月09日 13:05
Don’t think. Thinking is the enemy of creativity. It’s self-conscious, and anything self-conscious is lousy.
You can’t try to do things. You simply must do things.” – Ray Bradbury
2025年1月08日 12:03
<a href="https://naikpharmacy.in/">NaikPharmacy</a> is a great online platform for all your healthcare needs! The variety of products, fast delivery, and excellent customer service make it my go-to for medications and wellness items. Highly recommend!
2025年1月08日 12:04
Naikpharmacy is a great online platform for all your healthcare needs! The variety of products, fast delivery, and excellent customer service make it my go-to for medications and wellness items. Highly recommend!
https://naikpharmacy.in/
2025年1月26日 22:25
Awais International offers a fantastic range of IT products, including high-quality desktop computers, gaming laptops, and gaming PCs. They provide some of the best gaming laptops on the market, ensuring top-notch performance and reliability for gamers and professionals alike. A one-stop shop for all your tech needs!
https://awaisinternational.com/