如何使用 Logging 模組¶
- 作者:
Vinay Sajip <vinay_sajip at red-dove dot com>
This page contains tutorial information. For links to reference information and a logging cookbook, please see 其他資源.
基礎 Logging 指南¶
軟體執行時,追蹤有什麼事件發生的動作稱為 Logging。軟體開發者會使用 Logging 這樣的機制是因為想知道在運行過程中是否有特定的事件發生。事件會被一段訊息所描述。這段訊息可能包含一些因為此事件發生而改變的資料。開發者也可以指派事件的重要程度,重要程度有時候也會被稱作 程度 或是 嚴重性 。
什麼時候使用 logging¶
You can access logging functionality by creating a logger via logger =
logging.getLogger(__name__), and then calling the logger's debug(),
info(), warning(), error() and
critical() methods. To determine when to use logging, and to see
which logger methods to use when, see the table below. It states, for each of a
set of common tasks, the best tool to use for that task.
Task you want to perform |
The best tool for the task |
|---|---|
Display console output for ordinary usage of a command line script or program |
|
Report events that occur during normal operation of a program (e.g. for status monitoring or fault investigation) |
A logger's |
Issue a warning regarding a particular runtime event |
A logger's |
Report an error regarding a particular runtime event |
引發一個例外 |
Report suppression of an error without raising an exception (e.g. error handler in a long-running server process) |
A logger's |
The logger methods are named after the level or severity of the events they are used to track. The standard levels and their applicability are described below (in increasing order of severity):
Level |
When it's used |
|---|---|
|
Detailed information, typically of interest only when diagnosing problems. |
|
Confirmation that things are working as expected. |
|
An indication that something unexpected happened, or indicative of some problem in the near future (e.g. 'disk space low'). The software is still working as expected. |
|
Due to a more serious problem, the software has not been able to perform some function. |
|
A serious error, indicating that the program itself may be unable to continue running. |
The default level is WARNING, which means that only events of this severity and higher
will be tracked, unless the logging package is configured to do otherwise.
Events that are tracked can be handled in different ways. The simplest way of handling tracked events is to print them to the console. Another common way is to write them to a disk file.
一個簡單範例¶
一個非常簡單的例子是:
import logging
logging.warning('Watch out!') # 將會印出訊息至控制台
logging.info('I told you so') # 不會印出任何東西
If you type these lines into a script and run it, you'll see:
WARNING:root:Watch out!
printed out on the console. The INFO message doesn't appear because the
default level is WARNING. The printed message includes the indication of the
level and the description of the event provided in the logging call, i.e.
'Watch out!'. The actual output can be formatted quite flexibly if you need
that; formatting options will also be explained later.
Notice that in this example, we use functions directly on the logging
module, like logging.debug, rather than creating a logger and calling
functions on it. These functions operate on the root logger, but can be useful
as they will call basicConfig() for you if it has not been called yet, like in
this example. In larger programs you'll usually want to control the logging
configuration explicitly however - so for that reason as well as others, it's
better to create loggers and call their methods.
Logging to a file¶
A very common situation is that of recording logging events in a file, so let's look at that next. Be sure to try the following in a newly started Python interpreter, and don't just continue from the session described above:
import logging
logger = logging.getLogger(__name__)
logging.basicConfig(filename='example.log', encoding='utf-8', level=logging.DEBUG)
logger.debug('This message should go to the log file')
logger.info('So should this')
logger.warning('And this, too')
logger.error('And non-ASCII stuff, too, like Øresund and Malmö')
在 3.9 版的變更: The encoding argument was added. In earlier Python versions, or if not
specified, the encoding used is the default value used by open(). While
not shown in the above example, an errors argument can also now be passed,
which determines how encoding errors are handled. For available values and
the default, see the documentation for open().
And now if we open the file and look at what we have, we should find the log messages:
DEBUG:__main__:This message should go to the log file
INFO:__main__:So should this
WARNING:__main__:And this, too
ERROR:__main__:And non-ASCII stuff, too, like Øresund and Malmö
This example also shows how you can set the logging level which acts as the
threshold for tracking. In this case, because we set the threshold to
DEBUG, all of the messages were printed.
If you want to set the logging level from a command-line option such as:
--log=INFO
and you have the value of the parameter passed for --log in some variable
loglevel, you can use:
getattr(logging, loglevel.upper())
to get the value which you'll pass to basicConfig() via the level
argument. You may want to error check any user input value, perhaps as in the
following example:
# assuming loglevel is bound to the string value obtained from the
# command line argument. Convert to upper case to allow the user to
# specify --log=DEBUG or --log=debug
numeric_level = getattr(logging, loglevel.upper(), None)
if not isinstance(numeric_level, int):
raise ValueError('Invalid log level: %s' % loglevel)
logging.basicConfig(level=numeric_level, ...)
The call to basicConfig() should come before any calls to a logger's
methods such as debug(), info(), etc. Otherwise,
that logging event may not be handled in the desired manner.
If you run the above script several times, the messages from successive runs are appended to the file example.log. If you want each run to start afresh, not remembering the messages from earlier runs, you can specify the filemode argument, by changing the call in the above example to:
logging.basicConfig(filename='example.log', filemode='w', level=logging.DEBUG)
The output will be the same as before, but the log file is no longer appended to, so the messages from earlier runs are lost.
Logging variable data¶
To log variable data, use a format string for the event description message and append the variable data as arguments. For example:
import logging
logging.warning('%s before you %s', 'Look', 'leap!')
will display:
WARNING:root:Look before you leap!
As you can see, merging of variable data into the event description message
uses the old, %-style of string formatting. This is for backwards
compatibility: the logging package pre-dates newer formatting options such as
str.format() and