scriptharness.log module

The goal of full logging is to be able to debug problems purely through the log.



the default name to use for logging.getLogger()



default logging date format



default logging format



default logging level

class scriptharness.log.LogMethod(func=None, **kwargs)

Bases: object

Wrapper decorator object for logging and error detection. This is here as a shortcut to wrap functions with basic logging.



contains the config defaults that can be overridden via __init__ kwargs. Changing default_config directly may carry over to other decorated LogMethod functions!

__call__(func, *args, **kwargs)

Wrap the function call as a decorator.

When there are decorator arguments, __call__ is only called once, at decorator time. args and kwargs only show up when func is called, so we need to create and return a wrapping function.

  • func (function) – this is the decorated function.
  • *args – the args from the wrapped function call.
  • **kwargs – the kwargs from the wrapped function call.
default_config = {u'post_success_msg': u'%(func_name)s completed.', u'error_level': 40, u'post_failure_msg': u'%(func_name)s failed.', u'logger_name': u'scriptharness.{func_name}', u'level': 20, u'pre_msg': u'%(func_name)s arguments were: %(args)s %(kwargs)s', u'exception': None, u'detect_error_cb': None}

Log the success message until we get an error detection callback.

This method is split out for easier subclassing.


Log the function call before proceeding.

This method is split out for easier subclassing.


Create a replacement dictionary to format strings.

The log messages in pre_func() and post_func() require some additional info. Specify that info in the replacement dictionary.

Currently, set the following:

func_name: self.func.__name__
*args: the args passed to self.func()
**kwargs: the kwargs passed to self.func()

After running self.func, we’ll also set return_value.

class scriptharness.log.OutputBuffer(logger, pre_context_lines, post_context_lines)

Bases: object

Buffer output for context lines: essentially, an error_check can set the level of X lines in the past or Y lines in the future. If multiple error_checks set the level for a line, currently the higher level wins.

For instance, if a make: *** [all] Error 2 sets the level to logging.ERROR for 10 pre_context_lines, we’ll need to buffer at least 10 lines in case we hit that error. If a second error_check sets the level to logging.WARNING 5 lines above the make: *** [all] Error 2, the ERROR wins out, and that line is still marked as an ERROR.

This restricts the buffer size to pre_context_lines. In years past I’ve also ordered Visual Studio output by thread, and set the error all the way up until we match some other pattern, so the buffer had to grow to an arbitrary size. Those could be represented by separate classes/subclasses if needed.

add_line(level, line, *args, **kwargs)

Add a line to the buffer.

  • level (int) – the logging level for the line.
  • line (str) – the line to log
  • pre_context_lines (Optional[int]) – the number of lines before this one to set to log level level. This defaults to 0.
  • post_context_lines (Optional[int]) – the number of lines after this one to set to log level level. This defaults to 0.

Write all the buffered log lines to the log.


Pop num lines from the front of the buffer and log them at the level set for each line.

Parameters:num (Optional[int]) – The number of lines to pop and log. Defaults to 1.
update_buffer_levels(level, pre_context_lines)

Set the level for each buffer line to level if it’s higher than the existing level.

  • level (int) – The logging level to set the lines to
  • pre_context_lines (int) – The number of lines to affect. Since these are relative to the current line, these will be counted backwards from the end of the buffer.
class scriptharness.log.OutputParser(error_list, logger=None, **kwargs)

Bases: object

Helper object to parse command output.

add_buffer(level, messages, error_check=None)

Add the line to self.context_buffer if it exists, otherwise log it.

  • level (int) – logging level to log the line at
  • line (str) – line to log
  • error_check (Optional[dict]) – the error_check in error_list that first matched line, if applicable. Defaults to None.

parse a line and check if it matches one in error_list, if so then log it.

Parameters:line (str) – a line of output to parse.
class scriptharness.log.UnicodeFormatter(fmt=None, datefmt=None)

Bases: logging.Formatter

Subclass logging.Formatter to handle unicode strings in py2.



defaults to utf-8.

encoding = u'utf-8'
scriptharness.log.get_console_handler(formatter=None, logger=None, level=20)

Create a stream handler to add to a logger.

  • formatter (Optional[logging.Formatter]) – formatter to use for logs.
  • logger (Optional[logging logger]) – logger to add the file handler to.
  • level (Optional[int]) – logging level for the file.

logging.StreamHandler handler. This can be added to a logger via logger.addHandler(handler)

scriptharness.log.get_file_handler(path, level=20, formatter=None, logger=None, mode=u'w')

Create a file handler to add to a logger.

  • path (str) – the path to the logfile.
  • level (Optional[int]) – logging level for the file.
  • formatter (Optional[logging.Formatter]) – formatter to use for logs.
  • logger (Optional[logging logger]) – logger to add the file handler to.
  • mode (Optional[str]) – mode to open the file

handler – This can be added to a logger via logger.addHandler(handler)

Return type:


scriptharness.log.get_formatter(fmt=u'%(asctime)s %(levelname)8s - %(message)s', datefmt=u'%H:%M:%S')

Create a unicode-friendly formatter to add to logging handlers.

  • fmt (Optional[str]) – logging message format.
  • datefmt (Optional[str]) – date format for the log message.

UnicodeFormatter to add to a handler - handler.setFormatter(formatter)

scriptharness.log.prepare_simple_logging(path, mode=u'w', logger_name=u'', level=20, formatter=None)

Create a unicode-friendly logger.

By default it’ll create the root logger with a console handler; if passed a path it’ll also create a file handler. Both handlers will have a unicode-friendly formatter.

This function is intended to be called a single time. If called a second time, beware creating multiple console handlers or multiple file handlers writing to the same file.

  • path (Optional[str]) – path to the file log. If this isn’t set, don’t create a file handler. Default ‘’
  • mode (Optional[char]) – the mode to open the file log. Default ‘w’
  • logger_name (Optional[str]) – the name of the logger to use. Default ‘’
  • level (Optional[int]) – the level to log. Default DEFAULT_LEVEL
  • formatter (Optional[Formatter]) – a logging Formatter to use; to handle unicode, subclass UnicodeFormatter.

logger (Logger object). This is also easily retrievable via logging.getLogger(logger_name).