From: Neal H. Walfield Date: Mon, 22 Aug 2011 19:11:10 +0000 (+0200) Subject: Redirect output to log files. X-Git-Url: https://vcs.maemo.org/git/?a=commitdiff_plain;h=ca6f63b481b243c8e4167001e458c92dd20b3df0;p=feedingit Redirect output to log files. --- diff --git a/src/FeedingIt-Web.py b/src/FeedingIt-Web.py index 4c9c141..af3395f 100644 --- a/src/FeedingIt-Web.py +++ b/src/FeedingIt-Web.py @@ -11,6 +11,9 @@ from threading import Thread from os.path import isfile, isdir, exists from os import mkdir, remove, stat, environ +import debugging +debugging.init(dot_directory=".feedingit", program_name="feedingit-web") + CONFIGDIR = environ.get("HOME", "/home/user") + "/.feedingit" #CONFIGDIR = "/home/user/.feedingit/" diff --git a/src/FeedingIt.py b/src/FeedingIt.py index be9eb80..a808c26 100644 --- a/src/FeedingIt.py +++ b/src/FeedingIt.py @@ -46,6 +46,7 @@ from updatedbus import UpdateServerObject, get_lock from config import Config from cgi import escape import weakref +import debugging from rss_sqlite import Listing from opml import GetOpmlData, ExportOpmlData @@ -1484,6 +1485,7 @@ class FeedingIt: if __name__ == "__main__": mainthread.init () + debugging.init(dot_directory=".feedingit", program_name="feedingit") gobject.signal_new("feed-closed", DisplayFeed, gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)) gobject.signal_new("article-closed", DisplayArticle, gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)) diff --git a/src/debugging.py b/src/debugging.py new file mode 100644 index 0000000..7330871 --- /dev/null +++ b/src/debugging.py @@ -0,0 +1,113 @@ +# Copyright (c) 2011 Neal H. Walfield +# +# This software is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import with_statement +import os +import logging +import itertools +import sys +import string +import traceback +import time +import errno +import glob + +logger = None +original_excepthook = None + +def my_excepthook(exctype, value, tb): + """Log uncaught exceptions.""" + logger.error( + "Uncaught exception: %s" + % (''.join(traceback.format_exception(exctype, value, tb)),)) + original_excepthook(exctype, value, tb) + +def init(dot_directory, debug=False, max_logfiles=1, program_name=None): + if not os.path.isabs(dot_directory): + dot_directory = os.path.join(os.path.expanduser("~"), dot_directory) + + logging_directory = os.path.join(dot_directory, "logging") + try: + os.makedirs(logging_directory) + except OSError, e: + if e.errno != errno.EEXIST: + raise + + if program_name is None: + program_name = os.path.basename(sys.argv[0]) + string.translate(program_name, string.maketrans(' .', '__')) + + timestamp = time.strftime("%Y%m%d") + + logfiles = glob.glob(os.path.join(logging_directory, + program_name + '-*.log')) + if len(logfiles) >= max_logfiles: + logfiles.sort() + for f in logfiles[:-(max_logfiles+1)]: + print "Purging old log file %s" % (f,) + try: + os.remove(f) + except OSError, e: + print "Removing %s: %s" % (f, str(e)) + + logfile = os.path.join(logging_directory, + program_name + '-' + timestamp + '.log') + + print "Sending output to %s" % logfile + + global logger + logger = logging.getLogger(__name__) + + if debug: + level = logging.DEBUG + else: + level = logging.INFO + + logging.basicConfig( + level=level, + format=('%(asctime)s (pid: ' + str(os.getpid()) + ') ' + + '%(levelname)-8s %(message)s'), + filename=logfile, + filemode='a') + + # Log uncaught exceptions. + global original_excepthook + original_excepthook = sys.excepthook + sys.excepthook = my_excepthook + + def redirect(thing): + filename = os.path.join(logging_directory, program_name + '.' + thing) + try: + with open(filename, "r") as fhandle: + contents = fhandle.read() + except IOError, e: + if e.errno in (errno.ENOENT,): + fhandle = None + contents = "" + else: + logging.error("Reading %s: %s" % (filename, str(e))) + raise + + logging.error("std%s of last run: %s" % (thing, contents)) + + if fhandle is not None: + os.remove(filename) + + print "Redirecting std%s to %s" % (thing, filename) + return open(filename, "w", 0) + + sys.stderr = redirect('err') + sys.stdout = redirect('out') + diff --git a/src/update_feeds.py b/src/update_feeds.py index 9516594..89d208b 100644 --- a/src/update_feeds.py +++ b/src/update_feeds.py @@ -35,6 +35,9 @@ import traceback from jobmanager import JobManager import mainthread +import debugging +debugging.init(dot_directory=".feedingit", program_name="update_feeds") + CONFIGDIR="/home/user/.feedingit/" #DESKTOP_FILE = "/usr/share/applications/hildon-status-menu/feedingit_status.desktop" dbug = False @@ -46,14 +49,6 @@ del timeout from updatedbus import UpdateServerObject -debug_file = None -def debug(*args): - global debug_file - if not debug_file: - debug_file = open("/home/user/.feedingit/feedingit_update.log", "a") - - debug_file.write (*args) - class FeedUpdate(): def __init__(self): self.config = Config(self, CONFIGDIR+"config.ini") @@ -99,4 +94,4 @@ if app_lock != None: JobManager().quit() del app_lock else: - debug("Update in progress") + logger.error("Update in progress")