Skip to content

Commit ac3db2e

Browse files
committed
Simple logging interface.
1 parent 121102b commit ac3db2e

File tree

5 files changed

+64
-69
lines changed

5 files changed

+64
-69
lines changed

doc/devel/contributing.rst

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -435,18 +435,22 @@ To include `logging` in your module, at the top of the module, you need to
435435
will log to a logger named ``matplotlib.yourmodulename``.
436436

437437
If an end-user of Matplotlib sets up `logging` to display at levels
438-
more verbose than `logger.WARNING` in their code as follows::
438+
more verbose than `logger.WARNING` in their code with the Matplotlib-provided
439+
helper::
440+
441+
plt.set_loglevel("debug")
442+
443+
or manually with ::
439444

440445
import logging
441-
fmt = '%(name)s:%(lineno)5d - %(levelname)s - %(message)s'
442-
logging.basicConfig(level=logging.DEBUG, format=fmt)
446+
logging.basicConfig(level=logging.DEBUG)
443447
import matplotlib.pyplot as plt
444448

445449
Then they will receive messages like::
446450

447-
matplotlib.backends: 89 - INFO - backend MacOSX version unknown
448-
matplotlib.yourmodulename: 347 - INFO - Here is some information
449-
matplotlib.yourmodulename: 348 - DEBUG - Here is some more detailed information
451+
DEBUG:matplotlib.backends:backend MacOSX version unknown
452+
DEBUG:matplotlib.yourmodulename:Here is some information
453+
DEBUG:matplotlib.yourmodulename:Here is some more detailed information
450454

451455
Which logging level to use?
452456
~~~~~~~~~~~~~~~~~~~~~~~~~~~

doc/faq/troubleshooting_faq.rst

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -114,35 +114,18 @@ provide the following information in your e-mail to the `mailing list
114114
the error will help you find a bug in *your* code that is causing the
115115
problem.
116116

117-
* You can get helpful debugging output from Matlotlib by using the `logging`
118-
library in your code and posting the verbose output to the lists. For a
119-
command-line version of this, try::
117+
* Matplotlib provides debugging information through the `logging` library, and
118+
a helper function to set the logging level: one can call ::
120119

121-
python -c "from logging import *; basicConfig(level=DEBUG); from pylab import *; plot(); show()"
120+
plt.set_loglevel("info") # or "debug" for more info
122121

122+
to obtain this debugging information.
123123

124-
If you want to put the debugging hooks in your own code, then the
125-
most simple way to do so is to insert the following *before* any calls
126-
to ``import matplotlib``::
127-
128-
import logging
129-
logging.basicConfig(level=logging.DEBUG)
130-
131-
import matplotlib.pyplot as plt
132-
133-
Note that if you want to use `logging` in your own code, but do not
134-
want verbose Matplotlib output, you can set the logging level
135-
for Matplotlib independently::
136-
137-
import logging
138-
# set DEBUG for everything
139-
logging.basicConfig(level=logging.DEBUG)
140-
logger = logging.getLogger('matplotlib')
141-
# set WARNING for Matplotlib
142-
logger.setLevel(logging.WARNING)
143-
144-
The `logging` module is very flexible, and can be a valuable tool in chasing
145-
down errors.
124+
Standard functions from the `logging` module are also applicable; e.g. one
125+
could call ``logging.basicConfig(level="DEBUG")`` even before importing
126+
Matplotlib (this is in particular necessary to get the logging info emitted
127+
during Matplotlib's import), or attach a custom handler to the "matplotlib"
128+
logger. This may be useful if you use a custom logging configuration.
146129

147130
If you compiled Matplotlib yourself, please also provide:
148131

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
:orphan:
2+
3+
New logging API
4+
```````````````
5+
6+
`matplotlib.set_loglevel`/`.pyplot.set_loglevel` can be called to display more
7+
(or less) detailed logging output.

lib/matplotlib/__init__.py

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -206,48 +206,43 @@ def _check_versions():
206206
sys.argv = ['modpython']
207207

208208

209-
_verbose_msg = """\
210-
matplotlib.verbose is deprecated;
211-
Command line argument --verbose-LEVEL is deprecated.
212-
This functionality is now provided by the standard
213-
python logging library. To get more (or less) logging output:
214-
import logging
215-
logger = logging.getLogger('matplotlib')
216-
logger.set_level(logging.INFO)"""
209+
# The decorator ensures this always returns the same handler (and it is only
210+
# attached once).
211+
@functools.lru_cache()
212+
def _ensure_handler():
213+
"""
214+
The first time this function is called, attach a `StreamHandler` using the
215+
same format as `logging.basicConfig` to the Matplotlib root logger.
216+
217+
Return this handler every time this function is called.
218+
"""
219+
handler = logging.StreamHandler()
220+
handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
221+
_log.addHandler(handler)
222+
return handler
217223

218224

219-
def _set_logger_verbose_level(level_str='silent', file_str='sys.stdout'):
225+
def set_loglevel(level):
220226
"""
221-
Use a --verbose-LEVEL level to set the logging level:
227+
Sets the Matplotlib's root logger and root logger handler level, creating
228+
the handler if it does not exist yet.
222229
230+
Typically, one should call ``set_loglevel("info")`` or
231+
``set_loglevel("debug")`` to get additional debugging information.
232+
233+
Parameters
234+
----------
235+
level : {"notset", "debug", "info", "warning", "error", "critical"}
236+
The log level of the handler.
237+
238+
Notes
239+
-----
240+
The first time this function is called, an additional handler is attached
241+
to Matplotlib's root handler; this handler is reused every time and this
242+
function simply manipulates the logger and handler's level.
223243
"""
224-
levelmap = {'silent': logging.WARNING, 'helpful': logging.INFO,
225-
'debug': logging.DEBUG, 'debug-annoying': logging.DEBUG,
226-
'info': logging.INFO, 'warning': logging.WARNING}
227-
# Check that current state of logger isn't already more verbose
228-
# than the requested level. If it is more verbose, then leave more
229-
# verbose.
230-
newlev = levelmap[level_str]
231-
oldlev = _log.getEffectiveLevel()
232-
if newlev < oldlev:
233-
_log.setLevel(newlev)
234-
std = {
235-
'sys.stdout': sys.stdout,
236-
'sys.stderr': sys.stderr,
237-
}
238-
if file_str in std:
239-
fileo = std[file_str]
240-
else:
241-
fileo = sys.stdout
242-
try:
243-
fileo = open(file_str, 'w')
244-
# if this fails, we will just write to stdout
245-
except IOError:
246-
_log.warning('could not open log file "{0}" for writing. '
247-
'Check your matplotlibrc'.format(file_str))
248-
console = logging.StreamHandler(fileo)
249-
console.setLevel(newlev)
250-
_log.addHandler(console)
244+
_log.setLevel(level.upper())
245+
_ensure_handler().setLevel(level.upper())
251246

252247

253248
def _logged_cached(fmt, func=None):

lib/matplotlib/pyplot.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
The object-oriented API is recommended for more complex plots.
1919
"""
2020

21+
import functools
2122
import importlib
2223
import inspect
2324
import logging
@@ -166,6 +167,11 @@ def uninstall_repl_displayhook():
166167
draw_all = _pylab_helpers.Gcf.draw_all
167168

168169

170+
@functools.wraps(matplotlib.set_loglevel)
171+
def set_loglevel(*args, **kwargs): # Ensure this appears in the pyplot docs.
172+
return matplotlib.set_loglevel(*args, **kwargs)
173+
174+
169175
@docstring.copy(Artist.findobj)
170176
def findobj(o=None, match=None, include_self=True):
171177
if o is None:

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy