Logging tools

These tools allow log records and unhandled exceptions to be forwarded to a central log server. Basic usage consists of:

  1. Start a log server in any process using start_log_server().
  2. Attach a handler to the root logger (see Python logging documentation). If the log server is running in a process that can output to a terminal, then RPCLogHandler can be used to display log records color-coded by source.
  3. Set the log level of the root logger. Using INFO or DEBUG levels will reveal details about RPC communications between processes.
  4. In the remote process set the log level and call set_host_name(), set_process_name(), set_thread_name(), and set_logger_address() (note that ProcessSpawner handles this step automatically).
pyacq.core.rpc.log.start_log_server(logger)[source]

Create a global log server and attach it to a logger.

Use get_logger_address() to return the socket address for the server after it has started. On a remote process, call set_logger_address() to connect it to the server. Then all messages logged remotely will be forwarded to the server and handled by the logging system there.

class pyacq.core.rpc.log.LogServer(logger, address='tcp://127.0.0.1:*', sort=True)[source]

Thread for receiving log records via zmq socket.

Messages are immediately passed to a python logger for local handling.

Parameters:
logger : Logger

The python logger that should handle incoming messages.

run()[source]

Method representing the thread’s activity.

You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.

class pyacq.core.rpc.log.LogSender(address=None, logger=None)[source]

Handler for forwarding log messages to a remote LogServer via zmq socket.

Instances of this class can be attached to any python logger using logger.addHandler(log_sender).

This can be used with LogServer to collect log messages from many remote processes to a central logger.

Note: We do not use RPC for this because we have to avoid generating extra log messages.

Parameters:
address : str | None

The socket address of a log server. If None, then the sender is not connected to a server and connect() must be called later.

logger : str | None

The name of the python logger to which this handler should be attached. If None, then the handler is not attached (use ‘’ for the root logger).

close()[source]

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.

connect(addr)[source]

Set the address of the LogServer to which log messages should be sent. This value should be acquired from log_server.address or get_logger_address().

handle(record)[source]

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.

class pyacq.core.rpc.log.RPCLogHandler(stream=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>)[source]

StreamHandler that sorts incoming log records by their creation time and writes to stderr. Messages are also colored by their log level and the host/process/thread that created the record.

Credit: https://gist.github.com/kergoth/813057

Parameters:
stream : file-like

The stream to which messages should be sent. The default is sys.stderr.

pyacq.core.rpc.log.log_exceptions()[source]

Install a hook that creates log messages from unhandled exceptions.

pyacq.core.rpc.log.set_host_name(name)[source]

Set the name of this host used for logging.

pyacq.core.rpc.log.get_host_name()[source]

Return the name of this host used for logging.

pyacq.core.rpc.log.set_process_name(name)[source]

Set the name of this process used for logging.

pyacq.core.rpc.log.get_process_name()[source]

Return the name of this process used for logging.

pyacq.core.rpc.log.set_thread_name(name, tid=None)[source]

Set the name of a thread used for logging.

If no thread ID is given, then the current thread’s ID is used.

pyacq.core.rpc.log.get_thread_name(tid=None)[source]

Return the name of a thread used for logging.

If no thread ID is given, then the current thread’s ID is used.

pyacq.core.rpc.log.set_logger_address(addr)[source]

Set the address to which all log messages should be sent.

This function creates a global LogSender and attaches it to the root logger.

pyacq.core.rpc.log.get_logger_address()[source]

Return the address of the LogServer used by this process.

If a LogServer has been created in this process, then its address is returned. Otherwise, the last address set with set_logger_address() is used.