Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Simple logging interface. #13275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions doc/devel/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -435,18 +435,22 @@ To include `logging` in your module, at the top of the module, you need to
will log to a logger named ``matplotlib.yourmodulename``.

If an end-user of Matplotlib sets up `logging` to display at levels
more verbose than `logger.WARNING` in their code as follows::
more verbose than `logger.WARNING` in their code with the Matplotlib-provided
helper::

plt.set_loglevel("debug")

or manually with ::

import logging
fmt = '%(name)s:%(lineno)5d - %(levelname)s - %(message)s'
logging.basicConfig(level=logging.DEBUG, format=fmt)
logging.basicConfig(level=logging.DEBUG)
import matplotlib.pyplot as plt

Then they will receive messages like::

matplotlib.backends: 89 - INFO - backend MacOSX version unknown
matplotlib.yourmodulename: 347 - INFO - Here is some information
matplotlib.yourmodulename: 348 - DEBUG - Here is some more detailed information
DEBUG:matplotlib.backends:backend MacOSX version unknown
DEBUG:matplotlib.yourmodulename:Here is some information
DEBUG:matplotlib.yourmodulename:Here is some more detailed information

Which logging level to use?
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
35 changes: 9 additions & 26 deletions doc/faq/troubleshooting_faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -114,35 +114,18 @@ provide the following information in your e-mail to the `mailing list
the error will help you find a bug in *your* code that is causing the
problem.

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

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

to obtain this debugging information.

If you want to put the debugging hooks in your own code, then the
most simple way to do so is to insert the following *before* any calls
to ``import matplotlib``::

import logging
logging.basicConfig(level=logging.DEBUG)

import matplotlib.pyplot as plt

Note that if you want to use `logging` in your own code, but do not
want verbose Matplotlib output, you can set the logging level
for Matplotlib independently::

import logging
# set DEBUG for everything
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('matplotlib')
# set WARNING for Matplotlib
logger.setLevel(logging.WARNING)

The `logging` module is very flexible, and can be a valuable tool in chasing
down errors.
Standard functions from the `logging` module are also applicable; e.g. one
could call ``logging.basicConfig(level="DEBUG")`` even before importing
Matplotlib (this is in particular necessary to get the logging info emitted
during Matplotlib's import), or attach a custom handler to the "matplotlib"
logger. This may be useful if you use a custom logging configuration.

If you compiled Matplotlib yourself, please also provide:

Expand Down
7 changes: 7 additions & 0 deletions doc/users/next_whats_new/2019-01-24-AL-set_loglevel.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
:orphan:

New logging API
```````````````

`matplotlib.set_loglevel`/`.pyplot.set_loglevel` can be called to display more
(or less) detailed logging output.
69 changes: 32 additions & 37 deletions lib/matplotlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,48 +206,43 @@ def _check_versions():
sys.argv = ['modpython']


_verbose_msg = """\
matplotlib.verbose is deprecated;
Command line argument --verbose-LEVEL is deprecated.
This functionality is now provided by the standard
python logging library. To get more (or less) logging output:
import logging
logger = logging.getLogger('matplotlib')
logger.set_level(logging.INFO)"""
# The decorator ensures this always returns the same handler (and it is only
# attached once).
@functools.lru_cache()
def _ensure_handler():
"""
The first time this function is called, attach a `StreamHandler` using the
same format as `logging.basicConfig` to the Matplotlib root logger.

Return this handler every time this function is called.
"""
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
_log.addHandler(handler)
return handler


def _set_logger_verbose_level(level_str='silent', file_str='sys.stdout'):
def set_loglevel(level):
"""
Use a --verbose-LEVEL level to set the logging level:
Sets the Matplotlib's root logger and root logger handler level, creating
the handler if it does not exist yet.

Typically, one should call ``set_loglevel("info")`` or
``set_loglevel("debug")`` to get additional debugging information.

Parameters
----------
level : {"notset", "debug", "info", "warning", "error", "critical"}
The log level of the handler.

Notes
-----
The first time this function is called, an additional handler is attached
to Matplotlib's root handler; this handler is reused every time and this
function simply manipulates the logger and handler's level.
"""
levelmap = {'silent': logging.WARNING, 'helpful': logging.INFO,
'debug': logging.DEBUG, 'debug-annoying': logging.DEBUG,
'info': logging.INFO, 'warning': logging.WARNING}
# Check that current state of logger isn't already more verbose
# than the requested level. If it is more verbose, then leave more
# verbose.
newlev = levelmap[level_str]
oldlev = _log.getEffectiveLevel()
if newlev < oldlev:
_log.setLevel(newlev)
std = {
'sys.stdout': sys.stdout,
'sys.stderr': sys.stderr,
}
if file_str in std:
fileo = std[file_str]
else:
fileo = sys.stdout
try:
fileo = open(file_str, 'w')
# if this fails, we will just write to stdout
except IOError:
_log.warning('could not open log file "{0}" for writing. '
'Check your matplotlibrc'.format(file_str))
console = logging.StreamHandler(fileo)
console.setLevel(newlev)
_log.addHandler(console)
_log.setLevel(level.upper())
_ensure_handler().setLevel(level.upper())


def _logged_cached(fmt, func=None):
Expand Down
6 changes: 6 additions & 0 deletions lib/matplotlib/pyplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
The object-oriented API is recommended for more complex plots.
"""

import functools
import importlib
import inspect
import logging
Expand Down Expand Up @@ -166,6 +167,11 @@ def uninstall_repl_displayhook():
draw_all = _pylab_helpers.Gcf.draw_all


@functools.wraps(matplotlib.set_loglevel)
def set_loglevel(*args, **kwargs): # Ensure this appears in the pyplot docs.
return matplotlib.set_loglevel(*args, **kwargs)


@docstring.copy(Artist.findobj)
def findobj(o=None, match=None, include_self=True):
if o is None:
Expand Down