From f150d8bae53da352d5b48b677c68ddd66665f3ea Mon Sep 17 00:00:00 2001 From: Tehom Date: Sat, 20 May 2017 21:33:57 -0400 Subject: [PATCH 1/4] Add Evennia logfile class based on Twisted LogFile for automatic rotating channel logs. Append tail end of logs when rotating, customizable with settings. --- evennia/settings_default.py | 4 ++++ evennia/utils/logger.py | 28 +++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/evennia/settings_default.py b/evennia/settings_default.py index c5844205c..c472268a7 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -125,6 +125,10 @@ LOCKWARNING_LOG_FILE = os.path.join(LOG_DIR, 'lockwarnings.log') # file sizes down. Turn off to get ever growing log files and never # loose log info. CYCLE_LOGFILES = True +# Number of lines to append to rotating channel logs when they rotate +NUM_LOG_TAIL_LINES = 20 +# Max size of channel log files before they rotate +LOG_ROTATE_SIZE = 1000000 # Local time zone for this installation. All choices can be found here: # http://www.postgresql.org/docs/8.0/interactive/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE TIME_ZONE = 'UTC' diff --git a/evennia/utils/logger.py b/evennia/utils/logger.py index a46c549de..a22e313bc 100644 --- a/evennia/utils/logger.py +++ b/evennia/utils/logger.py @@ -19,8 +19,9 @@ import os import time from datetime import datetime from traceback import format_exc -from twisted.python import log +from twisted.python import log, logfile from twisted.internet.threads import deferToThread +from django.conf import settings _LOGDIR = None @@ -153,6 +154,27 @@ log_depmsg = log_dep # Arbitrary file logger +class EvenniaLogFile(logfile.LogFile): + num_lines_to_append = settings.NUM_LOG_TAIL_LINES + + def rotate(self): + append_tail = self.num_lines_to_append > 0 + print "append_tail is %s" % append_tail + if not append_tail: + logfile.LogFile.rotate(self) + return + lines = tail_log_file(self.path, 0, self.num_lines_to_append) + print "lines is %s" % lines + logfile.LogFile.rotate(self) + for line in lines: + self.write(line) + + def seek(self, *args, **kwargs): + return self._file.seek(*args, **kwargs) + + def readlines(self, *args, **kwargs): + return self._file.readlines(*args, **kwargs) + _LOG_FILE_HANDLES = {} # holds open log handles @@ -164,7 +186,6 @@ def _open_log_file(filename): """ global _LOG_FILE_HANDLES, _LOGDIR if not _LOGDIR: - from django.conf import settings _LOGDIR = settings.LOG_DIR filename = os.path.join(_LOGDIR, filename) @@ -173,7 +194,8 @@ def _open_log_file(filename): return _LOG_FILE_HANDLES[filename] else: try: - filehandle = open(filename, "a+") # append mode + reading + filehandle = EvenniaLogFile.fromFullPath(filename, rotateLength=settings.LOG_ROTATE_SIZE) + # filehandle = open(filename, "a+") # append mode + reading _LOG_FILE_HANDLES[filename] = filehandle return filehandle except IOError: From 6e2c10b008783ce13042f42b6fe3fa1b730cca81 Mon Sep 17 00:00:00 2001 From: Tehom Date: Sat, 20 May 2017 22:18:26 -0400 Subject: [PATCH 2/4] Remove print statements I had left in during debugging. Oops. --- evennia/utils/logger.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/evennia/utils/logger.py b/evennia/utils/logger.py index a22e313bc..70bf223fe 100644 --- a/evennia/utils/logger.py +++ b/evennia/utils/logger.py @@ -159,12 +159,10 @@ class EvenniaLogFile(logfile.LogFile): def rotate(self): append_tail = self.num_lines_to_append > 0 - print "append_tail is %s" % append_tail if not append_tail: logfile.LogFile.rotate(self) return lines = tail_log_file(self.path, 0, self.num_lines_to_append) - print "lines is %s" % lines logfile.LogFile.rotate(self) for line in lines: self.write(line) From 4605b3128ec7108a471d9f63fb23839d4a72bd90 Mon Sep 17 00:00:00 2001 From: Tehom Date: Sun, 21 May 2017 03:29:33 -0400 Subject: [PATCH 3/4] Add docstr to class and methods, adjust names of settings to be more clearly modifying channel logs. --- evennia/settings_default.py | 4 ++-- evennia/utils/logger.py | 31 +++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/evennia/settings_default.py b/evennia/settings_default.py index c472268a7..f94bf5d3e 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -126,9 +126,9 @@ LOCKWARNING_LOG_FILE = os.path.join(LOG_DIR, 'lockwarnings.log') # loose log info. CYCLE_LOGFILES = True # Number of lines to append to rotating channel logs when they rotate -NUM_LOG_TAIL_LINES = 20 +CHANNEL_LOG_NUM_TAIL_LINES = 20 # Max size of channel log files before they rotate -LOG_ROTATE_SIZE = 1000000 +CHANNEL_LOG_ROTATE_SIZE = 1000000 # Local time zone for this installation. All choices can be found here: # http://www.postgresql.org/docs/8.0/interactive/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE TIME_ZONE = 'UTC' diff --git a/evennia/utils/logger.py b/evennia/utils/logger.py index 70bf223fe..bde064992 100644 --- a/evennia/utils/logger.py +++ b/evennia/utils/logger.py @@ -155,9 +155,19 @@ log_depmsg = log_dep # Arbitrary file logger class EvenniaLogFile(logfile.LogFile): - num_lines_to_append = settings.NUM_LOG_TAIL_LINES + """ + A rotating logfile based off Twisted's LogFile. It overrides + the LogFile's rotate method in order to append some of the last + lines of the previous log to the start of the new log, in order + to preserve a continuous chat history for channel log files. + """ + num_lines_to_append = settings.CHANNEL_LOG_NUM_TAIL_LINES def rotate(self): + """ + Rotates our log file and appends some number of lines from + the previous log to the start of the new one. + """ append_tail = self.num_lines_to_append > 0 if not append_tail: logfile.LogFile.rotate(self) @@ -168,9 +178,26 @@ class EvenniaLogFile(logfile.LogFile): self.write(line) def seek(self, *args, **kwargs): + """ + Convenience method for accessing our _file attribute's seek method, + which is used in tail_log_function. + Args: + *args: Same args as file.seek + **kwargs: Same kwargs as file.seek + """ return self._file.seek(*args, **kwargs) def readlines(self, *args, **kwargs): + """ + Convenience method for accessing our _file attribute's readlines method, + which is used in tail_log_function. + Args: + *args: same args as file.readlines + **kwargs: same kwargs as file.readlines + + Returns: + lines (list): lines from our _file attribute. + """ return self._file.readlines(*args, **kwargs) _LOG_FILE_HANDLES = {} # holds open log handles @@ -192,7 +219,7 @@ def _open_log_file(filename): return _LOG_FILE_HANDLES[filename] else: try: - filehandle = EvenniaLogFile.fromFullPath(filename, rotateLength=settings.LOG_ROTATE_SIZE) + filehandle = EvenniaLogFile.fromFullPath(filename, rotateLength=settings.CHANNEL_LOG_ROTATE_SIZE) # filehandle = open(filename, "a+") # append mode + reading _LOG_FILE_HANDLES[filename] = filehandle return filehandle From 2bea778181f9f81e7eba2a77b07521f07f9dbb33 Mon Sep 17 00:00:00 2001 From: Tehom Date: Sun, 21 May 2017 06:59:54 -0400 Subject: [PATCH 4/4] Move settings to be local imports to prevent conflicts before django is fully loaded --- evennia/utils/logger.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/evennia/utils/logger.py b/evennia/utils/logger.py index bde064992..adf960d04 100644 --- a/evennia/utils/logger.py +++ b/evennia/utils/logger.py @@ -21,7 +21,6 @@ from datetime import datetime from traceback import format_exc from twisted.python import log, logfile from twisted.internet.threads import deferToThread -from django.conf import settings _LOGDIR = None @@ -161,6 +160,7 @@ class EvenniaLogFile(logfile.LogFile): lines of the previous log to the start of the new log, in order to preserve a continuous chat history for channel log files. """ + from django.conf import settings num_lines_to_append = settings.CHANNEL_LOG_NUM_TAIL_LINES def rotate(self): @@ -209,6 +209,7 @@ def _open_log_file(filename): handle. Will create a new file in the log dir if one didn't exist. """ + from django.conf import settings global _LOG_FILE_HANDLES, _LOGDIR if not _LOGDIR: _LOGDIR = settings.LOG_DIR