[Django] #21429: BaseCommand should use logging instead of custom output wrappers

81 views
Skip to first unread message

Django

unread,
Nov 12, 2013, 9:33:49 PM11/12/13
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
--------------------------------------------+------------------------------
Reporter: Nical | Owner: nobody
Type: New feature | Status: new
Component: Core (Management commands) | Version: 1.6
Severity: Normal | Keywords: command output
Triage Stage: Unreviewed | logger
Easy pickings: 0 | Has patch: 0
| UI/UX: 0
--------------------------------------------+------------------------------
Since python offers the powerful logging class,
django.core.management.base.BaseCommand should use it to output messages
instead of using custom output wrappers
(django.core.management.base.OutputWrapper).

Doing so, we could override those loggers in the settings.py file.

Instead of having two wrappers in a command and having to do:

{{{
class Command(BaseCommand):
def handle(self):
self.stdout.write('this is an info message')
self.stderr.write('this is an error message')
}}}

We could do

{{{
class Command(BaseCommand):
def handle(self):
self.output.info('this is an info message')
self.output.error('this is an error message')
# and even
self.output.warning('this is a warning message')
}}}

The style_func and ending arguments that the
django.core.management.base.OutputWrapper.write method takes could be
removed and be configured at once in a overriding custom logger.

--
Ticket URL: <https://code.djangoproject.com/ticket/21429>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Nov 13, 2013, 1:30:31 PM11/13/13
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------

Reporter: Nical | Owner: nobody
Type: New feature | Status: new
Component: Core (Management | Version: master
commands) | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: command output | Needs documentation: 0
logger | Patch needs improvement: 0

Has patch: 0 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by claudep):

* needs_better_patch: => 0
* needs_docs: => 0
* version: 1.6 => master
* needs_tests: => 0
* stage: Unreviewed => Accepted


Comment:

I worked on that idea in #15107 (that I just closed).

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:1>

Django

unread,
Nov 4, 2014, 8:38:15 PM11/4/14
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner:
Type: New feature | berkerpeksag
Component: Core (Management | Status: assigned
commands) | Version: master
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger | Needs documentation: 0
Has patch: 1 | Patch needs improvement: 0
Needs tests: 0 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by berkerpeksag):

* owner: nobody => berkerpeksag
* status: new => assigned
* has_patch: 0 => 1


Comment:

https://github.com/django/django/pull/3467

This PR implements an initial integration of logging module in
BaseCommand. I've also updated the documentation a bit. If this approach
is okay, I'll update all management commands and tests.

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:2>

Django

unread,
Nov 5, 2014, 2:52:28 AM11/5/14
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner:
Type: New feature | berkerpeksag
Component: Core (Management | Status: assigned
commands) | Version: master
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger | Needs documentation: 0
Has patch: 1 | Patch needs improvement: 0
Needs tests: 0 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by claudep):

Do we want to keep the old `stdout/stderr` way of outputting messages in
addition to the new API? This would make `self.stdout.write/self.info` and
`self.stderr.write/self.error` redundants. Or did you intend to deprecate
`self.stdout/self.stderr`?

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:3>

Django

unread,
Nov 5, 2014, 10:51:17 AM11/5/14
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner:
Type: New feature | berkerpeksag
Component: Core (Management | Status: assigned
commands) | Version: master
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger | Needs documentation: 0
Has patch: 1 | Patch needs improvement: 0
Needs tests: 0 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by berkerpeksag):

> Or did you intend to deprecate self.stdout/self.stderr?

Yes, but I couldn't find a simple way to deprecate them yesterday. Today,
here is my approach:
https://github.com/berkerpeksag/django/commit/b439b472842bfd2d04c36b28d079a80fac5814bb

PR updated to address Simon's comments.

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:4>

Django

unread,
Dec 24, 2014, 4:18:02 PM12/24/14
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner:
| berkerpeksag
Type: New feature | Status: assigned

Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* needs_better_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:5>

Django

unread,
Apr 22, 2016, 5:53:11 AM4/22/16
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner:
| berkerpeksag
Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by sposs):

I saw that the pull request was closed on github. Are there any plans to
revive this? It would be very nice to be able to configure logging like
everywhere else...

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:6>

Django

unread,
Apr 22, 2016, 7:26:48 AM4/22/16
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner:
| berkerpeksag
Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by timgraham):

Feel free to resume work on the patch if you like.

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:7>

Django

unread,
Feb 24, 2017, 11:14:06 PM2/24/17
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner:
| ChillarAnand

Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by ChillarAnand):

* owner: Berker Peksag => ChillarAnand


--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:8>

Django

unread,
Feb 26, 2017, 11:26:18 AM2/26/17
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner: (none)

Type: New feature | Status: new
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by ChillarAnand):

* owner: ChillarAnand => (none)
* status: assigned => new


--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:9>

Django

unread,
Aug 17, 2017, 7:05:46 PM8/17/17
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner: John Kang

Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by John Kang):

* status: new => assigned

* owner: (none) => John Kang


--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:10>

Django

unread,
Jan 27, 2018, 2:38:50 AM1/27/18
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner: John Kang
Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by John Kang):

Hi all, going to resume work on this patch.

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:11>

Django

unread,
Feb 17, 2018, 3:06:59 PM2/17/18
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner: John Kang
Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by John Kang):

Hi,

I was working through this ticket when I noticed that some of the command
outputs (migrations for example) output a status on the same line. Example
would be:
"migrating-xx.. OK"

Python loggers implicitly add new line characters at the end.
Should I leave these log outputs with newlines or is there a better way to
append command statuses on the same line?

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:12>

Django

unread,
Jul 13, 2019, 11:13:55 PM7/13/19
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner: John Kang
Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Forest Gregg):

> Python loggers implicitly add new line characters at the end.
> Should I leave these log outputs with newlines or is there a better way
to append command statuses on the same line?

As of Python 3.2, you can set the terminator to
[[https://docs.python.org/3/library/logging.handlers.html#streamhandler|something
other than the newline in the StreamHandler]]. You could use a special
handler for logging migrations to keep the current behavior.

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:13>

Django

unread,
Apr 18, 2020, 6:50:26 AM4/18/20
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner: François
| Freitag

Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by François Freitag):

* owner: John Kang => François Freitag


Comment:

It seems this ticket stalled. I am interested in seeing that feature in
Django, resuming work on it.

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:14>

Django

unread,
Jun 14, 2020, 12:49:18 PM6/14/20
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner: François
| Freitag
Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by François Freitag):

An update after about 2 months. There is still a good chunk of work left,
to clean-up commits, prepare for the transition, update the documentation,
etc. but the work is taking shape: all management commands have been
updated to use a logger, tests updated accordingly and the test suite
passes.

In my draft, there’s a main logger for all commands, `django.command`, and
a logger dedicated to report progress of commands `django.progress` that
uses `\r` as a terminator. I’m planning on splitting `django.command` to
have a logger per command, e.g. `django.command.migrate`, all with
`django.command` as their parent. That will facilitate redirecting the
output of a particular command while relying on the parent behavior
otherwise.

Notable changes:
- `CommandError` assumed the message was interpolated. A `logger_args`
keyword
argument was introduced to pass variable arguments separately
(https://docs.python.org/3.8/howto/logging.html#logging-variable-data).
- Format placeholders are generated for messages where a variable number
of
arguments is used, in order to pass the variable data separately from
the
message. For example, a message listing issues in apps was previously
logged
as `"\n".join(variables)`. To log variable data separately, the message
becomes
`"\n".join(["%s"] * len(variables))`.

Left out of scope:
Some commands directly raise the message from an exception they caught as
a `CommandError`.
Ideally, variable data would be separated from the message, so that the
logger handles the variable data separately. However, the exceptions are
generated by other modules, which do not know how the exception will be
used.. In these cases, I’m using the interpolated error message for the
`CommandError`, not logging variable data separately. This can be improved
upon at a later stage.

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:15>

Django

unread,
Mar 2, 2021, 3:08:46 PM3/2/21
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner: François
| Freitag
Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Mariusz Felisiak <felisiak.mariusz@…>):

In [changeset:"7ca7f4495ba746279b734695a8dd137bf7ee0bab" 7ca7f449]:
{{{
#!CommitTicketReference repository=""
revision="7ca7f4495ba746279b734695a8dd137bf7ee0bab"
Refs #21429 -- Added SimpleTestCase.assertNoLogs() on Python < 3.10.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:16>

Django

unread,
Apr 21, 2023, 8:54:05 AM4/21/23
to django-...@googlegroups.com
#21429: BaseCommand should use logging instead of custom output wrappers
-------------------------------------+-------------------------------------
Reporter: Nical | Owner: (none)
Type: New feature | Status: new
Component: Core (Management | Version: dev

commands) |
Severity: Normal | Resolution:
Keywords: command output | Triage Stage: Accepted
logger |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by François Freitag):

* owner: François Freitag => (none)


* status: assigned => new


--
Ticket URL: <https://code.djangoproject.com/ticket/21429#comment:17>

Reply all
Reply to author
Forward
0 new messages