--- a/cubicweb/cwctl.py Thu Jul 25 03:33:01 2019 +0200
+++ b/cubicweb/cwctl.py Tue May 21 18:08:17 2019 +0200
@@ -45,6 +45,8 @@
from cubicweb.toolsutils import Command, rm, create_dir, underline_title
from cubicweb.__pkginfo__ import version as cw_version
+LOG_LEVELS = ('debug', 'info', 'warning', 'error')
+
# don't check duplicated commands, it occurs when reloading site_cubicweb
CWCTL = CommandLine('cubicweb-ctl', 'The CubicWeb swiss-knife.',
version=cw_version, check_duplicated_command=False)
@@ -127,6 +129,13 @@
'help': 'launch pdb on exception',
}
),
+ ("loglevel",
+ {'type': 'choice', 'default': None, 'metavar': '<log level>',
+ 'choices': LOG_LEVELS, 'short': 'l',
+ 'help': 'allow to specify log level for debugging (choices: %s)'
+ % (', '.join(LOG_LEVELS)),
+ }
+ ),
)
actionverb = None
@@ -139,6 +148,19 @@
traceback_ = None
+ # debugmode=True is to force to have a StreamHandler used instead of
+ # writting the logs into a file in /tmp
+ self.cwconfig = cwcfg.config_for(appid, debugmode=True)
+
+ # by default loglevel is 'error' but we keep the default value to None
+ # because some subcommands (e.g: pyramid) can override the loglevel in
+ # certain situations if it's not explicitly set by the user and we want
+ # to detect that (the "None" case)
+ if self['loglevel'] is None:
+ init_cmdline_log_threshold(self.cwconfig, 'error')
+ else:
+ init_cmdline_log_threshold(self.cwconfig, self['loglevel'])
+
try:
status = cmdmeth(appid) or 0
except (ExecutionError, ConfigurationError) as ex:
@@ -433,7 +455,6 @@
name = 'delete'
arguments = '<instance>'
min_args = max_args = 1
- options = ()
def run(self, args):
"""run the command with its specific arguments"""
@@ -608,7 +629,7 @@
name = 'versions'
def versions_instance(self, appid):
- config = cwcfg.config_for(appid)
+ config = self.cwconfig
# should not raise error if db versions don't match fs versions
config.repairing = True
# no need to load all appobjects and schema
@@ -640,7 +661,7 @@
arguments = '<instance> [batch command file(s)] [-- <script arguments>]'
min_args = 1
max_args = None
- options = (
+ options = merge_options((
('system-only',
{'short': 'S', 'action': 'store_true',
'help': 'only connect to the system source when the instance is '
@@ -664,7 +685,7 @@
'group': 'local'
}),
- )
+ ) + InstanceCommand.options)
def _get_mih(self, appid):
""" returns migration context handler & shutdown function """
@@ -708,10 +729,9 @@
"""
name = 'i18ninstance'
- @staticmethod
- def i18ninstance_instance(appid):
+ def i18ninstance_instance(self, appid):
"""recompile instance's messages catalogs"""
- config = cwcfg.config_for(appid)
+ config = self.cwconfig
config.quick_start = True # notify this is not a regular start
repo = config.repository()
if config._cubes is None:
@@ -765,7 +785,7 @@
def configure_instance(self, appid):
if self.config.param is not None:
- appcfg = cwcfg.config_for(appid)
+ appcfg = self.cwconfig
for key, value in self.config.param.items():
try:
appcfg.global_set_option(key, value)
--- a/cubicweb/pyramid/pyramidctl.py Thu Jul 25 03:33:01 2019 +0200
+++ b/cubicweb/pyramid/pyramidctl.py Tue May 21 18:08:17 2019 +0200
@@ -32,7 +32,8 @@
import threading
import subprocess
-from cubicweb.cwconfig import CubicWebConfiguration as cwcfg
+from logilab.common.configuration import merge_options
+
from cubicweb.cwctl import CWCTL, InstanceCommand, init_cmdline_log_threshold
from cubicweb.pyramid import wsgi_application_from_cwconfig
from cubicweb.pyramid.config import get_random_secret_key
@@ -45,7 +46,6 @@
MAXFD = 1024
DBG_FLAGS = ('RQL', 'SQL', 'REPO', 'HOOKS', 'OPS', 'SEC', 'MORE')
-LOG_LEVELS = ('debug', 'info', 'warning', 'error')
def _generate_pyramid_ini_file(pyramid_ini_path):
@@ -93,7 +93,7 @@
name = 'pyramid'
actionverb = 'started'
- options = (
+ options = merge_options((
('debug-mode',
{'action': 'store_true',
'help': 'Activate the repository debug mode ('
@@ -107,12 +107,6 @@
('reload-interval',
{'type': 'int', 'default': 1,
'help': 'Interval, in seconds, between file modifications checks'}),
- ('loglevel',
- {'short': 'l', 'type': 'choice', 'metavar': '<log level>',
- 'default': None, 'choices': LOG_LEVELS,
- 'help': 'debug if -D is set, error otherwise; '
- 'one of %s' % (LOG_LEVELS,),
- }),
('dbglevel',
{'type': 'multiple_choice', 'metavar': '<dbg level>',
'default': None,
@@ -140,7 +134,7 @@
'metavar': 'key1:value1,key2:value2',
'default': {},
'help': 'override <key> configuration file option with <value>.'}),
- )
+ ) + InstanceCommand.options)
_reloader_environ_key = 'CW_RELOADER_SHOULD_RUN'
@@ -245,9 +239,7 @@
autoreload = self['reload'] or self['debug']
- # debugmode=True is to force to have a StreamHandler used instead of
- # writting the logs into a file in /tmp
- cwconfig = cwcfg.config_for(appid, debugmode=True)
+ cwconfig = self.cwconfig
filelist_path = os.path.join(cwconfig.apphome,
'.pyramid-reload-files.list')
@@ -269,9 +261,11 @@
filelist_path=filelist_path)
if self['dbglevel']:
- self['loglevel'] = 'debug'
set_debug('|'.join('DBG_' + x.upper() for x in self['dbglevel']))
- init_cmdline_log_threshold(cwconfig, self['loglevel'])
+
+ # if no loglevel is specified and --debug or --dbglevel are here, set log level at debug
+ if self['loglevel'] is None and (self['debug'] or self['dbglevel']):
+ init_cmdline_log_threshold(cwconfig, 'debug')
app = wsgi_application_from_cwconfig(
cwconfig, profile=self['profile'],
--- a/cubicweb/test/unittest_cwctl.py Thu Jul 25 03:33:01 2019 +0200
+++ b/cubicweb/test/unittest_cwctl.py Tue May 21 18:08:17 2019 +0200
@@ -108,8 +108,11 @@
self.CWCTL.register(_TestCommand)
self.CWCTL.register(_TestFailCommand)
+ self.fake_config = MagicMock()
+ self.fake_config.global_set_option = MagicMock()
+
# pretend that this instance exists
- patcher = patch.object(cwcfg, 'config_for', return_value=object())
+ patcher = patch.object(cwcfg, 'config_for', return_value=self.fake_config)
patcher.start()
self.addCleanup(patcher.stop)
@@ -167,6 +170,17 @@
test_fail_instance.assert_called_once()
+ def test_set_loglevel(self):
+ LOG_LEVELS = ('debug', 'info', 'warning', 'error')
+
+ for log_level in LOG_LEVELS:
+ with self.assertRaises(SystemExit) as cm:
+ self.CWCTL.run(["test", "some_instance", "--loglevel", log_level])
+ self.assertEqual(cm.exception.code, 0)
+
+ self.fake_config.global_set_option.assert_called_with('log-threshold',
+ log_level.upper())
+
if __name__ == '__main__':
unittest.main()
--- a/doc/changes/3.27.rst Thu Jul 25 03:33:01 2019 +0200
+++ b/doc/changes/3.27.rst Tue May 21 18:08:17 2019 +0200
@@ -20,6 +20,9 @@
* add a --pdb flag to all cubicweb-ctl command to launch (i)pdb if an exception
occurs during a command execution.
+* the --loglevel flag is available for all cubicweb-ctl instance commands (and
+ not only the ``pyramid`` one)
+
Backwards incompatible changes
------------------------------