Commit 00e2ebf6 authored by Guillaume Seguin's avatar Guillaume Seguin

WIP #561: Add log_path option to store log

This commit changes the way the Tee in Pronterface works. When no log is
specified, sys.stdout is redirected as before to a tee between the
console panel and the true sys.stdout. When a log is specified,
sys.stdout is untouched and logging output is saved in both the console
panel and the log file.
The side effect is that all output must now go through the logging
module to properly get in the console panel and in the log.
Now we have to catch all "print" statements =)
parent b423156f
......@@ -249,7 +249,8 @@ class pronsole(cmd.Cmd):
return False
def log(self, *msg):
print u"".join(unicode(i) for i in msg)
msg = u"".join(unicode(i) for i in msg)
logging.info(msg)
def logError(self, *msg):
msg = u"".join(unicode(i) for i in msg)
......
......@@ -63,8 +63,16 @@ from .settings import wxSetting, HiddenSetting, StringSetting, SpinSetting, \
from printrun import gcoder
from .pronsole import REPORT_NONE, REPORT_POS, REPORT_TEMP
class Tee(object):
def __init__(self, target):
class ConsoleOutputHandler(object):
"""Handle console output. All messages go through the logging submodule. We setup a logging handler to get logged messages and write them to both stdout (unless a log file path is specified, in which case we add another logging handler to write to this file) and the log panel.
When no file path is specified, we also redirect stdout to ourself to catch print messages and al."""
def __init__(self, target, log_path):
if log_path:
self.stdout = None
setup_logging(self, log_path)
self.target = target
else:
self.stdout = sys.stdout
sys.stdout = self
setup_logging(sys.stdout)
......@@ -78,6 +86,7 @@ class Tee(object):
self.target(data)
except:
pass
if self.stdout:
try:
data = data.encode("utf-8")
except:
......@@ -85,6 +94,7 @@ class Tee(object):
self.stdout.write(data)
def flush(self):
if self.stdout:
self.stdout.flush()
class ComboSetting(wxSetting):
......@@ -208,7 +218,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.statusbar = self.CreateStatusBar()
self.statusbar.SetStatusText(_("Not connected to printer."))
self.t = Tee(self.catchprint)
self.t = ConsoleOutputHandler(self.catchprint, self.settings.log_path)
self.stdout = sys.stdout
self.slicing = False
self.loading_gcode = False
......@@ -806,6 +816,7 @@ Printrun. If not, see <http://www.gnu.org/licenses/>."""
# --------------------------------------------------------------
def _add_settings(self, size):
self.settings._add(StringSetting("log_path", "", _("Log path"), _("Path to the log file. An empty path will log to the console."), "UI"))
self.settings._add(BooleanSetting("monitor", True, _("Monitor printer status"), _("Regularly monitor printer temperatures (required to have functional temperature graph or gauges)"), "Printer"), self.update_monitor)
self.settings._add(StringSetting("simarrange_path", "", _("Simarrange command"), _("Path to the simarrange binary to use in the STL plater"), "External"))
self.settings._add(BooleanSetting("circular_bed", False, _("Circular build platform"), _("Draw a circular (or oval) build platform instead of a rectangular one"), "Printer"), self.update_bed_viz)
......
......@@ -34,12 +34,31 @@ def install_locale(domain):
else:
gettext.install(domain, './locale', unicode = 1)
def setup_logging(out):
class LogFormatter(logging.Formatter):
def __init__(self, format_default, format_info):
super(LogFormatter, self).__init__(format_info)
self.format_default = format_default
self.format_info = format_info
def format(self, record):
if record.levelno == logging.INFO:
self._fmt = self.format_info
else:
self._fmt = self.format_default
return super(LogFormatter, self).format(record)
def setup_logging(out, filepath = None):
logger = logging.getLogger()
logger.setLevel(logging.INFO)
formatter = LogFormatter("[%(levelname)s] %(message)s", "%(message)s")
logger.handlers = []
logging_handler = logging.StreamHandler(out)
logging_handler.setFormatter(logging.Formatter("[%(levelname)s] %(message)s"))
logging_handler.setFormatter(formatter)
logger.addHandler(logging_handler)
if filepath is not None:
formatter = LogFormatter("%(asctime)s - [%(levelname)s] %(message)s", "%(asctime)s - %(message)s")
logging_handler = logging.FileHandler(filepath)
logging_handler.setFormatter(formatter)
logger.addHandler(logging_handler)
def iconfile(filename):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment