Browse Source

[2380] added -d option to control logging level

JINMEI Tatuya 12 years ago
parent
commit
790d0b5527

+ 47 - 2
src/bin/loadzone/loadzone.py.in

@@ -23,7 +23,13 @@ from isc.datasrc import *
 import isc.log
 import isc.log
 from isc.log_messages.loadzone_messages import *
 from isc.log_messages.loadzone_messages import *
 
 
-isc.log.init("b10-loadzone", buffer=False)
+# These are needed for logger settings
+import bind10_config
+import json
+from isc.config import module_spec_from_file
+from isc.config.ccsession import path_search
+
+isc.log.init("b10-loadzone")
 logger = isc.log.Logger("loadzone")
 logger = isc.log.Logger("loadzone")
 
 
 class BadArgument(Exception):
 class BadArgument(Exception):
@@ -47,6 +53,10 @@ def set_cmd_options(parser):
 the zone in.  Example:
 the zone in.  Example:
 '{"database_file": "/path/to/dbfile/db.sqlite3"}'""",
 '{"database_file": "/path/to/dbfile/db.sqlite3"}'""",
                       metavar='CONFIG')
                       metavar='CONFIG')
+    parser.add_option("-d", "--debug", dest="debug_level",
+                      action="store", default=None,
+                      help="enable debug logs with the specified level",
+                      metavar='DEBUG_LEVEL')
     parser.add_option("-t", "--datasrc-type", dest="datasrc_type",
     parser.add_option("-t", "--datasrc-type", dest="datasrc_type",
                       action="store", default='sqlite3',
                       action="store", default='sqlite3',
                       help="type of data source (e.g., 'sqlite3')")
                       help="type of data source (e.g., 'sqlite3')")
@@ -65,6 +75,19 @@ class LoadZoneRunner:
         self.__load_iteration_limit = 100000 # arbitrary choice for now
         self.__load_iteration_limit = 100000 # arbitrary choice for now
         self.__loaded_rrs = 0
         self.__loaded_rrs = 0
 
 
+        # system-wide log configuration.  We need to configure logging this
+        # way so that the logging policy applies to underlying libraries, too.
+        self.__log_spec = json.dumps(isc.config.module_spec_from_file(
+                path_search('logging.spec', bind10_config.PLUGIN_PATHS)).
+                                     get_full_spec())
+        # "severity" and "debuglevel" are the tunable parameters, which will
+        # be set in _config_log().
+        self.__log_conf_base = {"loggers":
+                                    [{"name": "*",
+                                      "output_options":
+                                          [{"output": "stdout",
+                                            "destination": "console"}]}]}
+
         # These are essentially private, and defined as "protected" for the
         # These are essentially private, and defined as "protected" for the
         # convenience of tests inspecting them
         # convenience of tests inspecting them
         self._zone_class = None
         self._zone_class = None
@@ -72,6 +95,21 @@ class LoadZoneRunner:
         self._zone_file = None
         self._zone_file = None
         self._datasrc_config = None
         self._datasrc_config = None
         self._datasrc_type = None
         self._datasrc_type = None
+        self._log_severity = 'INFO'
+        self._log_debuglevel = 0
+
+        self._config_log()
+
+    def _config_log(self):
+        '''Configure logging policy.
+
+        This is essentially private, but defined as "protected" for tests.
+
+        '''
+        self.__log_conf_base['loggers'][0]['severity'] = self._log_severity
+        self.__log_conf_base['loggers'][0]['debuglevel'] = self._log_debuglevel
+        isc.log.log_config_update(json.dumps(self.__log_conf_base),
+                                  self.__log_spec)
 
 
     def _parse_args(self):
     def _parse_args(self):
         '''Parse command line options and other arguments.
         '''Parse command line options and other arguments.
@@ -80,11 +118,18 @@ class LoadZoneRunner:
 
 
         '''
         '''
 
 
-        usage_txt = 'usage: %prog [options] zonename zonefile'
+        usage_txt = \
+            'usage: %prog [options] -c datasrc_config zonename zonefile'
         parser = OptionParser(usage=usage_txt)
         parser = OptionParser(usage=usage_txt)
         set_cmd_options(parser)
         set_cmd_options(parser)
         (options, args) = parser.parse_args(args=self.__command_args)
         (options, args) = parser.parse_args(args=self.__command_args)
 
 
+        # Configure logging policy as early as possible
+        if options.debug_level is not None:
+            self._log_severity = 'DEBUG'
+            self._log_debuglevel = int(options.debug_level)
+        self._config_log()
+
         if options.conf is None:
         if options.conf is None:
             raise BadArgument('data source config option cannot be omitted')
             raise BadArgument('data source config option cannot be omitted')
         self._datasrc_config = options.conf
         self._datasrc_config = options.conf

+ 1 - 1
src/bin/loadzone/loadzone_messages.mes

@@ -24,7 +24,7 @@
 
 
 % LOADZONE_CANCEL_CREATE_ZONE Creation of new zone %1/%2 was canceled
 % LOADZONE_CANCEL_CREATE_ZONE Creation of new zone %1/%2 was canceled
 
 
-% LOADZONE_UNEXPECTED_FAILURE Unexpected exception: ex
+% LOADZONE_UNEXPECTED_FAILURE Unexpected exception: %1
 
 
 % LOADZONE_LOADING Loaded %1 RRs into %2/%3, continued
 % LOADZONE_LOADING Loaded %1 RRs into %2/%3, continued
 
 

+ 17 - 2
src/bin/loadzone/tests/loadzone_test.py

@@ -60,11 +60,15 @@ class TestLoadZoneRunner(unittest.TestCase):
 
 
     def test_init(self):
     def test_init(self):
         '''
         '''
-        Test the old socket file is removed (if any) and a new socket
-        is created when the ddns server is created.
+        Checks initial class attributes
         '''
         '''
         self.assertIsNone(self.__runner._zone_class)
         self.assertIsNone(self.__runner._zone_class)
         self.assertIsNone(self.__runner._zone_name)
         self.assertIsNone(self.__runner._zone_name)
+        self.assertIsNone(self.__runner._zone_file)
+        self.assertIsNone(self.__runner._datasrc_config)
+        self.assertIsNone(self.__runner._datasrc_type)
+        self.assertEqual('INFO', self.__runner._log_severity)
+        self.assertEqual(0, self.__runner._log_debuglevel)
 
 
     def test_parse_args(self):
     def test_parse_args(self):
         self.__runner._parse_args()
         self.__runner._parse_args()
@@ -73,6 +77,14 @@ class TestLoadZoneRunner(unittest.TestCase):
         self.assertEqual(DATASRC_CONFIG, self.__runner._datasrc_config)
         self.assertEqual(DATASRC_CONFIG, self.__runner._datasrc_config)
         self.assertEqual('sqlite3', self.__runner._datasrc_type) # default
         self.assertEqual('sqlite3', self.__runner._datasrc_type) # default
         self.assertEqual(RRClass.IN(), self.__runner._zone_class) # default
         self.assertEqual(RRClass.IN(), self.__runner._zone_class) # default
+        self.assertEqual('INFO', self.__runner._log_severity) # default
+        self.assertEqual(0, self.__runner._log_debuglevel)
+
+    def test_set_loglevel(self):
+        runner = LoadZoneRunner(['-d', '1'] + self.__args)
+        runner._parse_args()
+        self.assertEqual('DEBUG', runner._log_severity)
+        self.assertEqual(1, runner._log_debuglevel)
 
 
     def test_parse_bad_args(self):
     def test_parse_bad_args(self):
         # -c cannot be omitted (right now)
         # -c cannot be omitted (right now)
@@ -205,4 +217,7 @@ class TestLoadZoneRunner(unittest.TestCase):
 
 
 if __name__== "__main__":
 if __name__== "__main__":
     isc.log.resetUnitTestRootLogger()
     isc.log.resetUnitTestRootLogger()
+    # Disable the internal logging setup so the test output won't be too
+    # verbose by default.
+    LoadZoneRunner._config_log = lambda x: None
     unittest.main()
     unittest.main()