[cubicweb-ctl] backport --dbglevel option of pyramid to all instance commands

Closes #17219653

authorLaurent Peuch <cortex@worlddomination.be>
changeset56f7386bc6b9
branchdefault
phasepublic
hiddenno
parent revision#5add82b08a6d [cubicweb-ctl] backport --loglevel option of pyramid to all instance commands
child revision#a54037a68b14 [logging] send logs by default to stdout
files modified by this revision
cubicweb/cwctl.py
cubicweb/pyramid/pyramidctl.py
cubicweb/test/unittest_cwctl.py
doc/changes/3.27.rst
# HG changeset patch
# User Laurent Peuch <cortex@worlddomination.be>
# Date 1558455411 -7200
# Tue May 21 18:16:51 2019 +0200
# Node ID 56f7386bc6b9c88f3e48f97241526af29cef8c05
# Parent 5add82b08a6df4361cd453ebabd04f69dda86a3e
[cubicweb-ctl] backport --dbglevel option of pyramid to all instance commands

Closes #17219653

diff --git a/cubicweb/cwctl.py b/cubicweb/cwctl.py
@@ -40,14 +40,16 @@
1  from logilab.common.configuration import merge_options
2  from logilab.common.decorators import clear_cache
3 
4  from cubicweb import ConfigurationError, ExecutionError, BadCommandUsage
5  from cubicweb.cwconfig import CubicWebConfiguration as cwcfg, CONFIGURATIONS
6 +from cubicweb.server import set_debug
7  from cubicweb.toolsutils import Command, rm, create_dir, underline_title
8  from cubicweb.__pkginfo__ import version as cw_version
9 
10  LOG_LEVELS = ('debug', 'info', 'warning', 'error')
11 +DBG_FLAGS = ('RQL', 'SQL', 'REPO', 'HOOKS', 'OPS', 'SEC', 'MORE')
12 
13  # don't check duplicated commands, it occurs when reloading site_cubicweb
14  CWCTL = CommandLine('cubicweb-ctl', 'The CubicWeb swiss-knife.',
15                      version=cw_version, check_duplicated_command=False)
16 
@@ -134,10 +136,17 @@
17            'choices': LOG_LEVELS, 'short': 'l',
18            'help': 'allow to specify log level for debugging (choices: %s)'
19                    % (', '.join(LOG_LEVELS)),
20            }
21           ),
22 +        ('dbglevel',
23 +         {'type': 'multiple_choice', 'metavar': '<debug level>',
24 +          'default': None,
25 +          'choices': DBG_FLAGS,
26 +          'help': ('Set the server debugging flags; you may choose several '
27 +                   'values in %s; imply "debug" loglevel if loglevel is not set' % (DBG_FLAGS,)),
28 +          }),
29      )
30      actionverb = None
31 
32      def run(self, args):
33          """run the <command>_method on each argument (a list of instance
@@ -155,14 +164,21 @@
34          # by default loglevel is 'error' but we keep the default value to None
35          # because some subcommands (e.g: pyramid) can override the loglevel in
36          # certain situations if it's not explicitly set by the user and we want
37          # to detect that (the "None" case)
38          if self['loglevel'] is None:
39 -            init_cmdline_log_threshold(self.cwconfig, 'error')
40 +            # if no loglevel is set but dbglevel is here we want to set level to debug
41 +            if self['dbglevel']:
42 +                init_cmdline_log_threshold(self.cwconfig, 'debug')
43 +            else:
44 +                init_cmdline_log_threshold(self.cwconfig, 'error')
45          else:
46              init_cmdline_log_threshold(self.cwconfig, self['loglevel'])
47 
48 +        if self['dbglevel']:
49 +            set_debug('|'.join('DBG_' + x.upper() for x in self['dbglevel']))
50 +
51          try:
52              status = cmdmeth(appid) or 0
53          except (ExecutionError, ConfigurationError) as ex:
54              # we need to do extract this information here for pdb since it is
55              # now lost in python 3 once we exit the try/catch statement
diff --git a/cubicweb/pyramid/pyramidctl.py b/cubicweb/pyramid/pyramidctl.py
@@ -35,20 +35,18 @@
56  from logilab.common.configuration import merge_options
57 
58  from cubicweb.cwctl import CWCTL, InstanceCommand, init_cmdline_log_threshold
59  from cubicweb.pyramid import wsgi_application_from_cwconfig
60  from cubicweb.pyramid.config import get_random_secret_key
61 -from cubicweb.server import serverctl, set_debug
62 +from cubicweb.server import serverctl
63  from cubicweb.web.webctl import WebCreateHandler
64  from cubicweb.toolsutils import fill_templated_file
65 
66  import waitress
67 
68  MAXFD = 1024
69 
70 -DBG_FLAGS = ('RQL', 'SQL', 'REPO', 'HOOKS', 'OPS', 'SEC', 'MORE')
71 -
72 
73  def _generate_pyramid_ini_file(pyramid_ini_path):
74      """Write a 'pyramid.ini' file into apphome."""
75      template_fpath = os.path.join(os.path.dirname(__file__), 'pyramid.ini.tmpl')
76      context = {
@@ -105,17 +103,10 @@
77           {'action': 'store_true',
78            'help': 'Restart the server if any source file is changed'}),
79          ('reload-interval',
80           {'type': 'int', 'default': 1,
81            'help': 'Interval, in seconds, between file modifications checks'}),
82 -        ('dbglevel',
83 -         {'type': 'multiple_choice', 'metavar': '<dbg level>',
84 -          'default': None,
85 -          'choices': DBG_FLAGS,
86 -          'help': ('Set the server debugging flags; you may choose several '
87 -                   'values in %s; imply "debug" loglevel' % (DBG_FLAGS,)),
88 -          }),
89          ('profile',
90           {'action': 'store_true',
91            'default': False,
92            'help': 'Enable profiling'}),
93          ('profile-output',
@@ -258,16 +249,13 @@
94              extra_files.extend(self.i18nfiles(cwconfig))
95              self.install_reloader(
96                  self['reload-interval'], extra_files,
97                  filelist_path=filelist_path)
98 
99 -        if self['dbglevel']:
100 -            set_debug('|'.join('DBG_' + x.upper() for x in self['dbglevel']))
101 -
102 -        # if no loglevel is specified and --debug or --dbglevel are here, set log level at debug
103 -        if self['loglevel'] is None and (self['debug'] or self['dbglevel']):
104 -            init_cmdline_log_threshold(cwconfig, 'debug')
105 +        # if no loglevel is specified and --debug is here, set log level at debug
106 +        if self['loglevel'] is None and self['debug']:
107 +            init_cmdline_log_threshold(self.cwconfig, 'debug')
108 
109          app = wsgi_application_from_cwconfig(
110              cwconfig, profile=self['profile'],
111              profile_output=self['profile-output'],
112              profile_dump_every=self['profile-dump-every']
diff --git a/cubicweb/test/unittest_cwctl.py b/cubicweb/test/unittest_cwctl.py
@@ -22,11 +22,11 @@
113  import unittest
114  from unittest.mock import patch, MagicMock
115 
116  from logilab.common.clcommands import CommandLine
117 
118 -from cubicweb import cwctl
119 +from cubicweb import cwctl, server
120  from cubicweb.cwctl import ListCommand, InstanceCommand
121  from cubicweb.devtools.testlib import CubicWebTC
122  from cubicweb.server.migractions import ServerMigrationHelper
123  from cubicweb.cwconfig import CubicWebConfiguration as cwcfg
124  from cubicweb.__pkginfo__ import version as cw_version
@@ -110,13 +110,13 @@
125 
126          self.fake_config = MagicMock()
127          self.fake_config.global_set_option = MagicMock()
128 
129          # pretend that this instance exists
130 -        patcher = patch.object(cwcfg, 'config_for', return_value=self.fake_config)
131 -        patcher.start()
132 -        self.addCleanup(patcher.stop)
133 +        config_patcher = patch.object(cwcfg, 'config_for', return_value=self.fake_config)
134 +        config_patcher.start()
135 +        self.addCleanup(config_patcher.stop)
136 
137      @patch.object(_TestCommand, 'test_instance', return_value=0)
138      def test_getting_called(self, test_instance):
139          with self.assertRaises(SystemExit) as cm:
140              self.CWCTL.run(["test", "some_instance"])
@@ -179,8 +179,22 @@
141              self.assertEqual(cm.exception.code, 0)
142 
143              self.fake_config.global_set_option.assert_called_with('log-threshold',
144                                                                    log_level.upper())
145 
146 +    @patch.object(server, "DEBUG", 0)
147 +    def test_set_dblevel(self):
148 +        DBG_FLAGS = ('RQL', 'SQL', 'REPO', 'HOOKS', 'OPS', 'SEC', 'MORE')
149 +
150 +        total_value = 0
151 +
152 +        for dbg_flag in DBG_FLAGS:
153 +            with self.assertRaises(SystemExit) as cm:
154 +                self.CWCTL.run(["test", "some_instance", "--dbglevel", dbg_flag])
155 +            self.assertEqual(cm.exception.code, 0)
156 +
157 +            total_value += getattr(server, "DBG_%s" % dbg_flag)
158 +            self.assertEqual(total_value, server.DEBUG)
159 +
160 
161  if __name__ == '__main__':
162      unittest.main()
diff --git a/doc/changes/3.27.rst b/doc/changes/3.27.rst
@@ -18,12 +18,12 @@
163    with the needed secrets.
164 
165  * add a --pdb flag to all cubicweb-ctl command to launch (i)pdb if an exception
166    occurs during a command execution.
167 
168 -* the --loglevel flag is available for all cubicweb-ctl instance commands (and
169 -  not only the ``pyramid`` one)
170 +* the --loglevel and --dbglevel flags are available for all cubicweb-ctl
171 +  instance commands (and not only the ``pyramid`` one)
172 
173  Backwards incompatible changes
174  ------------------------------
175 
176  * Standardization on the way to launch a cubicweb instance, from now on the