From 541e879b8ec683d07a95a562a2cadb54b07faaed Mon Sep 17 00:00:00 2001 From: Naoto Yokoyama Date: Thu, 21 Mar 2013 02:05:01 +0900 Subject: [PATCH 1/5] Enabled per-module logging level settings --- modules/call.py | 8 +++----- modules/tasks.py | 7 +++---- settings.py.example | 13 +++++++++---- sevabot/frontend/main.py | 9 ++------- sevabot/utils.py | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/modules/call.py b/modules/call.py index 8623c46..341b5e5 100755 --- a/modules/call.py +++ b/modules/call.py @@ -1,5 +1,4 @@ #!/sevabot - # -*- coding: utf-8 -*- """ @@ -11,12 +10,11 @@ import Skype4Py from sevabot.bot.stateful import StatefulSkypeHandler -from sevabot.utils import ensure_unicode +from sevabot.utils import ensure_unicode, get_module_log_level -logger = logging.getLogger('Call') +logger = logging.getLogger('sevabot.modules.Call') -# Set to debug only during dev -logger.setLevel(logging.INFO) +logger.setLevel(get_module_log_level(__name__)) logger.debug('Call module level load import') diff --git a/modules/tasks.py b/modules/tasks.py index 6cebcf1..0be36d6 100644 --- a/modules/tasks.py +++ b/modules/tasks.py @@ -17,12 +17,11 @@ from collections import OrderedDict from sevabot.bot.stateful import StatefulSkypeHandler -from sevabot.utils import ensure_unicode, get_chat_id +from sevabot.utils import ensure_unicode, get_chat_id, get_module_log_level -logger = logging.getLogger("Tasks") +logger = logging.getLogger("sevabot.modules.Tasks") -# Set to debug only during dev -logger.setLevel(logging.INFO) +logger.setLevel(get_module_log_level(__name__)) logger.debug("Tasks module level load import") diff --git a/settings.py.example b/settings.py.example index 3650576..1ef531b 100644 --- a/settings.py.example +++ b/settings.py.example @@ -1,4 +1,3 @@ - #: Known shared secret key in order to send messages over HTTP interface SHARED_SECRET = "koskela" @@ -21,9 +20,15 @@ HTTP_HOST = "localhost" #: Which port we run our HTTP interface HTTP_PORT = 5000 -#: Set logging level (INFO or DEBUG) +#: Set global logging level (INFO or DEBUG) #: This setting overrides --verbose option -#: LOG_LEVEL = "INFO" +#LOG_LEVEL = "INFO" + +#: Set module logging levels +#: Settings for all modules +#MODULE_LOG_LEVELS = "INFO" +#: Per-module setting +#MODULE_LOG_LEVELS = {"tasks": "DEBUG"} #: Setup Python logging for Sevabot #: Absolute path or relative to the settings file location @@ -38,4 +43,4 @@ LOG_ROTATE_COUNT = 10 LOG_ROTATE_MAX_SIZE = 1024 * 1024 #: Log all HTTP requests for debugging purposes -DEBUG_HTTP = False \ No newline at end of file +DEBUG_HTTP = False diff --git a/sevabot/frontend/main.py b/sevabot/frontend/main.py index 7a60b5e..3607d96 100644 --- a/sevabot/frontend/main.py +++ b/sevabot/frontend/main.py @@ -6,7 +6,6 @@ """ from __future__ import absolute_import, division, print_function, unicode_literals -import imp import sys import logging import logging.handlers @@ -20,6 +19,7 @@ from sevabot.frontend import api from sevabot.frontend.daemon import create_daemon +from sevabot.utils import load_settings logger = logging.getLogger("sevabot") @@ -64,12 +64,7 @@ def main(settings="settings.py", verbose=False, daemon=False): """ # Expose settings global module - try: - settings = imp.load_source("settings", settings) - except Exception: - import traceback - traceback.print_exc() - sys.exit("Could not load settings file: %s" % settings) + settings = load_settings(settings) # Config logging diff --git a/sevabot/utils.py b/sevabot/utils.py index b3690c4..6fd449d 100644 --- a/sevabot/utils.py +++ b/sevabot/utils.py @@ -4,6 +4,7 @@ """ +import imp import hashlib import logging @@ -58,3 +59,34 @@ def get_chat_id(chat): m.update(chat.Name) return m.hexdigest() + +def load_settings(filename="settings.py"): + """ + Load the global settings file. + + :return: Settings module. + """ + + try: + settings = imp.load_source("settings", filename) + except Exception: + import traceback + traceback.print_exc() + sys.exit("Could not load settings file: %s" % settings) + + return settings + + +def get_module_log_level(module_name): + """ + Get log level of the module from the global settings. + """ + + settings = load_settings() + + levels = getattr(settings, "MODULE_LOG_LEVELS", "INFO") + + if type(levels) is str: + return getattr(logging, levels.upper(), "INFO") + + return getattr(logging, levels.get(module_name, "INFO").upper(), "INFO") From b8023d1604792f1f6f09b2ea8cf9043dcae1ac8c Mon Sep 17 00:00:00 2001 From: Naoto Yokoyama Date: Thu, 21 Mar 2013 02:27:36 +0900 Subject: [PATCH 2/5] Fixed missing import --- sevabot/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sevabot/utils.py b/sevabot/utils.py index 6fd449d..23515ae 100644 --- a/sevabot/utils.py +++ b/sevabot/utils.py @@ -5,6 +5,7 @@ """ import imp +import sys import hashlib import logging From 7b07df6e29585737d6fbd8b10bf505fb54b8769b Mon Sep 17 00:00:00 2001 From: Naoto Yokoyama Date: Thu, 21 Mar 2013 02:47:59 +0900 Subject: [PATCH 3/5] Fixed a bug in disposing output of Skype --- scripts/start-server.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/start-server.sh b/scripts/start-server.sh index 2628b26..4fb786f 100755 --- a/scripts/start-server.sh +++ b/scripts/start-server.sh @@ -65,7 +65,7 @@ start() { if [[ $? != '0' ]]; then sleep 3 # http://devforum.skype.com/t5/Audio-Video/bt-audio-service-open-connect-failed-Connection-refused-111/td-p/303 - skype > /dev/null 2&>1 & + skype > /dev/null 2>&1 & else echo "skype already running" fi From 449a4b28d72f0e9bd771452d5d11b8330496b0a0 Mon Sep 17 00:00:00 2001 From: Naoto Yokoyama Date: Thu, 21 Mar 2013 23:32:58 +0900 Subject: [PATCH 4/5] Outsourced logging configurations to logging.conf --- logging.conf.example | 38 ++++++++++++++++++++++++++++++++++++++ modules/call.py | 6 ++---- modules/tasks.py | 6 ++---- settings.py.example | 22 ---------------------- sevabot/frontend/main.py | 27 +++------------------------ sevabot/utils.py | 15 --------------- 6 files changed, 45 insertions(+), 69 deletions(-) create mode 100644 logging.conf.example diff --git a/logging.conf.example b/logging.conf.example new file mode 100644 index 0000000..2af8fc8 --- /dev/null +++ b/logging.conf.example @@ -0,0 +1,38 @@ +# http://docs.python.org/library/logging.config.html + +[loggers] +keys=root,sevabot +#: Customize loggers for modules as below +#keys=root,sevabot,tasks + +#: An example for customizing the logging level of tasks module +#[logger_tasks] +#level=DEBUG +#handlers=sevabot +#qualname=tasks + +[handlers] +keys=sevabot + +[formatters] +keys=sevabot + +[logger_root] +level=NOTSET +handlers= + +[logger_sevabot] +level=INFO +handlers=sevabot +qualname=sevabot + +[handler_sevabot] +class=handlers.RotatingFileHandler +formatter=sevabot +args=('logs/sevabot.log', 'a', 1024 * 1024, 10, 'utf-8') + # filename, mode, maxBytes, backupCount, encoding + +[formatter_sevabot] +# http://docs.python.org/library/logging.html +format=%(asctime)s - %(name)s - %(levelname)s - %(message)s +class=logging.Formatter diff --git a/modules/call.py b/modules/call.py index 341b5e5..1f6b5d1 100755 --- a/modules/call.py +++ b/modules/call.py @@ -10,11 +10,9 @@ import Skype4Py from sevabot.bot.stateful import StatefulSkypeHandler -from sevabot.utils import ensure_unicode, get_module_log_level +from sevabot.utils import ensure_unicode -logger = logging.getLogger('sevabot.modules.Call') - -logger.setLevel(get_module_log_level(__name__)) +logger = logging.getLogger(__name__) logger.debug('Call module level load import') diff --git a/modules/tasks.py b/modules/tasks.py index 0be36d6..49031b1 100644 --- a/modules/tasks.py +++ b/modules/tasks.py @@ -17,11 +17,9 @@ from collections import OrderedDict from sevabot.bot.stateful import StatefulSkypeHandler -from sevabot.utils import ensure_unicode, get_chat_id, get_module_log_level +from sevabot.utils import ensure_unicode, get_chat_id -logger = logging.getLogger("sevabot.modules.Tasks") - -logger.setLevel(get_module_log_level(__name__)) +logger = logging.getLogger(__name__) logger.debug("Tasks module level load import") diff --git a/settings.py.example b/settings.py.example index 1ef531b..5843018 100644 --- a/settings.py.example +++ b/settings.py.example @@ -20,27 +20,5 @@ HTTP_HOST = "localhost" #: Which port we run our HTTP interface HTTP_PORT = 5000 -#: Set global logging level (INFO or DEBUG) -#: This setting overrides --verbose option -#LOG_LEVEL = "INFO" - -#: Set module logging levels -#: Settings for all modules -#MODULE_LOG_LEVELS = "INFO" -#: Per-module setting -#MODULE_LOG_LEVELS = {"tasks": "DEBUG"} - -#: Setup Python logging for Sevabot -#: Absolute path or relative to the settings file location -LOG_FILE = "logs/sevabot.log" - -# http://docs.python.org/library/logging.html -LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" - -#: Log rotation options -LOG_ROTATE_COUNT = 10 - -LOG_ROTATE_MAX_SIZE = 1024 * 1024 - #: Log all HTTP requests for debugging purposes DEBUG_HTTP = False diff --git a/sevabot/frontend/main.py b/sevabot/frontend/main.py index 3607d96..fbedf13 100644 --- a/sevabot/frontend/main.py +++ b/sevabot/frontend/main.py @@ -8,7 +8,7 @@ import sys import logging -import logging.handlers +import logging.config import os from flask import Flask @@ -58,7 +58,7 @@ def get_settings(): verbose=("Verbose debug output", 'flag', 'v', None, None), daemon=("Start as a detached background process", 'flag', 'd', None, None), ) -def main(settings="settings.py", verbose=False, daemon=False): +def main(settings="settings.py", logconf="logging.conf", verbose=False, daemon=False): """ Application entry point. """ @@ -67,28 +67,7 @@ def main(settings="settings.py", verbose=False, daemon=False): settings = load_settings(settings) # Config logging - - level = getattr(logging, getattr(settings, "LOG_LEVEL", "INFO").upper(), "INFO") - - logging.basicConfig(level=level, stream=sys.stdout, format=settings.LOG_FORMAT) - - # Setup logging file - if getattr(settings, "LOG_FILE", None): - if not settings.LOG_FILE.startswith("/"): - log_path = settings.LOG_FILE - else: - log_path = os.path.join(os.path.dirname(settings.__file__), settings.LOG_FILE) - - formatter = logging.Formatter(settings.LOG_FORMAT) - - hdlr = logging.handlers.RotatingFileHandler(log_path, - encoding="utf-8", - maxBytes=settings.LOG_ROTATE_MAX_SIZE, - backupCount=settings.LOG_ROTATE_COUNT) - - hdlr.setFormatter(formatter) - - logger.addHandler(hdlr) + logging.config.fileConfig(logconf, disable_existing_loggers=False) logger.info("Starting sevabot") diff --git a/sevabot/utils.py b/sevabot/utils.py index 23515ae..13588ca 100644 --- a/sevabot/utils.py +++ b/sevabot/utils.py @@ -76,18 +76,3 @@ def load_settings(filename="settings.py"): sys.exit("Could not load settings file: %s" % settings) return settings - - -def get_module_log_level(module_name): - """ - Get log level of the module from the global settings. - """ - - settings = load_settings() - - levels = getattr(settings, "MODULE_LOG_LEVELS", "INFO") - - if type(levels) is str: - return getattr(logging, levels.upper(), "INFO") - - return getattr(logging, levels.get(module_name, "INFO").upper(), "INFO") From aae3380b7cdf9b5711533cc08b1c4074b1c4ba21 Mon Sep 17 00:00:00 2001 From: Naoto Yokoyama Date: Fri, 22 Mar 2013 15:00:00 +0900 Subject: [PATCH 5/5] Git-ignored logging.conf --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a23899f..c256e46 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ virtualenv.py tests/test-installation-environment settings.py Skype4Py +logging.conf .vagrant .idea