Skip to content

Commit 28b5642

Browse files
committed
feat: add support for using dictConfig to configure logging.
Basic logging config (one level and one output file non-rotating) was always possible from config.ini. However the LOGGING_CONFIG setting could be used to load an ini fileConfig style file to set various channels (e.g. roundup.hyperdb) (also called qualname or tags) with their own logging level, destination (rotating file, socket, /dev/null) and log format. This is now a deprecated method in newer logging modules. The dictConfig format is preferred and allows disabiling other loggers as well as invoking new loggers in local code. This commit adds support for it reading the dict from a .json file. It also implements a comment convention so you can document the dictConfig. configuration.py: new code test_config.py: test added for the new code. admin_guide.txt, upgrading.txt CHANGES.txt: docs added upgrading references the section in admin_guid.
1 parent 55c4d2f commit 28b5642

File tree

5 files changed

+570
-12
lines changed

5 files changed

+570
-12
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ Features:
3232
- add support for authorized changes. User can be prompted to enter
3333
their password to authorize a change. If the user's password is
3434
properly entered, the change is committed. (John Rouillard)
35+
- add support for dictConfig style logging configuration. Ini/File
36+
style configs will still be supported. (John Rouillard)
3537

3638
2025-07-13 2.5.0
3739

doc/admin_guide.txt

Lines changed: 264 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,31 +47,284 @@ There's two "installations" that we talk about when using Roundup:
4747
in the tracker's config.ini.
4848

4949

50-
Configuring Roundup's Logging of Messages For Sysadmins
51-
=======================================================
50+
Configuring Roundup Message Logging
51+
===================================
5252

53-
You may configure where Roundup logs messages in your tracker's config.ini
54-
file. Roundup will use the standard Python (2.3+) logging implementation.
53+
You can control how Roundup logs messages using your tracker's
54+
config.ini file. Roundup uses the standard Python (2.3+) logging
55+
implementation. The config file and ``roundup-server`` provide very
56+
basic control over logging.
5557

56-
Configuration for standard "logging" module:
57-
- tracker configuration file specifies the location of a logging
58-
configration file as ``logging`` -> ``config``
59-
- ``roundup-server`` specifies the location of a logging configuration
60-
file on the command line
6158
Configuration for "BasicLogging" implementation:
6259
- tracker configuration file specifies the location of a log file
6360
``logging`` -> ``filename``
6461
- tracker configuration file specifies the level to log to as
6562
``logging`` -> ``level``
63+
- tracker configuration file lets you disable other loggers
64+
(e.g. when running under a wsgi framework) with
65+
``logging`` -> ``disable_loggers``.
6666
- ``roundup-server`` specifies the location of a log file on the command
6767
line
68-
- ``roundup-server`` specifies the level to log to on the command line
68+
- ``roundup-server`` enable using the standard python logger with
69+
the tag/channel ``roundup.http`` on the command line
70+
71+
By supplying a standard log config file in ini or json (dictionary)
72+
format, you get more control over the logs. You can set different
73+
levels for logs (e.g. roundup.hyperdb can be set to WARNING while
74+
other Roundup log channels are set to INFO and roundup.mailgw logs at
75+
DEBUG level). You can also send the logs for roundup.mailgw to syslog,
76+
and other roundup logs go to an automatically rotating log file, or
77+
are submitted to your log aggregator over https.
6978

70-
(``roundup-mailgw`` always logs to the tracker's log file)
79+
Configuration for standard "logging" module:
80+
- tracker configuration file specifies the location of a logging
81+
configuration file as ``logging`` -> ``config``.
7182

7283
In both cases, if no logfile is specified then logging will simply be sent
7384
to sys.stderr with only logging of ERROR messages.
7485

86+
Standard Logging Setup
87+
----------------------
88+
89+
You can specify your log configs in one of two formats:
90+
91+
* `fileConfig format
92+
<https://docs.python.org/3/library/logging.config.html#logging.config.fileConfig>`_
93+
in ini style
94+
* `dictConfig format
95+
<https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig>`_
96+
using json with comment support
97+
98+
The dictConfig allows more control over configuration including
99+
loading your own log handlers and disabling existing handlers. If you
100+
use the fileConfig format, the ``logging`` -> ``disable_loggers`` flag
101+
in the tracker's config is used to enable/disable pre-existing loggers
102+
as there is no way to do this in the logging config file.
103+
104+
.. _`dictLogConfig`:
105+
106+
dictConfig Based Logging Config
107+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
108+
109+
dictConfigs are specified in JSON format with support for comments.
110+
The file name in the tracker's config for the ``logging`` -> ``config``
111+
setting must end with ``.json`` to choose the correct processing.
112+
113+
Comments have to be in one of two forms:
114+
115+
1. A ``#`` with preceding white space is considered a comment and is
116+
stripped from the file before being passed to the json parser. This
117+
is a "block comment".
118+
119+
2. A ``#`` preceded by at least three
120+
white space characters is stripped from the end of the line before
121+
begin passed to the json parser. This is an "inline comment".
122+
123+
Other than this the file is a standard json file that matches the
124+
`Configuration dictionary schema
125+
<https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema>`_
126+
defined in the Python documentation.
127+
128+
129+
Example dictConfig Logging Config
130+
.................................
131+
132+
Note that this file is not actually JSON format as it include comments.
133+
So you can not use tools that expect JSON (linters, formatters) to
134+
work with it.
135+
136+
The config below works with the `Waitress wsgi server
137+
<https://github.com/Pylons/waitress>`_ configured to use the
138+
roundup.wsgi channel. It also controls the `TransLogger middleware
139+
<https://github.com/pasteorg/paste>`_ configured to use
140+
roundup.wsgi.translogger, to produce httpd style combined logs. The
141+
log file is specified relative to the current working directory not
142+
the tracker home. The tracker home is the subdirectory demo under the
143+
current working directory. The commented config is::
144+
145+
{
146+
"version": 1, # only supported version
147+
"disable_existing_loggers": false, # keep the wsgi loggers
148+
149+
"formatters": {
150+
# standard format for Roundup messages
151+
"standard": {
152+
"format": "%(asctime)s %(levelname)s %(name)s:%(module)s %(msg)s"
153+
},
154+
# used for waitress wsgi server to produce httpd style logs
155+
"http": {
156+
"format": "%(message)s"
157+
}
158+
},
159+
"handlers": {
160+
# create an access.log style http log file
161+
"access": {
162+
"level": "INFO",
163+
"formatter": "http",
164+
"class": "logging.FileHandler",
165+
"filename": "demo/access.log"
166+
},
167+
# logging for roundup.* loggers
168+
"roundup": {
169+
"level": "DEBUG",
170+
"formatter": "standard",
171+
"class": "logging.FileHandler",
172+
"filename": "demo/roundup.log"
173+
},
174+
# print to stdout - fall through for other logging
175+
"default": {
176+
"level": "DEBUG",
177+
"formatter": "standard",
178+
"class": "logging.StreamHandler",
179+
"stream": "ext://sys.stdout"
180+
}
181+
},
182+
"loggers": {
183+
"": {
184+
"handlers": [
185+
"default"
186+
],
187+
"level": "DEBUG",
188+
"propagate": false
189+
},
190+
# used by roundup.* loggers
191+
"roundup": {
192+
"handlers": [
193+
"roundup"
194+
],
195+
"level": "DEBUG",
196+
"propagate": false # note pytest testing with caplog requires
197+
# this to be true
198+
},
199+
"roundup.hyperdb": {
200+
"handlers": [
201+
"roundup"
202+
],
203+
"level": "INFO", # can be a little noisy use INFO for production
204+
"propagate": false
205+
},
206+
"roundup.wsgi": { # using the waitress framework
207+
"handlers": [
208+
"roundup"
209+
],
210+
"level": "DEBUG",
211+
"propagate": false
212+
},
213+
"roundup.wsgi.translogger": { # httpd style logging
214+
"handlers": [
215+
"access"
216+
],
217+
"level": "DEBUG",
218+
"propagate": false
219+
},
220+
"root": {
221+
"handlers": [
222+
"default"
223+
],
224+
"level": "DEBUG",
225+
"propagate": false
226+
}
227+
}
228+
}
229+
230+
fileConfig Based Logging Config
231+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
232+
233+
The file config is an older and more limited method of configuring
234+
logging. It is described by the `Configuration file format
235+
<https://docs.python.org/3/library/logging.config.html#configuration-file-format>`_
236+
in the Python documentation. The file name in the tracker's config for
237+
the ``logging`` -> ``config`` setting must end with ``.ini`` to choose
238+
the correct processing.
239+
240+
Example fileConfig LoggingConfig
241+
................................
242+
243+
This is an example .ini used with roundup-server configured to use
244+
``roundup.http`` channel. It also includes some custom logging
245+
qualnames/tags/channels for logging schema/permission detector and
246+
extension output::
247+
248+
[loggers]
249+
#other keys: roundup.hyperdb.backend
250+
keys=root,roundup,roundup.http,roundup.hyperdb,actions,schema,extension,detector
251+
252+
[logger_root]
253+
#also for root where channlel is not set (NOTSET) aka all
254+
level=DEBUG
255+
handlers=rotate
256+
257+
[logger_roundup]
258+
# logger for all roundup.* not otherwise configured
259+
level=DEBUG
260+
handlers=rotate
261+
qualname=roundup
262+
propagate=0
263+
264+
[logger_roundup.http]
265+
level=INFO
266+
handlers=rotate_weblog
267+
qualname=roundup.http
268+
propagate=0
269+
270+
[logger_roundup.hyperdb]
271+
level=WARNING
272+
handlers=rotate
273+
qualname=roundup.hyperdb
274+
propagate=0
275+
276+
[logger_actions]
277+
level=INFO
278+
handlers=rotate
279+
qualname=actions
280+
propagate=0
281+
282+
[logger_detector]
283+
level=INFO
284+
handlers=rotate
285+
qualname=detector
286+
propagate=0
287+
288+
[logger_schema]
289+
level=DEBUG
290+
handlers=rotate
291+
qualname=schema
292+
propagate=0
293+
294+
[logger_extension]
295+
level=INFO
296+
handlers=rotate
297+
qualname=extension
298+
propagate=0
299+
300+
[handlers]
301+
keys=basic,rotate,rotate_weblog
302+
303+
[handler_basic]
304+
class=StreamHandler
305+
args=(sys.stderr,)
306+
formatter=basic
307+
308+
[handler_rotate]
309+
class=logging.handlers.RotatingFileHandler
310+
args=('roundup.log','a', 5120000, 2)
311+
formatter=basic
312+
313+
[handler_rotate_weblog]
314+
class=logging.handlers.RotatingFileHandler
315+
args=('httpd.log','a', 1024000, 2)
316+
formatter=plain
317+
318+
[formatters]
319+
keys=basic,plain
320+
321+
[formatter_basic]
322+
format=%(asctime)s %(process)d %(name)s:%(module)s.%(funcName)s,%(levelname)s: %(message)s
323+
datefmt=%Y-%m-%d %H:%M:%S
324+
325+
[formatter_plain]
326+
format=%(process)d %(message)s
327+
75328

76329
Configuring roundup-server
77330
==========================

doc/upgrading.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,21 @@ date, text etc.) do not need JavaScript to work.
133133

134134
See :ref:`Confirming the User` in the reference manual for details.
135135

136+
Support for dictConfig Logging Configuration (optional)
137+
-------------------------------------------------------
138+
139+
Roundup's basic log configuration via config.ini has always had the
140+
ability to use an ini style logging configuration to set levels per
141+
log channel, control output file rotation etc.
142+
143+
With Roundup 2.6 you can use a JSON like file to configure logging
144+
using `dictConfig
145+
<https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig>`_. The
146+
JSON file format as been enhanced to support comments that are
147+
stripped before being processed by the logging system.
148+
149+
You can read about the details in the :ref:`admin manual <dictLogConfig>`.
150+
136151
.. index:: Upgrading; 2.4.0 to 2.5.0
137152

138153
Migrating from 2.4.0 to 2.5.0

0 commit comments

Comments
 (0)