1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
:LastChangedDate: $LastChangedDate$
:LastChangedRevision: $LastChangedRevision$
:LastChangedBy: $LastChangedBy$
Twisted's Legacy Logging System: ``twisted.python.log``
=======================================================
.. note::
There is now a new logging system in Twisted (:doc:`you can read about how to use it here <logger>` and :py:mod:`its API reference here <twisted.logger>`) which is a replacement for :py:mod:`twisted.python.log`.
The old logging API, described here, remains for compatibility, and is now implemented as a client of the new logging system.
New code should adopt the new API.
Basic usage
-----------
Twisted provides a simple and flexible logging system in the :py:mod:`twisted.python.log` module. It has three commonly used
functions:
:py:meth:`msg <twisted.python.log.LogPublisher.msg>`
Logs a new message. For example:
.. code-block:: python
from twisted.python import log
log.msg('Hello, world.')
:py:func:`err <twisted.python.log.err>`
Writes a failure to the log, including traceback information (if any).
You can pass it a :py:class:`Failure <twisted.python.failure.Failure>` or Exception instance, or
nothing. If you pass something else, it will be converted to a string
with ``repr`` and logged.
If you pass nothing, it will construct a Failure from the
currently active exception, which makes it convenient to use in an ``except`` clause:
.. code-block:: python
try:
x = 1 / 0
except BaseException:
log.err() # will log the ZeroDivisionError
:py:func:`startLogging <twisted.python.log.startLogging>`
Starts logging to a given file-like object. For example:
.. code-block:: python
log.startLogging(open('/var/log/foo.log', 'w'))
or:
.. code-block:: python
log.startLogging(sys.stdout)
or:
.. code-block:: python
from twisted.python.logfile import DailyLogFile
log.startLogging(DailyLogFile.fromFullPath("/var/log/foo.log"))
By default, ``startLogging`` will also redirect anything written
to ``sys.stdout`` and ``sys.stderr`` to the log. You
can disable this by passing ``setStdout=False`` to
``startLogging`` .
Before ``startLogging`` is called, log messages will be
discarded and errors will be written to stderr.
Logging and twistd
~~~~~~~~~~~~~~~~~~
If you are using ``twistd`` to run your daemon, it
will take care of calling ``startLogging`` for you, and will also
rotate log files. See :ref:`twistd and tac <core-howto-application-twistd>`
and the ``twistd`` man page for details of using
twistd.
Log files
~~~~~~~~~
The :py:mod:`twisted.python.logfile` module provides
some standard classes suitable for use with ``startLogging`` , such
as :py:class:`DailyLogFile <twisted.python.logfile.DailyLogFile>` ,
which will rotate the log to a new file once per day.
Using the standard library logging module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If your application uses the
Python `standard library logging module <http://docs.python.org/library/logging.html>`_ or you want to use its easy configuration but
don't want to lose twisted-produced messages, the observer
:py:class:`PythonLoggingObserver <twisted.python.log.PythonLoggingObserver>`
should be useful to you.
You just start it like any other observer:
.. code-block:: python
observer = log.PythonLoggingObserver()
observer.start()
Then `configure the standard library logging module <http://docs.python.org/library/logging.html>`_ to behave as you want.
This method allows you to customize the log level received by the
standard library logging module using the ``logLevel`` keyword:
.. code-block:: python
log.msg("This is important!", logLevel=logging.CRITICAL)
log.msg("Don't mind", logLevel=logging.DEBUG)
Unless ``logLevel`` is provided, logging.INFO is used for ``log.msg``
and ``logging.ERROR`` is used for ``log.err`` .
One special care should be made when you use special configuration of
the standard library logging module: some handlers (e.g. SMTP, HTTP) use the network and
so can block inside the reactor loop. *Nothing* in ``PythonLoggingObserver`` is
done to prevent that.
Writing log observers
---------------------
Log observers are the basis of the Twisted logging system.
Whenever ``log.msg`` (or ``log.err`` ) is called, an
event is emitted. The event is passed to each observer which has been
registered. There can be any number of observers, and each can treat
the event in any way desired.
An example of
a log observer in Twisted is the ``emit`` method of :py:class:`FileLogObserver <twisted.python.log.FileLogObserver>` .
``FileLogObserver`` , used by
``startLogging`` , writes events to a log file. A log observer
is just a callable that accepts a dictionary as its only argument. You can
then register it to receive all log events (in addition to any other
observers):
.. code-block:: python
twisted.python.log.addObserver(yourCallable)
The dictionary will have at least two items:
message
The message (a list, usually of strings)
for this log event, as passed to ``log.msg`` or the
message in the failure passed to ``log.err`` .
isError
This is a boolean that will be true if this event came from a call to
``log.err`` . If this is set, there may be a ``failure``
item in the dictionary as will, with a Failure object in it.
Other items the built in logging functionality may add include:
printed
This message was captured from ``sys.stdout`` , i.e. this
message came from a ``print`` statement. If
``isError`` is also true, it came from
``sys.stderr`` .
You can pass additional items to the event dictionary by passing keyword
arguments to ``log.msg`` and ``log.err`` . The standard
log observers will ignore dictionary items they don't use.
Important notes:
- Never block in a log observer, as it may run in main Twisted thread.
This means you can't use socket or syslog standard library logging backends.
- The observer needs to be thread safe if you anticipate using threads
in your program.
Customizing ``twistd`` logging
-------------------------------
The behavior of the logging that ``twistd`` does can be
customized either with the ``--logger`` option or by setting the
``ILogObserver`` component on the application object. See the :doc:`Application document <application>` for more information.
|