diff --git a/docs/installguide/release_notes.rst b/docs/installguide/release_notes.rst index 99e6902a16..18b9c12ff2 100644 --- a/docs/installguide/release_notes.rst +++ b/docs/installguide/release_notes.rst @@ -25,6 +25,12 @@ Bug fixes * Add line breaks in buttons so text isn't cut :url-issue:`5004` +New features +^^^^^^^^^^^^ + + * Log rotation: Logs for 30 days are now stored in ``~/.kalite/logs`` :url-issue:`4890` + + Known issues ^^^^^^^^^^^^ diff --git a/kalite/cli.py b/kalite/cli.py index 20a6e56a2f..8e669dfa95 100644 --- a/kalite/cli.py +++ b/kalite/cli.py @@ -123,7 +123,7 @@ # Where to store user data KALITE_HOME = os.environ["KALITE_HOME"] -SERVER_LOG = os.path.join(KALITE_HOME, "server.log") +DAEMON_LOG = os.path.join(KALITE_HOME, "server.log") if not os.path.isdir(KALITE_HOME): os.mkdir(KALITE_HOME) @@ -493,11 +493,11 @@ def start(debug=False, daemonize=True, args=[], skip_job_scheduler=False, port=N from django.utils.daemonize import become_daemon kwargs = {} # Truncate the file - open(SERVER_LOG, "w").truncate() - print("Going to daemon mode, logging to {0}\n".format(SERVER_LOG)) + open(DAEMON_LOG, "w").truncate() + print("Going to daemon mode, logging to {0}\n".format(DAEMON_LOG)) print_server_address(port) - kwargs['out_log'] = SERVER_LOG - kwargs['err_log'] = SERVER_LOG + kwargs['out_log'] = DAEMON_LOG + kwargs['err_log'] = DAEMON_LOG become_daemon(**kwargs) # Write the new PID with open(PID_FILE, 'w') as f: @@ -665,7 +665,7 @@ def status(): STATUS_STOPPED: 'Stopped', STATUS_STARTING_UP: 'Starting up', STATUS_NOT_RESPONDING: 'Not responding', - STATUS_FAILED_TO_START: 'Failed to start (check log file: {0})'.format(SERVER_LOG), + STATUS_FAILED_TO_START: 'Failed to start (check log file: {0})'.format(DAEMON_LOG), STATUS_UNCLEAN_SHUTDOWN: 'Unclean shutdown', STATUS_UNKNOWN_INSTANCE: 'Unknown KA Lite running on port', STATUS_SERVER_CONFIGURATION_ERROR: 'KA Lite server configuration error', diff --git a/kalite/settings/base.py b/kalite/settings/base.py index 5a4d589276..c2bcd40d9a 100644 --- a/kalite/settings/base.py +++ b/kalite/settings/base.py @@ -44,7 +44,17 @@ # We should use local module level logging.getLogger LOG = logging.getLogger("kalite") -SERVER_LOG = os.path.join(USER_DATA_ROOT, "server.log") +DAEMON_LOG = os.path.join(USER_DATA_ROOT, "server.log") + +LOG_ROOT = os.environ.get( + "KALITE_LOG_ROOT", + os.path.join(USER_DATA_ROOT, "logs") +) + +# Ensure that path exists +if not os.path.exists(LOG_ROOT): + os.mkdir(LOG_ROOT) + LOGGING = { 'version': 1, @@ -80,6 +90,15 @@ 'formatter': 'no_format', 'stream': sys.stdout, }, + 'file': { + 'level': 'INFO', + 'class': 'logging.handlers.TimedRotatingFileHandler', + 'filename': os.path.join(LOG_ROOT, 'django.log'), + 'formatter': 'standard', + 'when': 'midnight', + 'backupCount': '30', + 'maxBytes': 1 * 1024 * 1024, + }, }, 'loggers': { 'django': { @@ -93,37 +112,37 @@ 'propagate': False, }, 'kalite': { - 'handlers': ['console'], + 'handlers': ['console', 'file'], 'level': LOGGING_LEVEL, 'propagate': False, }, 'kalite.distributed.management.commands': { - 'handlers': ['console_no_format'], + 'handlers': ['console_no_format', 'file'], 'level': LOGGING_LEVEL, 'propagate': False, }, 'fle_utils': { - 'handlers': ['console'], + 'handlers': ['console', 'file'], 'level': LOGGING_LEVEL, 'propagate': False, }, 'cherrypy.console': { - 'handlers': ['console'], + 'handlers': ['console', 'file'], 'level': LOGGING_LEVEL, 'propagate': False, }, 'cherrypy.access': { - 'handlers': ['console'], + 'handlers': ['console', 'file'], 'level': LOGGING_LEVEL, 'propagate': False, }, 'cherrypy.error': { - 'handlers': ['console'], + 'handlers': ['console', 'file'], 'level': LOGGING_LEVEL, 'propagate': False, }, '': { - 'handlers': ['console'], + 'handlers': ['console', 'file'], 'level': 'INFO', 'propagate': False, },