[chirp_devel] [PATCH 6/9] Add chirp.logger module (#2347)
Zach Welch
Tue Feb 24 23:26:50 PST 2015
# HG changeset patch
# User Zach Welch <zach at mandolincreekfarm.com>
Add chirp.logger module (#2347)
This patch adds the chirp.logger module, using it in chirpc and chirpw.
It adds a handful of optional command line arguments to control the new
logging features. In addition, CHIRP_DEBUG, CHIRP_LOG, and
CHIRP_LOG_LEVEL can be used to control the logging features from the
environment.
diff --git a/chirp/logger.py b/chirp/logger.py
new file mode 100644
index 0000000..753f75f
--- /dev/null
+++ b/chirp/logger.py
@@ -0,0 +1,127 @@
+# Copyright 2015 Zachary T Welch <zach at mandolincreekfarm.com>
+#
+# This program 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 program 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/>.
+
+
+r"""
+The chirp.logger module provides the core logging facilties for CHIRP.
+It sets up the console and (optionally) a log file. For early debugging,
+it checks the CHIRP_DEBUG, CHIRP_LOG, and CHIRP_LOG_LEVEL environment
+variables.
+"""
+
+import logging
+import os
+
+#: Map human-readable logging levels to their internal values.
+log_level_names = {"critical": logging.CRITICAL,
+ "error": logging.ERROR,
+ "warn": logging.WARNING,
+ "info": logging.INFO,
+ "debug": logging.DEBUG,
+ }
+
+
+class Logger(object):
+ def __init__(self):
+ # create root logger
+ self.logger = logging.getLogger()
+ self.logger.setLevel(logging.DEBUG)
+
+ self.LOG = logging.getLogger(__name__)
+
+ # Set CHIRP_DEBUG in environment for early console debugging.
+ # It can be a number or a name; otherwise, level is set to 'debug'
+ # in order to maintain backward compatibility.
+ CHIRP_DEBUG = os.getenv("CHIRP_DEBUG")
+ level = logging.WARNING
+ if CHIRP_DEBUG:
+ try:
+ level = int(CHIRP_DEBUG)
+ except:
+ try:
+ level = log_evel_names[CHIRP_DEBUG]
+ except:
+ level = logging.DEBUG
+
+ self.console = logging.StreamHandler()
+ self.console.setLevel(level)
+ format_str = '%(levelname)s: %(message)s'
+ self.console.setFormatter(logging.Formatter(format_str))
+ self.logger.addHandler(self.console)
+
+ # Set CHIRP_LOG in envoronment to the name of log file.
+ logname = os.getenv("CHIRP_LOG")
+ self.logfile = None
+ if logname is not None:
+ self.create_log_file(logname)
+ level = os.getenv("CHIRP_LOG_LEVEL")
+ if level is not None:
+ self.set_log_verbosity(level)
+ else:
+ self.set_log_level(logging.DEBUG)
+
+ self.LOG.debug("logging started")
+
+ def create_log_file(self, name):
+ if self.logfile is None:
+ self.logname = name
+ self.logfile = logging.FileHandler(name)
+ format_str = '[%(asctime)s] %(name)s - %(levelname)s: %(message)s'
+ self.logfile.setFormatter(logging.Formatter(format_str))
+ self.logger.addHandler(self.logfile)
+ else:
+ self.logger.error("already logging to " + self.logname)
+
+ def set_verbosity(self, level):
+ if level > logging.CRITICAL:
+ level = logging.CRITICAL
+ self.console.setLevel(level)
+ self.LOG.debug("verbosity=%d", level)
+
+ def set_log_level(self, level):
+ if level > logging.CRITICAL:
+ level = logging.CRITICAL
+ self.logfile.setLevel(level)
+ self.LOG.debug("log level=%d", level)
+
+ def set_log_level_by_name(self, level):
+ self.set_log_level(log_level_names[level])
+
+LOG = Logger()
+
+
+def add_arguments(parser):
+ parser.add_argument("-q", "--quiet", action="count", default=0,
+ help="Decrease verbosity")
+ parser.add_argument("-v", "--verbose", action="count", default=0,
+ help="Increase verbosity")
+ parser.add_argument("--log", dest="log_file", action="store", default=0,
+ help="Log messages to a file")
+ parser.add_argument("--log-level", action="store", default="debug",
+ help="Log file verbosity (critical, error, warn, " +
+ "info, debug). Defaults to 'debug'.")
+
+
+def handle_options(options):
+ if options.verbose or options.quiet:
+ LOG.set_verbosity(30 + 10 * (options.quiet - options.verbose))
+
+ if options.log_file:
+ LOG.create_log_file(options.log_file)
+ try:
+ level = int(options.log_level)
+ LOG.set_log_level(level)
+ except:
+ LOG.set_log_level_by_name(options.log_level)
diff --git a/chirpc b/chirpc
index c3ff224..dc55de3 100755
--- a/chirpc
+++ b/chirpc
@@ -19,10 +19,14 @@
import serial
import sys
import argparse
+import logging
+from chirp import logger
from chirp import *
from chirp import chirp_common, errors, idrp, directory, util
+LOG = logging.getLogger("chirpc")
+
def fail_unsupported():
print "Operation not supported by selected radio"
sys.exit(1)
@@ -152,8 +156,10 @@ if __name__ == "__main__":
action="store_true",
default=False,
help="Upload memory map to radio")
+ logger.add_arguments(parser)
parser.add_argument("args", metavar="arg", nargs='*',
help="Some commands require additional arguments")
+
if len(sys.argv) <= 1:
parser.print_help()
sys.exit(0)
@@ -161,6 +167,8 @@ if __name__ == "__main__":
options = parser.parse_args()
args = options.args
+ logger.handle_options(options)
+
if options.list_radios:
print "Supported Radios:\n\t", "\n\t".join(sorted(RADIOS.keys()))
sys.exit(0)
@@ -182,7 +190,7 @@ if __name__ == "__main__":
if options.mmap:
rclass = directory.get_radio_by_image(options.mmap).__class__
else:
- print "Must specify a radio model"
+ LOG.critical("You must specify a radio model.")
sys.exit(1)
else:
rclass = directory.get_radio(options.radio)
diff --git a/chirpw b/chirpw
index 4f53e0d..c1fd0ea 100755
--- a/chirpw
+++ b/chirpw
@@ -18,7 +18,7 @@
import os
from chirp import elib_intl
-from chirp import platform, version
+from chirp import platform, version, logger
from chirpui import config
# Hack to setup environment
@@ -126,8 +126,11 @@ parser.add_argument("files", metavar="file", nargs='*', help="File to open")
version.add_argument(parser)
parser.add_argument("--profile", action="store_true",
help="Enable profiling")
+logger.add_arguments(parser)
args = parser.parse_args()
+logger.handle_options(args)
+
a = mainapp.ChirpMain()
for i in args.files:
More information about the chirp_devel
mailing list