Write debug output to logfile (bug 1460)

Also, various clean-ups around the logging mechanism (remove
gpodder.ui.desktop, etc..) needed to make the logging work without
problems.
This commit is contained in:
Thomas Perl 2012-03-02 09:03:01 +01:00
parent 8f6189c88c
commit 9f58b8eda8
8 changed files with 148 additions and 77 deletions

8
README
View File

@ -156,6 +156,14 @@
export GPODDER_HOME=/media/usbdisk/gpodder-data/
[ LOGGING ]
By default, gPodder writes log files to $GPODDER_HOME/Logs/ and removes
them after a certain amount of times. To avoid this behavior, you can set
the environment variable GPODDER_WRITE_LOGS to "no", e.g:
export GPODDER_WRITE_LOGS=no
[ MORE INFORMATION ]

15
bin/gpo
View File

@ -88,14 +88,12 @@ except ImportError:
struct = None
# A poor man's argparse/getopt - but it works for our use case :)
for verbose_flag in ('-v', '--verbose'):
if verbose_flag in sys.argv:
FMT = '%(created)f [%(name)s] %(levelname)s: %(message)s'
logging.basicConfig(format=FMT, level=logging.DEBUG)
sys.argv.remove(verbose_flag)
verbose = False
for flag in ('-v', '--verbose'):
if flag in sys.argv:
sys.argv.remove(flag)
verbose = True
break
else:
logging.basicConfig()
gpodder_script = sys.argv[0]
if os.path.islink(gpodder_script):
@ -125,12 +123,15 @@ from gpodder import api
from gpodder import my
from gpodder import opml
from gpodder import util
from gpodder import log
from gpodder.config import config_value_to_string
have_ansi = sys.stdout.isatty() and not gpodder.win32
interactive_console = sys.stdin.isatty() and sys.stdout.isatty()
is_single_command = False
log.setup(verbose)
def incolor(color_id, s):
if have_ansi and cli.config.ui.cli.colors:
return '\033[9%dm%s\033[0m' % (color_id, s)

View File

@ -52,7 +52,7 @@ except ImportError:
from optparse import OptionParser
if __name__ == '__main__':
def main():
# Paths to important files
gpodder_script = sys.argv[0]
while os.path.islink(gpodder_script):
@ -113,39 +113,23 @@ if __name__ == '__main__':
action="store_true", dest="qml", default=False,
help=_("Start the QML interface of gPodder"))
parser.add_option("-w", "--web",
action="store_true", dest="web", default=False,
help=_("Start the web interface of gPodder"))
parser.add_option('-s', '--subscribe', dest='subscribe', metavar='URL',
help=_('Subscribe to the given URL'))
# On Mac OS X, support the "psn" parameter for compatibility (bug 939)
if sys.platform == 'darwin':
if gpodder.osx:
parser.add_option('-p', '--psn', dest='macpsn', metavar='PSN',
help=_('Mac OS X application process number'))
(options, args) = parser.parse_args(sys.argv)
if gpodder.ui.desktop:
gpodder.ui_folders.insert(0, os.path.join(ui_folder, 'gtk'))
if options.verbose:
FMT = '%(created)f [%(name)s] %(levelname)s: %(message)s'
logging.basicConfig(format=FMT, level=logging.DEBUG)
else:
logging.basicConfig()
options, args = parser.parse_args(sys.argv)
if options.qml or gpodder.ui.fremantle or gpodder.ui.harmattan:
from gpodder import qmlui
gpodder.ui.qml = True
gpodder.ui_folders.insert(0, os.path.join(ui_folder, 'qml'))
sys.exit(qmlui.main(args))
else:
gpodder.ui.gtk = True
if options.web:
from gpodder import webui
webui.main()
sys.exit(0)
from gpodder import log
log.setup(options.verbose)
if have_dbus:
# Try to find an already-running instance of gPodder
@ -155,32 +139,36 @@ if __name__ == '__main__':
# such an instance doesn't exist as it *will* create a new instance
if session_bus.name_has_owner(gpodder.dbus_bus_name):
try:
remote_object = session_bus.get_object(gpodder.dbus_bus_name, \
remote_object = session_bus.get_object(gpodder.dbus_bus_name,
gpodder.dbus_gui_object_path)
except dbus.exceptions.DBusException:
remote_object = None
else:
remote_object = None
else:
# No D-Bus available :/
remote_object = None
if remote_object is not None:
# An instance of GUI is already running
print >>sys.stderr, 'Existing instance running - activating via D-Bus.'
remote_object.show_gui_window(dbus_interface=gpodder.dbus_interface)
if options.subscribe:
remote_object.subscribe_to_url(options.subscribe)
else:
# gPodder is not yet running - create new instance
# An instance of GUI is already running
logger.info('Activating existing instance via D-Bus.')
remote_object.show_gui_window(
dbus_interface=gpodder.dbus_interface)
if options.subscribe:
remote_object.subscribe_to_url(options.subscribe)
return
except dbus.exceptions.DBusException, dbus_exception:
logger.info('Cannot connect to remote object.', exc_info=True)
if not gpodder.win32 and os.environ.get('DISPLAY', '') == '':
logger.error('Cannot start gPodder: $DISPLAY is not set.')
sys.exit(1)
if gpodder.ui.qml:
from gpodder import qmlui
gpodder.ui_folders.insert(0, os.path.join(ui_folder, 'qml'))
sys.exit(qmlui.main(args))
elif gpodder.ui.gtk:
from gpodder.gtkui import main
gpodder.ui.gtk = True
# check if we have an X11 connection (but not on Windows)
if platform.system() != 'Windows' and \
not os.environ.get('DISPLAY', None):
print >>sys.stderr, 'Cannot start gPodder: $DISPLAY is not set.'
sys.exit(1)
gpodder.ui_folders.insert(0, os.path.join(ui_folder, 'gtk'))
main.main(options)
else:
logger.error('No GUI selected.')
if __name__ == '__main__':
main()

View File

@ -76,7 +76,6 @@ user_agent = 'gPodder/%s (+%s)' % (__version__, __url__)
# Are we running in GUI, Maemo or console mode?
class UI(object):
def __init__(self):
self.desktop = False
self.fremantle = False
self.harmattan = False
self.gtk = False
@ -199,21 +198,14 @@ def detect_platform():
global ui
try:
ui.fremantle = ('Maemo 5' in open('/etc/issue').read())
if ui.fremantle:
print >>sys.stderr, 'Detected platform: Maemo 5 (Fremantle)'
etc_issue = open('/etc/issue').read()
except Exception, e:
ui.fremantle = False
etc_issue = ''
try:
ui.harmattan = ('MeeGo 1.2 Harmattan' in open('/etc/issue').read())
except Exception, e:
ui.harmattan = False
ui.fremantle = ('Maemo 5' in etc_issue)
ui.harmattan = ('MeeGo 1.2 Harmattan' in etc_issue)
ui.fremantle = ui.fremantle or ui.harmattan
ui.desktop = not ui.fremantle and not ui.harmattan
if ui.fremantle and 'GPODDER_HOME' not in os.environ:
if (ui.fremantle or ui.harmattan) and 'GPODDER_HOME' not in os.environ:
new_home = os.path.expanduser(os.path.join('~', 'MyDocs', 'gPodder'))
set_home(os.path.expanduser(new_home))

View File

@ -3356,14 +3356,10 @@ def main(options=None):
if options.subscribe:
util.idle_add(gp.subscribe_to_url, options.subscribe)
# mac OS X stuff :
# handle "subscribe to podcast" events from firefox
if platform.system() == 'Darwin':
# Mac OS X: Handle "subscribe to podcast" events from Firefox
if gpodder.osx:
from gpodder.gtkui import macosx
macosx.register_handlers(gp)
# end mac OS X stuff
gp.run()

86
src/gpodder/log.py Normal file
View File

@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
#
# gPodder - A media aggregator and podcast client
# Copyright (c) 2005-2012 Thomas Perl and the gPodder Team
#
# gPodder 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.
#
# gPodder 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 <http://www.gnu.org/licenses/>.
#
# gpodder.log - Logging setup
# Thomas Perl <thp@gpodder.org>; 2012-03-02
# Based on an initial draft by Neal Walfield
import gpodder
import glob
import logging
import os
import sys
import time
import traceback
logger = logging.getLogger(__name__)
def setup(verbose=True):
# Configure basic stdout logging
STDOUT_FMT = '%(created)f [%(name)s] %(levelname)s: %(message)s'
logging.basicConfig(format=STDOUT_FMT,
level=logging.DEBUG if verbose else logging.WARNING)
# Replace except hook with a custom one that logs it as an error
original_excepthook = sys.excepthook
def on_uncaught_exception(exctype, value, tb):
message = ''.join(traceback.format_exception(exctype, value, tb))
logger.error('Uncaught exception: %s', message)
original_excepthook(exctype, value, tb)
sys.excepthook = on_uncaught_exception
if os.environ.get('GPODDER_WRITE_LOGS', 'yes') != 'no':
# Configure file based logging
logging_basename = time.strftime('%Y-%m-%d.log')
logging_directory = os.path.join(gpodder.home, 'Logs')
if not os.path.isdir(logging_directory):
logger.warn('Cannot create output directory: %s', logging_directory)
try:
os.makedirs(logging_directory)
except:
return False
# Keep logs around for 5 days
LOG_KEEP_DAYS = 5
# Purge old logfiles if they are older than LOG_KEEP_DAYS days
old_logfiles = glob.glob(os.path.join(logging_directory, '*-*-*.log'))
for old_logfile in old_logfiles:
st = os.stat(old_logfile)
if time.time() - st.st_mtime > 60*60*24*LOG_KEEP_DAYS:
logger.info('Purging old logfile: %s', old_logfile)
try:
os.remove(old_logfile)
except:
logger.warn('Cannot purge logfile: %s', exc_info=True)
root = logging.getLogger()
logfile = os.path.join(logging_directory, logging_basename)
file_handler = logging.FileHandler(logfile, 'a', 'utf-8')
FILE_FMT = '%(asctime)s [%(name)s] %(levelname)s: %(message)s'
file_handler.setFormatter(logging.Formatter(FILE_FMT))
root.addHandler(file_handler)
logger.debug('==== gPodder starts up (ui=%s) ===', ', '.join(name
for name in ('cli', 'gtk', 'qml') if getattr(gpodder.ui, name, False)))
return True

View File

@ -85,7 +85,7 @@ if encoding is None:
lang = os.environ['LANG']
(language, encoding) = lang.rsplit('.', 1)
logger.info('Detected encoding: %s', encoding)
elif gpodder.ui.fremantle:
elif gpodder.ui.fremantle or gpodder.ui.harmattan:
encoding = 'utf-8'
elif gpodder.win32:
# To quote http://docs.python.org/howto/unicode.html:
@ -1462,7 +1462,7 @@ def detect_device_type():
Possible return values:
desktop, laptop, mobile, server, other
"""
if gpodder.ui.fremantle:
if gpodder.ui.fremantle or gpodder.ui.harmattan:
return 'mobile'
elif glob.glob('/proc/acpi/battery/*'):
# Linux: If we have a battery, assume Laptop

View File

@ -63,7 +63,7 @@ def get_real_download_url(url, preferred_fmt_id=None):
preferred_fmt_id = 18
# For Maemo 5, we force fmt_id 5 for performance reasons
if gpodder.ui.fremantle and not gpodder.ui.harmattan:
if gpodder.ui.fremantle:
preferred_fmt_id = 5
vid = get_youtube_id(url)
@ -100,7 +100,7 @@ def get_real_download_url(url, preferred_fmt_id=None):
formats_available = set(fmt_id for fmt_id, url in fmt_id_url_map)
fmt_id_url_map = dict(fmt_id_url_map)
if gpodder.ui.fremantle:
if gpodder.ui.fremantle or gpodder.ui.harmattan:
# This provides good quality video, seems to be always available
# and is playable fluently in Media Player
if preferred_fmt_id == 5: