diff --git a/docs/en_US/release_notes_5_4.rst b/docs/en_US/release_notes_5_4.rst index 239bbb38d..2ac631121 100644 --- a/docs/en_US/release_notes_5_4.rst +++ b/docs/en_US/release_notes_5_4.rst @@ -11,6 +11,7 @@ New features | `Issue #2341 `_ - Added support to launch PSQL for the connected database server. | `Issue #4064 `_ - Added window maximize/restore functionality for properties dialog. +| `Issue #6395 `_ - Added support to rotate the pgadmin log file on the basis of Size and Age. Housekeeping ************ diff --git a/web/config.py b/web/config.py index 3b34d69b4..feae86aeb 100644 --- a/web/config.py +++ b/web/config.py @@ -286,6 +286,13 @@ if SERVER_MODE and not IS_WIN: else: LOG_FILE = os.path.join(DATA_DIR, 'pgadmin4.log') +# Log rotation setting +# Log file will be rotated considering values for LOG_ROTATION_SIZE +# & LOG_ROTATION_AGE. Rotated file will be named in format +# - LOG_FILE.Y-m-d_H-M-S +LOG_ROTATION_SIZE = 10 # In MBs +LOG_ROTATION_AGE = 1440 # In minutes +LOG_ROTATION_MAX_LOG_FILES = 90 # Maximum number of backups to retain ########################################################################## # Server Connection Driver Settings ########################################################################## diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index fad910824..6e395f42f 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -262,7 +262,13 @@ def create_app(app_name=None): create_app_data_directory(config) # File logging - fh = logging.FileHandler(config.LOG_FILE, encoding='utf-8') + from pgadmin.utils.enhanced_log_rotation import \ + EnhancedRotatingFileHandler + fh = EnhancedRotatingFileHandler(config.LOG_FILE, + config.LOG_ROTATION_SIZE, + config.LOG_ROTATION_AGE, + config.LOG_ROTATION_MAX_LOG_FILES) + fh.setLevel(config.FILE_LOG_LEVEL) fh.setFormatter(logging.Formatter(config.FILE_LOG_FORMAT)) app.logger.addHandler(fh) diff --git a/web/pgadmin/utils/enhanced_log_rotation.py b/web/pgadmin/utils/enhanced_log_rotation.py new file mode 100644 index 000000000..00c5e9399 --- /dev/null +++ b/web/pgadmin/utils/enhanced_log_rotation.py @@ -0,0 +1,59 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2021, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import re +import logging.handlers as handlers + + +class EnhancedRotatingFileHandler(handlers.TimedRotatingFileHandler, + handlers.RotatingFileHandler): + """ + Handler for logging to a set of files, which switches from one file + to the next when the current file reaches a certain size, or at certain + timed intervals + @filename - log file name + @max_bytes - file size in bytes to rotate file + @interval - Duration to rotate file + @backup_count - Maximum number of files to retain + @encoding - file encoding + @when - 'when' events supported: + # S - Seconds + # M - Minutes + # H - Hours + # D - Days + # midnight - roll over at midnight + # W{0-6} - roll over on a certain day; 0 - Monday + Here we are defaulting rotation with minutes interval + """ + def __init__(self, filename, max_bytes=1, interval=60, backup_count=0, + encoding=None, when='M'): + max_bytes = max_bytes * 1024 * 1024 + handlers.TimedRotatingFileHandler.__init__(self, filename=filename, + when=when, + interval=interval, + backupCount=backup_count, + encoding=encoding) + + handlers.RotatingFileHandler.__init__(self, filename=filename, + mode='a', + maxBytes=max_bytes, + backupCount=backup_count, + encoding=encoding) + + # Time & Size combined rollover + def shouldRollover(self, record): + return handlers.TimedRotatingFileHandler.shouldRollover(self, record) \ + or handlers.RotatingFileHandler.shouldRollover(self, record) + + # Roll overs current file + def doRollover(self): + self.suffix = "%Y-%m-%d_%H-%M-%S" + self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}(\.\w+)?$" + self.extMatch = re.compile(self.extMatch, re.ASCII) + handlers.TimedRotatingFileHandler.doRollover(self)