loggingTools¶
fontTools.misc.loggingTools.py – tools for interfacing with the Python logging package.
-
class
fontTools.misc.loggingTools.
CapturingLogHandler
(logger, level)[source]¶ -
acquire
()¶ Acquire the I/O thread lock.
-
addFilter
(filter)¶ Add the specified filter to this handler.
-
close
()¶ Tidy up any resources used by the handler.
This version removes the handler from an internal map of handlers, _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods.
-
createLock
()¶ Acquire a thread lock for serializing access to the underlying I/O.
-
emit
(record)[source]¶ Do whatever it takes to actually log the specified logging record.
This version is intended to be implemented by subclasses and so raises a NotImplementedError.
-
filter
(record)¶ Determine if a record is loggable by consulting all the filters.
The default is to allow the record to be logged; any filter can veto this and the record is then dropped. Returns a zero value if a record is to be dropped, else non-zero.
Changed in version 3.2: Allow filters to be just callables.
-
flush
()¶ Ensure all logging output has been flushed.
This version does nothing and is intended to be implemented by subclasses.
-
format
(record)¶ Format the specified record.
If a formatter is set, use it. Otherwise, use the default formatter for the module.
-
get_name
()¶
-
handle
(record)¶ Conditionally emit the specified logging record.
Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of the I/O thread lock. Returns whether the filter passed the record for emission.
-
handleError
(record)¶ Handle errors which occur during an emit() call.
This method should be called from handlers when an exception is encountered during an emit() call. If raiseExceptions is false, exceptions get silently ignored. This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors. You could, however, replace this with a custom handler if you wish. The record which was being processed is passed in to this method.
-
property
name
¶
-
release
()¶ Release the I/O thread lock.
-
removeFilter
(filter)¶ Remove the specified filter from this handler.
-
setFormatter
(fmt)¶ Set the formatter for this handler.
-
setLevel
(level)¶ Set the logging level of this handler. level must be an int or a str.
-
set_name
(name)¶
-
-
class
fontTools.misc.loggingTools.
ChannelsFilter
(*names)[source]¶ Filter out records emitted from a list of enabled channel names, including their children. It works the same as the logging.Filter class, but allows to specify multiple channel names.
>>> import sys >>> handler = logging.StreamHandler(sys.stdout) >>> handler.setFormatter(logging.Formatter("%(message)s")) >>> filter = ChannelsFilter("A.B", "C.D") >>> handler.addFilter(filter) >>> root = logging.getLogger() >>> root.addHandler(handler) >>> root.setLevel(level=logging.DEBUG) >>> logging.getLogger('A.B').debug('this record passes through') this record passes through >>> logging.getLogger('A.B.C').debug('records from children also pass') records from children also pass >>> logging.getLogger('C.D').debug('this one as well') this one as well >>> logging.getLogger('A.B.').debug('also this one') also this one >>> logging.getLogger('A.F').debug('but this one does not!') >>> logging.getLogger('C.DE').debug('neither this one!')
-
class
fontTools.misc.loggingTools.
LevelFormatter
(fmt=None, datefmt=None, style='%')[source]¶ Formatter class which optionally takes a dict of logging levels to format strings, allowing to customise the log records appearance for specific levels. The ‘*’ key identifies the default format string.
>>> import sys >>> handler = logging.StreamHandler(sys.stdout) >>> formatter = LevelFormatter( ... fmt={ ... '*': '[%(levelname)s] %(message)s', ... 'DEBUG': '%(name)s [%(levelname)s] %(message)s', ... 'INFO': '%(message)s', ... }) >>> handler.setFormatter(formatter) >>> log = logging.getLogger('test') >>> log.setLevel(logging.DEBUG) >>> log.addHandler(handler) >>> log.debug('this uses a custom format string') test [DEBUG] this uses a custom format string >>> log.info('this also uses a custom format string') this also uses a custom format string >>> log.warning("this one uses the default format string") [WARNING] this one uses the default format string
-
converter
()¶ - localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,
tm_sec,tm_wday,tm_yday,tm_isdst)
Convert seconds since the Epoch to a time tuple expressing local time. When ‘seconds’ is not passed in, convert the current time instead.
-
default_msec_format
= '%s,%03d'¶
-
default_time_format
= '%Y-%m-%d %H:%M:%S'¶
-
format
(record)[source]¶ Format the specified record as text.
The record’s attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message.
-
formatException
(ei)¶ Format and return the specified exception information as a string.
This default implementation just uses traceback.print_exception()
-
formatMessage
(record)¶
-
formatStack
(stack_info)¶ This method is provided as an extension point for specialized formatting of stack information.
The input data is a string as returned from a call to
traceback.print_stack()
, but with the last trailing newline removed.The base implementation just returns the value passed in.
-
formatTime
(record, datefmt=None)¶ Return the creation time of the specified LogRecord as formatted text.
This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the ‘converter’ attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the ‘converter’ attribute in the Formatter class.
-
usesTime
()¶ Check if the format uses the creation time of the record.
-
-
class
fontTools.misc.loggingTools.
LogMixin
[source]¶ Mixin class that adds logging functionality to another class. You can define a new class that subclasses from LogMixin as well as other base classes through multiple inheritance. All instances of that class will have a ‘log’ property that returns a logging.Logger named after their respective <module>.<class>. For example:
>>> class BaseClass(object): ... pass >>> class MyClass(LogMixin, BaseClass): ... pass >>> a = MyClass() >>> isinstance(a.log, logging.Logger) True >>> print(a.log.name) fontTools.misc.loggingTools.MyClass >>> class AnotherClass(MyClass): ... pass >>> b = AnotherClass() >>> isinstance(b.log, logging.Logger) True >>> print(b.log.name) fontTools.misc.loggingTools.AnotherClass
-
property
log
¶
-
property
-
class
fontTools.misc.loggingTools.
Timer
(logger=None, msg=None, level=None, start=None)[source]¶ Keeps track of overall time and split/lap times.
>>> import time >>> timer = Timer() >>> time.sleep(0.01) >>> print("First lap:", timer.split()) First lap: ... >>> time.sleep(0.02) >>> print("Second lap:", timer.split()) Second lap: ... >>> print("Overall time:", timer.time()) Overall time: ...
Can be used as a context manager inside with-statements.
>>> with Timer() as t: ... time.sleep(0.01) >>> print("%0.3f seconds" % t.elapsed) 0... seconds
If initialised with a logger, it can log the elapsed time automatically upon exiting the with-statement.
>>> import logging >>> log = logging.getLogger("my-fancy-timer-logger") >>> configLogger(logger=log, level="DEBUG", format="%(message)s", stream=sys.stdout) >>> with Timer(log, 'do something'): ... time.sleep(0.01) Took ... to do something
The same Timer instance, holding a reference to a logger, can be reused in multiple with-statements, optionally with different messages or levels.
>>> timer = Timer(log) >>> with timer(): ... time.sleep(0.01) elapsed time: ...s >>> with timer('redo it', level=logging.INFO): ... time.sleep(0.02) Took ... to redo it
It can also be used as a function decorator to log the time elapsed to run the decorated function.
>>> @timer() ... def test1(): ... time.sleep(0.01) >>> @timer('run test 2', level=logging.INFO) ... def test2(): ... time.sleep(0.02) >>> test1() Took ... to run 'test1' >>> test2() Took ... to run test 2
-
default_format
= 'Took %(time).3fs to %(msg)s'¶
-
default_msg
= 'elapsed time: %(time).3fs'¶
-
-
fontTools.misc.loggingTools.
configLogger
(**kwargs)[source]¶ Do basic configuration for the logging system. This is more or less the same as logging.basicConfig with some additional options and defaults.
The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the DEFAULT_FORMATS strings, and add the handler to the top-level library logger (“fontTools”).
A number of optional keyword arguments may be specified, which can alter the default behaviour.
- logger Specifies the logger name or a Logger instance to be configured.
(it defaults to “fontTools” logger). Unlike basicConfig, this function can be called multiple times to reconfigure a logger. If the logger or any of its children already exists before the call is made, they will be reset before the new configuration is applied.
- filename Specifies that a FileHandler be created, using the specified
filename, rather than a StreamHandler.
- filemode Specifies the mode to open the file, if filename is specified
(if filemode is unspecified, it defaults to ‘a’).
- format Use the specified format string for the handler. This argument
also accepts a dictionary of format strings keyed by level name, to allow customising the records appearance for specific levels. The special ‘*’ key is for ‘any other’ level.
datefmt Use the specified date/time format. level Set the logger level to the specified level. stream Use the specified stream to initialize the StreamHandler. Note
that this argument is incompatible with ‘filename’ - if both are present, ‘stream’ is ignored.
- handlers If specified, this should be an iterable of already created
handlers, which will be added to the logger. Any handler in the list which does not have a formatter assigned will be assigned the formatter created in this function.
- filters If specified, this should be an iterable of already created
filters, which will be added to the handler(s), if the latter do(es) not already have filters assigned.
- propagate All loggers have a “propagate” attribute initially set to True,
which determines whether to continue searching for handlers up the logging hierarchy. By default, this arguments sets the “propagate” attribute to False.