Created
October 5, 2019 20:36
-
-
Save arduino12/144c346c9f3ecc8175be45a2f6bda599 to your computer and use it in GitHub Desktop.
Python CSV Rotating Logger
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import logging | |
from logging.handlers import RotatingFileHandler | |
LOG_FILE_NAME = 'log.csv' | |
LOG_MAX_SIZE = 4096 # Max size of each log file in bytes | |
LOG_MAX_FILES = 4 # Max lof files count | |
LOG_HEADER = ['date', 'value_1', 'value_2'] # Pass None for no csv header | |
LOG_FORMAT = '%(asctime)s,%(message)s' # Log record format can use: asctime, levelname | |
LOG_DATE_FORMAT = '%Y/%m/%d %H:%M:%S' | |
class CsvFormatter(logging.Formatter): | |
def format_msg(self, msg): | |
'''Format the msg to csv string''' | |
if isinstance(msg, list): | |
msg = ','.join(map(str, msg)) | |
return msg | |
def format(self, record): | |
record.msg = self.format_msg(record.msg) | |
return logging.Formatter.format(self, record) | |
class CsvRotatingFileHandler(RotatingFileHandler): | |
def __init__(self, fmt, datefmt, filename, max_size, max_files, header=None): | |
handler = RotatingFileHandler.__init__(self, filename, maxBytes=max_size, backupCount=max_files) | |
self.formatter = CsvFormatter(fmt, datefmt) | |
# Format header string if needed | |
self._header = header and self.formatter.format_msg(header) | |
def rotation_filename(self, default_name): | |
'''Make log files counter before the .csv extension''' | |
s = default_name.rsplit('.', 2) | |
return '{}_{:0{}d}.csv'.format(s[0], int(s[-1]), self.backupCount // 10 + 1) | |
def doRollover(self): | |
'''Apped header string to each log file''' | |
RotatingFileHandler.doRollover(self) | |
if self._header is None: | |
return | |
f = self.formatter.format | |
self.formatter.format = lambda x: x | |
self.handle(self._header) | |
self.formatter.format = f | |
class RotatingCsvLogger(logging.Logger): | |
def __init__(self, level, fmt, datefmt, filename, max_size, max_files, header=None): | |
logging.Logger.__init__(self, filename.rsplit('.', 1)[0], level) | |
handler = CsvRotatingFileHandler(fmt, datefmt, filename, max_size, max_files, header) | |
self.addHandler(handler) | |
def main(): | |
# Creat logger with csv rotating handler | |
logger = RotatingCsvLogger(logging.INFO, LOG_FORMAT, LOG_DATE_FORMAT, | |
LOG_FILE_NAME, LOG_MAX_SIZE, LOG_MAX_FILES, LOG_HEADER) | |
# Log some records | |
for i in range(10): | |
logger.info([i, i * 2]) | |
# You can log list or string | |
logger.info([1000, 1000]) | |
logger.info('2000,2000') | |
# Note that "LOG_HEADER" will only appear in the rotated files (that ends with _1 _2..) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment