Merge branch 'improve/loggingHandlers' into maintenance

This commit is contained in:
Gina Häußge 2016-10-12 18:15:12 +02:00
commit 67634e4f7c
9 changed files with 108 additions and 8 deletions

View file

@ -1,4 +1,6 @@
#!/usr/bin/env python
from __future__ import absolute_import
import sys
from octoprint.daemon import Daemon
from octoprint.server import Server

View file

@ -0,0 +1,4 @@
# coding=utf-8
from __future__ import absolute_import
from . import handlers

View file

@ -0,0 +1,83 @@
# coding=utf-8
from __future__ import absolute_import
import logging.handlers
import os
import re
import time
class CleaningTimedRotatingFileHandler(logging.handlers.TimedRotatingFileHandler):
def __init__(self, *args, **kwargs):
logging.handlers.TimedRotatingFileHandler.__init__(self, *args, **kwargs)
# clean up old files on handler start
if self.backupCount > 0:
for s in self.getFilesToDelete():
os.remove(s)
class SerialLogHandler(logging.handlers.RotatingFileHandler):
_do_rollover = False
_suffix_template = "%Y-%m-%d_%H-%M-%S"
_file_pattern = re.compile(r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}$")
@classmethod
def on_open_connection(cls):
cls._do_rollover = True
def __init__(self, *args, **kwargs):
logging.handlers.RotatingFileHandler.__init__(self, *args, **kwargs)
self.cleanupFiles()
def emit(self, record):
logging.handlers.RotatingFileHandler.emit(self, record)
def shouldRollover(self, record):
return self.__class__._do_rollover
def getFilesToDelete(self):
"""
Determine the files to delete when rolling over.
"""
dirName, baseName = os.path.split(self.baseFilename)
fileNames = os.listdir(dirName)
result = []
prefix = baseName + "."
plen = len(prefix)
for fileName in fileNames:
if fileName[:plen] == prefix:
suffix = fileName[plen:]
if self.__class__._file_pattern.match(suffix):
result.append(os.path.join(dirName, fileName))
result.sort()
if len(result) < self.backupCount:
result = []
else:
result = result[:len(result) - self.backupCount]
return result
def cleanupFiles(self):
if self.backupCount > 0:
for path in self.getFilesToDelete():
os.remove(path)
def doRollover(self):
self.__class__._do_rollover = False
if self.stream:
self.stream.close()
self.stream = None
if os.path.exists(self.baseFilename):
# figure out creation date/time to use for file suffix
t = time.localtime(os.stat(self.baseFilename).st_mtime)
dfn = self.baseFilename + "." + time.strftime(self.__class__._suffix_template, t)
if os.path.exists(dfn):
os.remove(dfn)
os.rename(self.baseFilename, dfn)
self.cleanupFiles()
if not self.delay:
self.stream = self._open()

View file

@ -46,7 +46,8 @@ class CuraPlugin(octoprint.plugin.SlicerPlugin,
def on_startup(self, host, port):
# setup our custom logger
cura_logging_handler = logging.handlers.RotatingFileHandler(self._settings.get_plugin_logfile_path(postfix="engine"), maxBytes=2*1024*1024)
from octoprint.logging.handlers import CleaningTimedRotatingFileHandler
cura_logging_handler = CleaningTimedRotatingFileHandler(self._settings.get_plugin_logfile_path(postfix="engine"), when="D", backupCount=3)
cura_logging_handler.setFormatter(logging.Formatter("%(asctime)s %(message)s"))
cura_logging_handler.setLevel(logging.DEBUG)

View file

@ -65,7 +65,8 @@ class PluginManagerPlugin(octoprint.plugin.SimpleApiPlugin,
##~~ StartupPlugin
def on_startup(self, host, port):
console_logging_handler = logging.handlers.RotatingFileHandler(self._settings.get_plugin_logfile_path(postfix="console"), maxBytes=2*1024*1024)
from octoprint.logging.handlers import CleaningTimedRotatingFileHandler
console_logging_handler = CleaningTimedRotatingFileHandler(self._settings.get_plugin_logfile_path(postfix="console"), when="D", backupCount=3)
console_logging_handler.setFormatter(logging.Formatter("%(asctime)s %(message)s"))
console_logging_handler.setLevel(logging.DEBUG)

View file

@ -194,6 +194,10 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback):
if self._comm is not None:
self._comm.close()
self._printerProfileManager.select(profile)
from octoprint.logging.handlers import SerialLogHandler
SerialLogHandler.on_open_connection()
self._comm = comm.MachineCom(port, baudrate, callbackObject=self, printerProfileManager=self._printerProfileManager)
def disconnect(self):

View file

@ -564,6 +564,9 @@ class Server(object):
"formatters": {
"simple": {
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
},
"serial": {
"format": "%(asctime)s - %(message)s"
}
},
"handlers": {
@ -574,18 +577,18 @@ class Server(object):
"stream": "ext://sys.stdout"
},
"file": {
"class": "logging.handlers.TimedRotatingFileHandler",
"class": "octoprint.logging.handlers.CleaningTimedRotatingFileHandler",
"level": "DEBUG",
"formatter": "simple",
"when": "D",
"backupCount": "1",
"backupCount": 6,
"filename": os.path.join(settings().getBaseFolder("logs"), "octoprint.log")
},
"serialFile": {
"class": "logging.handlers.RotatingFileHandler",
"class": "octoprint.logging.handlers.SerialLogHandler",
"level": "DEBUG",
"formatter": "simple",
"maxBytes": 2 * 1024 * 1024, # let's limit the serial log to 2MB in size
"formatter": "serial",
"backupCount": 3,
"filename": os.path.join(settings().getBaseFolder("logs"), "serial.log")
}
},
@ -633,7 +636,6 @@ class Server(object):
if settings().getBoolean(["serial", "log"]):
# enable debug logging to serial.log
logging.getLogger("SERIAL").setLevel(logging.DEBUG)
logging.getLogger("SERIAL").debug("Enabling serial logging")
def _setup_app(self, app):
from octoprint.server.util.flask import ReverseProxiedEnvironment, OctoPrintFlaskRequest, OctoPrintFlaskResponse

View file

@ -1,4 +1,5 @@
# coding=utf-8
from __future__ import absolute_import
__author__ = "Gina Häußge <osd@foosel.net>"
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'

View file

@ -1,4 +1,6 @@
# coding=utf-8
from __future__ import absolute_import
"""
This module bundles commonly used utility methods or helper classes that are used in multiple places withing
OctoPrint's source code.