Handlers

Handlers are responsible for emitting the log record to a specific destination. All handlers within Burin are derived from the BurinHandler class.

One feature of all Burin handlers is the ability to set the handler’s log level when it is created. Every handler class has an optional level parameter for this so BurinHandler.set_level() doesn’t need to be called seperately. The default level for every handler is NOTSET.

Note

The handlers in the Burin library are not usable with the standard logging package, and vice-versa. Using logging handlers with Burin or Burin handlers with logging will cause issues and may result in exceptions or lost logs.

Below is a list of all handlers available within Burin. After that detailed descriptions of each handler is provided.

BurinBaseRotatingHandler

Base class for handlers that rotate log files.

BurinBufferingHandler

A handler that stores log records in a buffer.

BurinDatagramHandler

A handler that writes log records to a datagram socket.

BurinFileHandler

A handler for writing log records to a file.

BurinHandler

Handlers emit logging events to specific destinations.

BurinHTTPHandler

A handler that can send log records over HTTP to a Web server.

BurinMemoryHandler

A handler which buffers log records in memory.

BurinNTEventLogHandler

A handler which sends events to Windows NT Event Log.

BurinNullHandler

A handler that doesn't do any formatting or output any log records.

BurinQueueHandler

A handler that supports logging messages to a queue.

BurinQueueListener

Listens for and processes log records queued by BurinQueueHandler.

BurinRotatingFileHandler

A handler that rotates the file when it reaches a certain size.

BurinSMTPHandler

A handler that can send emails over SMTP for logging events.

BurinSocketHandler

A handler that writes pickled log records to a network socket.

BurinStreamHandler

A handler that writes log records to a stream.

BurinSyslogHandler

A handler that supports sending log records to a local or remote syslog.

BurinTimedRotatingFileHandler

A handler that rotates the file at specific intervals.

BurinWatchedFileHandler

A handler that watches for changes to the file.

BurinBaseRotatingHandler

This is the base rotating handler which can be used by any handlers that need to rotate files. This should not be used directly but instead can be inherited from to create custom handlers.

class burin.BurinBaseRotatingHandler(filename, mode, encoding=None, delay=False, errors=None, level='NOTSET')

Base class for handlers that rotate log files.

This is derived from BurinFileHandler.

This should not be instantiated directly except within a subclass __init__ method.

This will initialize the handler for outputting to a file.

Parameters:
  • filename (str | pathlib.Path) – The filename or path to write to.

  • mode (str) – The mode that the file is opened with.

  • encoding (str) – The text encoding to open the file with.

  • delay (bool) – Whether to delay opening the file until the first record is emitted. (Default = False)

  • errors (str) – Specifies how encoding errors are handled. See open() for information on the appropriate values.

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

do_rollover()

This method should perform the rotation of the file.

This should be implemented within a subclass and will only raise a NotImplementedError in this base class.

Raises:

NotImplementedError – As this is not implemented in the base class.

emit(record)

Emits the record to the file.

This will check if the file should be rotated by calling should_rollover and if that returns True it calls do_rollover to perform the actual rotation.

Parameters:

record (BurinLogRecord) – The log record to emit.

rotate(source, dest)

Rotate the current log.

This will call the rotator attribute of the handler, if it is callable, along with the source and destination. If the attribute isn’t callable (it defaults to None), then the source is simply renamed to the destination.

Note

Default rotation is done using os.replace() instead of os.rename() which is used in the standard logging.BaseRotatingHandler. This is so the renaming operation is more consistent across different platforms.

Parameters:
  • source (string | Path) – The source filename to rotate.

  • dest (string | Path) – The destination filename.

rotation_filename(defaultName)

Modifies the filename when rotating.

This is provided so that a method for customising filenames can be used during rotation.

If the namer attribute of the handler is callable then it is passed the defaultName and the resulting value is returned. If it is not callable then the defaultName value is returned unchanged.

Parameters:

defaultName (str) – The default name for the file.

Returns:

The name to be used for the file rotation.

Return type:

str

should_rollover(record)

This method should check if the rotation of the file should be done.

This should be implemented within a subclass and will only raise a NotImplementedError in this base class.

Note

The record parameter is needed for the BurinRotatingFileHandler, so to ensure the signature is the same all subclasses should include it whether they use it or not.

Parameters:

record (BurinLogRecord) – The log record. (Not used for all subclasses)

Raises:

NotImplementedError – As this is not implemented in the base class.

BurinBufferingHandler

This is a base buffering handler which can be used to create other handlers which require a buffering pattern. This should not be used directly but instead can be inherited from to create custom handlers.

class burin.BurinBufferingHandler(capacity, level='NOTSET')

A handler that stores log records in a buffer.

Each time a record is added to the buffer a check is done to see if the buffer should be flushed.

This class is intended to be subclassed by other handlers that need to use a buffering pattern and should not be instantiated directly except within a subclass __init__ method.

The buffer will flush once capacity number of records are stored.

Parameters:
  • capacity (int) – The number of log records to hold in the buffer before flushing.

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

close()

Closes the handler and flush the buffer.

emit(record)

Emits a log record.

This appends the record to the buffer. Then this checks if the handler should flush, and if so flushes.

Parameters:

record (BurinLogRecord) – The log record to emit.

flush()

Flushes the handler’s buffer.

This should be overridden in subclasses to customise the flushing behaviour.

should_flush(record)

Checks if the handler should flush its buffer.

This will simply return whether the buffer is currently at or above capacity. This can be overridden in subclasses to perform other checks including ones that may use the provided record to make a determination.

Parameters:

record (BurinLogRecord) – The log record being handled. This is not used in this base class method.

Returns:

Whether the handler should flush its buffer.

Return type:

bool

BurinDatagramHandler

This handler can be used to send logs through a datagram socket to another Python application.

class burin.BurinDatagramHandler(host, port, pickleProtocol=4, level='NOTSET')

A handler that writes log records to a datagram socket.

The pickled data that is sent is just of the log records attribute dictionary (__dict__) so it can process the event in any way it needs and doesn’t require Burin to be installed.

This is derived from BurinSocketHandler.

Note

The default pickle protocol version used in BurinSocketHandler is different than what is used in logging.handlers.SocketHandler.

Since this is a subclass of the socket handler it is also impacted.

This should only cause issues if the receiving Python version is much older. However if needed the pickle protocol version used can be changed with the pickleProtocol parameter.

The make_log_record() function can be used on the receiving end to recreate the log record from the pickled data if desired.

The host and port will set address and family of socket used.

If port is specified as None then the socket family will be socket.AF_UNIX; otherwise the socket family is socket.AF_INET.

Parameters:
  • host (str) – The address of the host to communicate with.

  • port (int) – The port to communicate on.

  • pickleProtocol (int) – The pickle protocol version to use. (Default = 4)

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

make_socket()

Makes the UDP (socket.SOCK_DGRAM) socket.

The socket family will be either socket.AF_UNIX or socket.AF_INET depending on the address that was passed in during initialization.

Returns:

The UDP socket.

Return type:

socket.socket

send(msg)

Sends the pickled log record through the socket.

This will try to create the socket first if it hasn’t been created yet.

Parameters:

msg (str) – The pickled string of the log record.

BurinFileHandler

This handler allows for simply writing logs out to a file.

class burin.BurinFileHandler(filename, mode='a', encoding=None, delay=False, errors=None, level='NOTSET')

A handler for writing log records to a file.

This is derived from BurinStreamHandler.

This will setup the handler using the absolute file path.

The file that is opened will grow indefinitely while being logged to. If this isn’t desired consider using the BurinRotatingFileHandler or BurinTimedRotatingFileHandler instead.

Parameters:
  • filename (str | pathlib.Path) – The filename or path to write to.

  • mode (str) – The mode that the file is opened with. (Default = ‘a’)

  • encoding (str) – The text encoding to open the file with.

  • delay (bool) – Whether to delay opening the file until the first record is emitted. (Default = False)

  • errors (str) – Specifies how encoding errors are handled. See open() for information on the appropriate values.

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

close()

Flushes and closes the file.

emit(record)

Emits a log record to the file.

Parameters:

record (BurinLogRecord) – The log record to emit.

BurinHandler

This is the base handler class that all other handlers in Burin are derived from. This should not be used directly but instead can be inherited from to create custom handlers.

class burin.BurinHandler(level='NOTSET')

Handlers emit logging events to specific destinations.

Note

This functions almost identically to logging.Handler but has some minor changes that allow it to work within Burin. These changes shouldn’t impact normal usage when compared with the standard logging library.

This is not a subclass of logging.Handler and is not usable with the standard library logging module.

This is the base handler class for Burin and should not be used directly, but instead can be subclassed to create other handlers that work with Burin.

This will setup the basic instance values for the handler.

Typically this should be called within any subclasses __init__ method to ensure all required handler instance attributes are created.

Parameters:

level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

property name

The name of the handler.

acquire()

Acquires the handlers internal thread lock.

It is recommended to use a handler’s lock in a context manager using the with statement. The lock is simply accessible as BurinHandler.lock on any handler instance.

The BurinHandler.acquire() and BurinHandler.release() methods are primarily provided for improved compatibility with the standard library logging.Handler.

close()

Cleans up the handler.

This simply removes the handler from an internal library reference map, but any subclasses should ensure this is called in any overridden close() methods to ensure the reference to the handler is cleaned up.

create_lock()

Creates a re-entrant lock for the handler for threading protection.

The lock is available through the instance BurinHandler.lock attribute or it can be used with BurinHandler.acquire() and BurinHandler.release().

This lock can then be used by subclasses to serialize access to I/O or any other places where protection of the instance across threads may be needed.

This also registers the handler to reinitialize the lock after a fork as otherwise it could prevent logging through the handler if fork is called while the lock is held.

flush()

Meant to ensure that all logging output is flushed.

This is intended to be implemented within subclasses as needed; this method on the base class does not do anything.

format(record)

Formats the received log record.

If the handler doesn’t have a formatter a basic default formatter is used.

Parameters:

record (BurinLogRecord) – The log record to be formatted.

Returns:

The formatted text of the log record.

Return type:

str

handle(record)

Process the log record and possibly emit it.

This will check any filters that have been added to the handler and emit the record if no filters return False.

If the record passes all filters then the instance of the record that was emitted will be returned.

Note

In Python 3.12 the ability for this to return a record was added to the standard library; it is supported here for all versions of Python compatible with Burin (including versions below 3.12).

Parameters:

record (BurinLogRecord) – The log record to process.

Returns:

An instance of the record that was emitted, or False if the record was not emitted.

Return type:

BurinLogRecord | bool

handle_error(record)

Handles errors which may occur during an emit() call.

This should be called from subclasses when an exception is encountered during an emit() call.

If raiseExceptions is False then the error will be silently ignored. This can be useful for a logging system as most users would be more concerned with application errors vs logging library errors.

However if raiseExceptions is True then information about the error will be output to sys.stderr.

Parameters:

record (BurinLogRecord) – The log record that was being processed when the error occurred.

release()

Releases the handler’s internal thread lock.

It is recommended to use a handler’s lock in a context manager using the with statement. The lock is simply accessible as BurinHandler.lock on any handler instance.

The BurinHandler.acquire() and BurinHandler.release() methods are primarily provided for improved compatibility with the standard library logging.Handler.

set_formatter(fmt)

Sets the formatter to be used by this handler.

Parameters:

fmt (BurinFormatter) – The formatter to use.

set_level(level)

Sets the logging level of this handler.

Parameters:

level (int | str) – The new level for the handler.

BurinHTTPHandler

This handler can send logs to another service using HTTP.

class burin.BurinHTTPHandler(host, url, method='GET', secure=False, credentials=None, context=None, level='NOTSET')

A handler that can send log records over HTTP to a Web server.

Note

This has the BurinHTTPHandler.get_connection() method (also aliased as BurinHTTPHandler.getConnection()); this was added to the standard library in Python 3.9 but is available here for all Python versions supported by Burin.

This will setup the handler and do some basic checks of parameters.

Only ‘GET’ or ‘POST’ are allowed as method. Also context must be None if secure is False.

Parameters:
  • host (str) – The host to connect to; this can be in the form of ‘host:port’ if non-standard HTTP/HTTPS ports are to be used.

  • url (str) – The URL path on the host to use.

  • method (str) – The HTTP method to use for the request. This must be either ‘GET’ or ‘POST’. (Default = ‘GET’)

  • secure (bool) – Whether to use HTTPS or not. (Default = False)

  • credentials (tuple(str, str)) – If authentication is needed for the host then this should be a 2-tuple of (username, password). This will be placed into an HTTP ‘Authorization’ header for Basic Authentication support. If this is used you should also use secure*=**True* so that the username and password are not sent in cleartext to the host.

  • context (ssl.SSLContext) – A ssl.SSLContext instance to configured settings for an HTTPS connection. This must be None if secure*=**False*.

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

Raises:

ValueError – If method is not ‘GET’ or ‘POST’, or context is not None and secure*=**False*.

emit(record)

Emits a log record.

This will send the record to a web server using a percent-encoded dictionary.

Parameters:

record (BurinLogRecord) – The log record to emit.

get_connection(host, secure)

Gets the HTTP or HTTPS connection.

This can be overridden to change how the connection is created; for example if a proxy is required.

Note

In Python 3.9 logging.handlers.HTTPHandler added this undocumented method. It is available here for all versions of Python compatible with Burin (including versions below 3.9).

Parameters:
  • host (str) – The host to connect to.

  • secure (bool) – Whether to use HTTPS or not.

Returns:

The connection object.

Return type:

http.client.HTTPConnection | http.client.HTTPSConnection

map_log_record(record)

Default mapping of log record to dictionary for CGI data.

This can be overridden in subclasses to customise the record map format.

Parameters:

record (BurinLogRecord) – The log record being handled.

Returns:

A map of the record properties and values.

Return type:

dict{str: Any}

BurinMemoryHandler

This handler can buffer logs in memory until a specified capacity is reached.

class burin.BurinMemoryHandler(capacity, flushLevel='ERROR', target=None, flushOnClose=True, level='NOTSET')

A handler which buffers log records in memory.

This is derived from BurinBufferingHandler.

This handler will flush when the buffer reaches the specified capacity or when a record of the specified flushLevel or above is emitted.

The target handler will be called when this flushes its buffer.

Parameters:
  • capacity (int) – The number of log records to hold in the buffer before flushing.

  • flushLevel (int | str) – If a log record of this level is put in the buffer it will immediately flush the whole buffer. (Default = ‘ERROR’)

  • target (BurinHandler) – The handler which is called with the log records when the buffer is flushed.

  • flushOnClose (bool) – Whether the buffer should be flushed when the handler is closed. (Default = True)

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

close()

Closes the handler.

This will also flush the buffer if flushOnClose was True when the handler was initialized.

flush()

This sends the memory handler’s buffered records to the target handler.

If there is no current target handler this will not do anything.

set_target(target)

Sets the target handler for this handler.

Parameters:

target (BurinHandler) – The target handler to flush to when this handler’s buffer is full or should be flushed.

should_flush(record)

Checks the level and buffer size for if the buffer should be flushed.

This will determine if the buffer should be flushed based on either the current size of the buffer and also the record level.

Parameters:

record (BurinLogRecord) – The log record being handled.

Returns:

Whether the buffer should be flushed.

Return type:

bool

BurinNTEventLogHandler

This handler can log to the Windows event log; this requires the pywin32 package.

class burin.BurinNTEventLogHandler(appname, dllname=None, logtype='Application', level='NOTSET')

A handler which sends events to Windows NT Event Log.

To use this handler you must be on a Windows system and have the pywin32 package installed.

This sets the application name and allows using a specific dll.

During initialization this will try to import the win32evtlogutil and win32evtlog modules from the pywin32 package. If this fails it will print a message to stdout and the handler that is created will not log anything.

A registry entry for the appname will be created. Also if dllname is None then win32service.pyd is used. This can cause the resulting event logs to be quite large, so you can specify a different dllname with the message definitions you want to use.

Parameters:
  • appname (str) – The name of the application which will be added to the registry.

  • dllname (str) – Specify a dll to use other than win32service.pyd.

  • logtype (str) – The log type used to register the event logs.

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

close()

Closes the handler.

emit(record)

Emits a log record.

This will get the message ID, event category, and event type, then it will log the message to the NT event log.

Note

If the win32evtlogutil could not be imported during handler initialization then this will not do anything.

Parameters:

record (BurinLogRecord) – The log record to emit.

get_event_category(record)

Returns the event category for the record.

This can be overidden to specify a category, by default this just returns 0.

Parameters:

record (BurinLogRecord) – The log record being handled. This is not used in this basic method implementation.

Returns:

The event category for the record.

Return type:

int

get_event_type(record)

Returns the event type for the record.

A basic mapping of the standard log levels to Win32 event log types is used for this. If you are using your own log levels or want to customise this process you can either override the typemap property of the handler, or override this method.

Parameters:

record (BurinLogRecord) – The log record being handled.

Returns:

The Win32 event log type for the record. If the log record’s level does not map to a type this will return the ERROR type.

Return type:

int

get_message_id(record)

Return the message ID for the record.

This returns 1 be default which is the base message ID in win32service.pyd. This can be changed or customised by overriding this method and crafting your log messages or records in a specific way to allow a lookup for each ID.

Parameters:

record (BurinLogRecord) – The log record being handled.

Returns:

The event message ID for the log record.

Return type:

int

BurinNullHandler

This handler doesn’t do anything, but can be used to ensure a logger has a configured handler that doesn’t actually output to anything (not even sys.stderr). This may be useful in libraries where you want to use Burin if it’s available, but want to let the application configure the output handlers.

class burin.BurinNullHandler(level='NOTSET')

A handler that doesn’t do any formatting or output any log records.

This is essentially meant as a no-op handler to be used when you need a handler to be attached to a logger, but don’t want any output.

create_lock()

Does not actually create a lock; this will set self.lock to None.

emit(record)

Does not emit anything.

Parameters:

record (BurinLogRecord) – This is not emitted to anything; it is only here so the signature matches other handlers.

handle(record)

Does no processing or handling of the record.

Parameters:

record (BurinLogRecord) – This is not processed in any way; it is only here so the signature matches other handlers.

BurinQueueHandler

This handler adds all logs to a queue which a BurinQueueListener can then process. This can be useful in a multiprocess application to have one process handle all of the actual logging (and I/O involved) while the others just add to the queue.

class burin.BurinQueueHandler(queue, level='NOTSET')

A handler that supports logging messages to a queue.

This can be used along with BurinQueueListener to allow one process or thread in a program handle logging output which may consist of slow operations like file writing or sending emails. This can be useful in Web or service applications where responsiveness is important in worker processes and threads.

Logs records are added to the queue by each BurinQueueHandler and then processed and output by the BurinQueueListener.

This will initialize the handler and set the queue to use.

Parameters:
emit(record)

Emits a log record.

This will prepare the record and then add it to the queue.

Parameters:

record (BurinLogRecord) – The log record to emit.

enqueue(record)

Enqueues a log record.

This uses put_nowait on the queue to add the record. If blocking, timeoutes, or custom queueing is required this should be overridden.

Parameters:

record (BurinLogRecord) – The log record being handled.

prepare(record)

Prepares a log record for queueing.

This will format the record and remove any unpickleable elements from it. Both the message and msg properties of the record will be set to the same value and args, kwargs, exc_info, exc_text, and stack_info will all be set to None.

Note

This makes a copy of the record instead of altering the original one. This way other handlers in the chain will still be able to process the original record.

This can be overidden to change how the record is prepared. For example to convert the record into some other format, or to create a copy of the record for enqueueing while keeping the original.

Parameters:

record (BurinLogRecord) – The log record to prepare for enqueueing.

Returns:

The record prepared for enqueueing.

Return type:

BurinLogRecord

BurinQueueListener

This can be paired with BurinQueueHandler to have one process for a queue of logs which multiple handlers add to.

class burin.BurinQueueListener(queue, *handlers, respect_handler_level=False)

Listens for and processes log records queued by BurinQueueHandler.

Note

This is a subclass of logging.handlers.QueueListener and is just a stub class to provide a matching listener for BurinQueueHandler.

This can be used along with BurinQueueHandler so that log processing and output, which may consist of slow operations like file writing or sending emails, can be done outside of worker processes or threads where responsiveness may be important.

BurinRotatingFileHandler

This handler can automatically rotate a log file when it reaches a specific size.

class burin.BurinRotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False, errors=None, level='NOTSET')

A handler that rotates the file when it reaches a certain size.

This is derived from BurinBaseRotatingHandler.

The file is rotated once it reaches a specific size. A limit can also be placed on how many rotated files are kept.

This will initialize the handler to write to the file.

The file will be rotated when it reaches maxBytes size. The number of rotated files to keep is set by backupCount.

When the files are rotated a number is appended to the filename in the order ‘.1’, ‘.2’, ‘.3’, etc. until the backupCount is reached. So a backupCount of 5 will result in 5 files other than the active log file being kept up to ‘filename.5’. Once backupCount is reached the next time a rotate happens the oldest file will be removed.

The active log file set with filename is always the file being written to.

Parameters:
  • filename (str | pathlib.Path) – The filename or path to write to.

  • mode (str) – The mode that the file is opened with. This should be ‘a’ in almost all use cases. If ‘w’ is in the mode and maxBytes != 0 then it will be replaced with ‘a’ as otherwise the file will be truncated every time the program runs which is counter-intuitive to a rotating log file. (Default = ‘a’)

  • maxBytes (int) – The maximum size (in bytes) the file can be before a rotation happens. The rotation happens before an emit so the file should never go above this size. If this is 0 then the file will never be rotated. (Default = 0)

  • backupCount (int) – How many rotated log files to keep. If this is 0 then the file will not be rotated. (Default = 0)

  • encoding (str) – The text encoding to open the file with.

  • delay (bool) – Whether to delay opening the file until the first record is emitted. (Default = False)

  • errors (str) – Specifies how encoding errors are handled. See open() for information on the appropriate values.

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

do_rollover()

Does the rollover of the file.

Note

This uses os.replace() instead of the combination of os.remove() and os.rename() from the standard logging library.

Functionally this should be the same, but it simplifies the operation slightly.

should_rollover(record)

Determines if a file rollover should occur.

This uses the supplied record to check if the file would exceed the size limit that has been set.

Parameters:

record (BurinLogRecord) – The log record being handled.

Returns:

Whether a file rotation should occur as the new record would put the file past the size limit.

Return type:

bool

BurinSMTPHandler

This handler can send logs through email using a SMTP server.

class burin.BurinSMTPHandler(mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None, timeout=5.0, level='NOTSET')

A handler that can send emails over SMTP for logging events.

This requires an email server that you have permission to send emails through; it cannot be used standalone to send directly to a receiving server.

This will initialize the handler for sending emails.

The standard SMTP port from smtplib.SMTP_PORT is used by default; if you need to use a non-standard port then mailhost must be a tuple in the form of (host, port).

You can send to multiple recipients by passing a list of addresses to toaddrs.

If your SMTP server requires authentication then credentials should be a list or tuple in the form of (username, password). If you are sending credentials then secure should not be None to prevent them being sent unencrypted.

Note

Unlike the standard logging.handlers.SMTPHandler you can use secure even without credentials. This will at least send the message over a connection using STARTTLS.

Also burin allows secure to be a ssl.SSLContext instead of just a tuple with optional keyfile and certfile as these are deprecated in the smtplib.SMTP.starttls() call.

Parameters:
  • mailhost (str | tuple(str, int)) – The SMTP server to connect to and send mail through. By default the standard SMTP port is used; if you need to use a custom port this should be a tuple in the form of (host, port).

  • fromaddr (str) – The address that the email is sent from.

  • toaddrs (list[str] | str) – The recipient email addresses. This can be a single address or a list of multiple addresses.

  • subject (str) – The subject line of the email.

  • credentials (tuple(str, str)) – If the SMTP server requires authentication you can pass a tuple here in the form (username, password).

  • secure (tuple) – If this is set to a tuple or a ssl.SSLContext it will enable STARTTLS encryption for the connection to the SMTP server. It is recommended to use a ssl.SSLContext as the keyfile and certfile params for smtplib.SMTP.starttls() are deprecated. However, If using a tuple it can follow one of three forms, an empty tuple (), a single value tuple with the name of a keyfile (keyfile,), or a 2-value tuple with the names of a keyfile and certificate file (keyfile, certfile). This is then passed to smtplib.SMTP.starttls().

  • timeout (float | int) – A timeout (in seconds) for communications with the SMTP server.

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

emit(record)

Emits a log record.

This will format the log record, prepare the email message, and then send the message.

Parameters:

record (BurinLogRecord) – The log record to emit.

get_subject(record)

Gets the subject for the mail.

This just returns the subject value; however this class can be overridden to determine subject based on the record.

Parameters:

record (BurinLogRecord) – The log record being handled. This is not used in this basic method implementation.

Returns:

The subject for the mail.

Return type:

str

BurinSocketHandler

This handler can send pickled log records through a socket to another Python application.

class burin.BurinSocketHandler(host, port, pickleProtocol=4, level='NOTSET')

A handler that writes pickled log records to a network socket.

Note

This has a change from the logging.handlers.SocketHandler that may be incompatible depending on the receiver’s Python version.

The default pickle protocol version used is 4 instead of 1; this can be configured though by the pickleProtocol parameter which was added.

The pickled data that is sent is just of the log records attribute dictionary (__dict__) so it can process the event in any way it needs and doesn’t require Burin to be installed.

The make_log_record() function can be used on the receiving end to recreate the log record from the pickled data if desired.

This will set the host and port for the socket to connect to.

Parameters:
  • host (str) – The address of the host to communicate with.

  • port (int) – The port to communicate on.

  • pickleProtocol (int) – The pickle protocol version to use. (Default = 4)

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

close()

Closes and handler and the socket.

create_socket()

Tries creating the socket.

If creation of the socket fails this will use a progressively greater period of time to retry creation up to BurinSocketHandler.retryMax (default 30 seconds).

emit(record)

Emits a log record.

This will pickle the record and then send it through the socket.

Parameters:

record (BurinLogRecord) – The log record to emit.

handle_error(record)

Handles errors which may occur during an emit() call.

This wile close the socket if self.closeOnError*=**True*; it then calls BurinHandler.handle_error() to continue with the error handling.

Parameters:

record (BurinLogRecord) – The log record that was being processed when the error occurred.

make_pickle(record)

Pickles the record in a binary format.

This prepares the record for transmission across the socket.

Parameters:

record (BurinLogRecord) – The log record to pickle.

Returns:

The pickled representation of the record.

Return type:

bytes

make_socket(timeout=1)

Makes the socket that is used for the connection.

If BurinSocketHandler.port is not None then this will make a TCP socket, otherwise it will create a UNIX socket.

Parameters:

timeout (int) – The timeout to configure for the socket.

Returns:

The socket that was created.

Return type:

socket.socket

Raises:

OSError – If making a UNIX socket fails.

send(pickledRecord)

Sends the specified pickled record to the socket.

Note

The parameter for this has been renamed from s to pickledRecord compared to logging.handlers.SocketHandler.send(). This is not a keyword arg and therefore this shouldn’t have an impact on any functionality.

This will try to create the socket before sending if it hasn’t been made yet.

Parameters:

pickledRecord (bytes) – The pickled log record to send over the socket.

BurinStreamHandler

This handler can write logs to an I/O stream.

class burin.BurinStreamHandler(stream=None, level='NOTSET')

A handler that writes log records to a stream.

Note

This handler will not close the stream it is writing to as sys.stdout and sys.stderr are commonly used.

This initializes the handler and sets the stream to use.

If stream is None then sys.stderr is used by default.

Parameters:
  • stream (io.TextIOBase) – The stream to log to. If this is None then sys.stderr is used.

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

emit(record)

Emits a log record.

This will format and then write the record to the stream with a trailing newline. The newline character is whatever the BurinStreamHandler.terminator property is set to (default \n).

Parameters:

record (BurinLogRecord) – The log record to emit.

Raises:

RecursionError – This is to prevent an interpreter crash if a recursion error is raised. See Python #36272

flush()

Flushes the stream.

set_stream(stream)

Sets the stream for the handler to write to.

This will return the previous stream if the stream has changed, or None if the new stream is the same or there was no previous stream.

Note

This will flush the previous stream before assigning the new one.

Parameters:

stream (io.TextIOBase) – The stream the handler will write to.

Returns:

The previous stream or None if both streams are the same or there was no previous stream.

Return type:

io.TextIOBase | None

BurinSyslogHandler

This handler can write logs out using Syslog.

class burin.BurinSyslogHandler(address=('localhost', 514), facility=1, socktype=None, level='NOTSET')

A handler that supports sending log records to a local or remote syslog.

Note

Unlike the standard library handler the ‘l’ in ‘Syslog’ of the class name is not capitalized so this class better matches the actual ‘Syslog’ name.

The mapPriority method and priority_map property from logging.handlers.SysLogHandler is also not included as they have not been needed for mapping to lowercase levels for a while.

This initializes the handler and sets it for sending to syslog.

By default the handler will try to use a local syslog through UDP port 514. To change this address must be set as a tuple in the form (host, port); or to use a UNIX socket as a string that is a file system location. A bytes-like object can also be used as this may represent addresses in Linux’s abstract namespace.

By default a UDP connection is created; if TCP is needed ensure socktype is set to socket.SOCK_STREAM.

Parameters:
  • address (tuple(str, int) | str | bytes | bytearray | array.array) – The address to connect to syslog at. This should be a tuple in the form of (host, port) for an INET socket; or for a UNIX socket a string to a filesystem path or a bytes-like object (such as for Linux’s abstract namespace addresses). (Default = (‘localhost’, 514))

  • facility (int) – The syslog facility to use. These are available as class attributes on the handler to simplify usage. (Default = 1 (LOG_USER))

  • socktype (int) – The socket type to use for the connection to syslog. By default a socket.SOCK_DGRAM socket is used if this is None; for TCP connections specify socket.SOCK_STREAM.

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

close()

Closes the handler and the syslog socket.

create_socket()

Try to create a socket and, if not datagram, connect to the other end.

This will be called automatically during initialization of the handler. If it fails to connect at this point it is not considered an error. The method will be called again when emitting an event if there is still no socket connected.

Note

In Python 3.11 logging.handlers.SysLogHandler.createSocket() was added to the standard library; it is supported here for all versions of Python compatible with Burin (including versions below 3.11).

emit(record)

Emits a log record to the Syslog socket.

The log record will be formatted and sent to the Syslog server. If exception information is present in the log record it will NOT be sent along to the server.

Note

If a socket connection was not established earlier this will attempt to create it again before emitting the record. This functionality was added in the Python 3.11 standard library and is supported here for all versions of Python compatible with Burin (including versions below 3.11)

Parameters:

record (BurinLogRecord) – The log record to emit.

encode_priority(facility, priority)

Encodes the facility and priority.

Either strings or integers can be used for the facility and priority values, these will be mapped into the single 32-bit value used by Syslog.

Parameters:
  • facility (int | str) – The facility for Syslog to log the record as.

  • priority (int | str) – The priority for Syslog to log the record with.

Returns:

The single 32-bit value for Syslog encoded with the facility and priority.

Return type:

int

BurinTimedRotatingFileHandler

This handler can rotate log files based on a timing pattern.

class burin.BurinTimedRotatingFileHandler(filename, when='H', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None, errors=None, level='NOTSET')

A handler that rotates the file at specific intervals.

This is derived from BurinBaseRotatingHandler.

The file is rotated once at the specified interval. A limit can also be placed on how many rotated files are kept.

This will initialize the handler to write to the file.

The file will be rotated based on the when, interval, and atTime values. The number of rotated files to keep is set by backupCount.

when

Interval type

atTime usage

‘S’

Seconds

Ignored

‘M’

Minutes

Ignored

‘H’

Hours

Ignored

‘D’

Days

Ignored

‘W0’-‘W6’

Weeks
Weekday (0 = Monday)

Time of the day to rotate, default is midnight

‘MIDNIGHT’

Days
Midnight or atTime

Time of the day to rotate, default is midnight

If using a weekday W0-W6 value for when then the interval will be how many weeks between the rotation is desired. Whereas if MIDNIGHT is used then the interval is how many days between rotation at either midnight or the specified time.

When the files are rotated a time and/or date is appended to the filename until the backupCount is reached. The time.strftime() format %Y-%m-%d_%H-%M-%S is used with later parts stripped off when not relevant for the rotation interval selected. Once backupCount is reached the next time a rotate happens the oldest file will be removed.

The rotation interval is calculated (during initialization) based on the last modification time of the log file, or the current time if the file doesn’t exist, to determine when the next rotation will occur.

Note

Rotation intervals for this class treat midnight as the beginning of the day, and not the end of it. This differs from the standard logging.handlers.TimedRotatingFileHandler.

For example if the current time is a Tuesday (W1) and when is set to Wednesday (W2) without a specific atTime; then the next rotation will occur on the next logging event after 00:00 of Wednesday; not 00:00 of Thursday (as the standard library does)

The active log file set with filename is always the file being written to.

Note

In Python 3.9 the errors parameter was adder to logging.handlers.TimedRotatingFileHandler. This is available here for all versions of Python compatible with Burin (including versions below 3.9).

Parameters:
  • filename (str | pathlib.Path) – The filename or path to write to.

  • when (str) – The type of interval to use when calculating the rotation. Use the table above to see the available options and how they impact the rotation interval. (Default = ‘H’)

  • interval (int) – The interval to use for the file rotation. Use the table above to see how this is used in determining the rotation interval. (Default = 1)

  • backupCount (int) – How many rotated log files to keep. If this is 0 then the file will not be rotated. (Default = 0)

  • encoding (str) – The text encoding to open the file with.

  • delay (bool) – Whether to delay opening the file until the first record is emitted. (Default = False)

  • utc (bool) – Whether to use UTC time or local time. (Default = False)

  • atTime (datetime.time) – The time to use for weekday or ‘midnight’ (daily at set time) rotations. Use the table above to see how this is used in determining the rotation interval.

  • errors (str) – Specifies how encoding errors are handled. See open() for information on the appropriate values.

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

compute_rollover(currentTime)

Determines the rollover time.

This will used the specified time to determine the next rollover based on the interval set on the handler.

Parameters:

currentTime (int) – The current time to calculate the next rollover from.

Returns:

The next rollover time.

Return type:

int

do_rollover()

Does the rollover of the file.

This will append date-time to the filename of when the current interval started. This will also remove extra files over the backup count.

Note

The date-time appended to filenames where when is set to a weekday (W0-W6) or midnight may not be accurate for the first file created. This is because atTime - interval is unlikely to match the actual creation time for the first file.

get_files_to_delete()

Determines the files to delete when rolling over.

Returns:

A list of file paths to remove.

Return type:

list[str]

should_rollover(record)

Determines if a rollover should occur.

Note

The record parameter is not used, it is included to keep the method signatures the same for all subclasses of BurinBaseRotatingHandler

Note

In Python 3.11 logging.handlers.TimedRotatingFileHandler.shouldRollover() was changed to ensure that if the target is not currently a regular file the check is skipped and the next one is scheduled. Previously checks simply ran and failed repeatedly. This change is incorporated here for all versions of Python compatible with Burin (including versions below 3.11).

Parameters:

record (BurinLogRecord) – The log record. (Not used)

Returns:

Whether a rollover is scheduled to occur.

Return type:

bool

BurinWatchedFileHandler

This handler watches the file it is writing to and will close and reopen it automatically if it detects any changes.

class burin.BurinWatchedFileHandler(filename, mode='a', encoding=None, delay=False, errors=None, level='NOTSET')

A handler that watches for changes to the file.

If the file this is logging to changes it will close and then reopen the file.

This is intended for use on Unix/Linux systems and checks for device or inode changes. Such changes would occur if a program like logrotate was to rotate the file.

This should not be used on Windows and is not needed as log files are opened with exclusive locks and cannot be moved or renamed when in use.

This will setup the handler and stat the file.

Parameters:
  • filename (str | pathlib.Path) – The filename or path to write to.

  • mode (str) – The mode that the file is opened with. (Default = ‘a’)

  • encoding (str) – The text encoding to open the file with.

  • delay (bool) – Whether to delay opening the file until the first record is emitted. (Default = False)

  • errors (str) – Specifies how encoding errors are handled. See open() for information on the appropriate values.

  • level (int | str) – The logging level of the handler. (Default = ‘NOTSET’)

emit(record)

Emits the record to the file.

This will check if the file needs to be reopened before writing to it.

Parameters:

record (BurinLogRecord) – The log record to emit.

reopen_if_needed()

Reopens the log file if needed.

This checks if the underlying file has changed and if it has it closes and then reopens the file to get the current stream.