logstool

Logging Engines

Author: Jacek Kotlarski –<szumak@virthost.pl> Created: 2023-10-10

Purpose: Implement logging engines targeting stdout, stderr, files, and syslog.

Each engine adheres to ILoggerEngine, providing consistent send semantics while supporting optional formatters and buffering behaviour.

class jsktoolbox.logstool.engines.LoggerEngineStdout(name=None, formatter=None, buffered=False)[source]

Bases: ILoggerEngine, BLoggerEngine, BData, NoDynamicAttributes

Emit formatted log records to standard output.

Parameters:
__init__(name=None, formatter=None, buffered=False)[source]

Initialise stdout engine state.

### Arguments: * name: Optional[str] - Logger name injected into formatted messages. * formatter: Optional[BLogFormatter] - Formatter applied prior to emission. * buffered: bool - When False, flush the stream after each message.

### Returns: None - Constructor.

Parameters:
Return type:

None

property name: str | None

Return the configured application name.

### Returns: [Optional[str]] - Application name value or None.

send(message)[source]

Write the message to stdout honoring buffering/formatting rules.

### Arguments: * message: str - Raw log payload.

### Returns: None - Output is written to stdout.

Parameters:

message (str)

Return type:

None

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

class jsktoolbox.logstool.engines.LoggerEngineStderr(name=None, formatter=None, buffered=False)[source]

Bases: ILoggerEngine, BLoggerEngine, BData, NoDynamicAttributes

Emit formatted log records to standard error.

Parameters:
__init__(name=None, formatter=None, buffered=False)[source]

Initialise stderr engine state.

### Arguments: * name: Optional[str] - Logger name injected into formatted messages. * formatter: Optional[BLogFormatter] - Formatter applied prior to emission. * buffered: bool - When False, flush the stream after each message.

Parameters:
Return type:

None

property name: str | None

Return the configured application name.

### Returns: [Optional[str]] - Application name value or None.

send(message)[source]

Write the message to stderr honoring buffering/formatting rules.

### Arguments: * message: str - Raw log payload.

### Returns: None - Output is written to stderr.

Parameters:

message (str)

Return type:

None

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

class jsktoolbox.logstool.engines.LoggerEngineFile(name=None, formatter=None, buffered=False)[source]

Bases: ILoggerEngine, BLoggerEngine, BData, NoDynamicAttributes

Append formatted log records to files stored on disk.

Supports optional size-based rotation with numbered suffixes when configured.

Parameters:
__init__(name=None, formatter=None, buffered=False)[source]

Initialise file engine configuration.

### Arguments: * name: Optional[str] - Logger name injected into formatted messages. * formatter: Optional[BLogFormatter] - Formatter applied prior to emission. * buffered: bool - When False, flush the stream after each message.

Parameters:
Return type:

None

property name: str | None

Return the configured application name.

### Returns: [Optional[str]] - Application name value or None.

send(message)[source]

Append the formatted message to the configured log file.

### Arguments: * message: str - Raw log payload.

### Returns: None - The file on disk is updated.

### Raises: * ValueError: Raised when logfile is not configured.

Parameters:

message (str)

Return type:

None

property logdir: str | None

Return configured log directory.

### Returns: Optional[str] - Directory path or None when unset.

property logfile: str | None

Return configured log file name.

### Returns: Optional[str] - File name or None when unset.

property rotation_max_bytes: int | None

Return the maximum file size before rotation triggers.

### Returns: Optional[int] - Size threshold in bytes; None disables rotation.

property rotation_backup_count: int

Return the number of rotated log archives retained.

### Returns: int - Number of archives; zero disables rotation.

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

class jsktoolbox.logstool.engines.LoggerEngineSyslog(name=None, formatter=None, buffered=False)[source]

Bases: ILoggerEngine, BLoggerEngine, BData, NoDynamicAttributes

Send formatted log records to the system syslog daemon.

Parameters:
__init__(name=None, formatter=None, buffered=False)[source]

Initialise syslog engine configuration.

### Arguments: * name: Optional[str] - Logger name injected into formatted messages. * formatter: Optional[BLogFormatter] - Formatter applied prior to emission. * buffered: bool - When False, flush the stream after each message.

Parameters:
Return type:

None

property name: str | None

Return the configured application name.

### Returns: [Optional[str]] - Application name value or None.

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

property facility: int

Return active syslog facility.

### Returns: int - Syslog facility value.

property level: int

Return active syslog level.

### Returns: int - Syslog level value.

send(message)[source]

Emit the message to syslog.

### Arguments: * message: str - Raw log payload.

### Returns: None - Message is forwarded to syslog with configured facility/level.

Parameters:

message (str)

Return type:

None

Formatters

Author: Jacek ‘Szumak’ Kotlarski –<szumak@virthost.pl> Created: 2023-10-10

Purpose: Provide reusable log formatter implementations.

Each formatter composes a list of format segments consumed by BLogFormatter to render message payloads consistently across engines.

class jsktoolbox.logstool.formatters.LogFormatterNull[source]

Bases: BLogFormatter

Provide bare message formatting with optional logger name prefix.

__init__()[source]

Initialise null formatter templates.

### Returns: None - Populates the formatter template list.

Return type:

None

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

format(message, name=None)

Render a log message based on the configured forms list.

### Arguments: * message: str - Log string to include in the output. * name: Optional[str] - Optional application name.

### Returns: [str] - Formatted log payload.

Parameters:
  • message (str)

  • name (str | None)

Return type:

str

class jsktoolbox.logstool.formatters.LogFormatterDateTime[source]

Bases: BLogFormatter

Prefix log messages with the current local date and time.

__init__()[source]

Initialise date-time formatter templates.

### Returns: None - Populates the formatter template list.

Return type:

None

__get_formatted_date__()[source]

Return the current local datetime string.

### Returns: str - Timestamp in %Y-%m-%d %H:%M:%S format.

Return type:

str

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

format(message, name=None)

Render a log message based on the configured forms list.

### Arguments: * message: str - Log string to include in the output. * name: Optional[str] - Optional application name.

### Returns: [str] - Formatted log payload.

Parameters:
  • message (str)

  • name (str | None)

Return type:

str

class jsktoolbox.logstool.formatters.LogFormatterTime[source]

Bases: BLogFormatter

Prefix log messages with the current local time.

__init__()[source]

Initialise time-only formatter templates.

### Returns: None - Populates the formatter template list.

Return type:

None

__get_formatted_time__()[source]

Return the current local time string.

### Returns: str - Timestamp in %H:%M:%S format.

Return type:

str

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

format(message, name=None)

Render a log message based on the configured forms list.

### Arguments: * message: str - Log string to include in the output. * name: Optional[str] - Optional application name.

### Returns: [str] - Formatted log payload.

Parameters:
  • message (str)

  • name (str | None)

Return type:

str

class jsktoolbox.logstool.formatters.LogFormatterTimestamp[source]

Bases: BLogFormatter

Prefix log messages with a high-resolution numeric timestamp.

__init__()[source]

Initialise timestamp formatter templates.

### Returns: None - Populates the formatter template list.

Return type:

None

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

format(message, name=None)

Render a log message based on the configured forms list.

### Arguments: * message: str - Log string to include in the output. * name: Optional[str] - Optional application name.

### Returns: [str] - Formatted log payload.

Parameters:
  • message (str)

  • name (str | None)

Return type:

str

Keys

Author: Jacek ‘Szumak’ Kotlarski –<szumak@virthost.pl> Created: 2024-09-06

Purpose: Define read-only key containers for the logging subsystem.

The module centralises symbolic names for log levels, facilities, and queue attributes to keep engines, formatters, and clients aligned.

class jsktoolbox.logstool.keys.LogKeys[source]

Bases: object

Expose symbolic names shared across log engines, queues, and clients.

BUFFERED: str = '__buffered__'
CONF: str = '__conf__'
DIR: str = '__dir__'
FACILITY: str = '__facility__'
FILE: str = '__file__'
FORMATTER: str = '__formatter__'
LEVEL: str = '__level__'
NAME: str = '__name__'
NO_CONF: str = '__no_conf__'
QUEUE: str = '__queue__'
SYSLOG: str = '__syslog__'
ROTATE_SIZE: str = '__rotate_size__'
ROTATE_COUNT: str = '__rotate_count__'
class jsktoolbox.logstool.keys.SysLogKeys[source]

Bases: object

Provide syslog level and facility constants as read-only namespaces.

level

Exposes syslog level constants as read-only namespace.

alias of __Levels

facility

Exposes syslog facility constants as read-only namespace.

alias of __Facilities

level_keys: Mapping[str, int] = mappingproxy({'ALERT': 1, 'CRITICAL': 2, 'DEBUG': 7, 'EMERGENCY': 0, 'ERROR': 3, 'INFO': 6, 'NOTICE': 5, 'WARNING': 4})

Maps human-readable level names to syslog values.

facility_keys: Mapping[str, int] = mappingproxy({'DAEMON': 24, 'LOCAL0': 128, 'LOCAL1': 136, 'LOCAL2': 144, 'LOCAL3': 152, 'LOCAL4': 160, 'LOCAL5': 168, 'LOCAL6': 176, 'LOCAL7': 184, 'MAIL': 16, 'SYSLOG': 40, 'USER': 8})

Maps human-readable facility names to syslog values.

class jsktoolbox.logstool.keys.LogsLevelKeys[source]

Bases: object

Provide symbolic identifiers for supported log severities.

ALERT: str = 'ALERT'
CRITICAL: str = 'CRITICAL'
DEBUG: str = 'DEBUG'
EMERGENCY: str = 'EMERGENCY'
ERROR: str = 'ERROR'
INFO: str = 'INFO'
NOTICE: str = 'NOTICE'
WARNING: str = 'WARNING'
keys: tuple[str, ...] = ('ALERT', 'CRITICAL', 'DEBUG', 'EMERGENCY', 'ERROR', 'INFO', 'NOTICE', 'WARNING')

Contains all supported log level identifiers.

Logs

Author: Jacek Kotlarski –<szumak@virthost.pl> Created: 2023-09-04

Purpose: Implement logging client, engine, and processing thread utilities.

These classes orchestrate message queuing, engine dispatch, and background processing for the logging subsystem.

class jsktoolbox.logstool.logs.LoggerClient(queue=None, name=None)[source]

Bases: BLoggerQueue, NoDynamicAttributes

Provide a user-facing client for enqueuing log messages.

Parameters:
__init__(queue=None, name=None)[source]

Initialise a logging client instance.

### Arguments: * queue: Optional[LoggerQueue] - Shared queue supplied by a LoggerEngine. * name: Optional[str] - Optional client prefix added to messages.

### Returns: None - Constructor.

Parameters:
Return type:

None

property logs_queue: LoggerQueue | None

Return the configured logging queue instance.

### Returns: [Optional[LoggerQueue]] - Logger queue or None when not set.

property name: str | None

Return the configured client name.

### Returns: Optional[str] - Client identifier or None.

message(message, log_level='INFO')[source]

Emit a log message at the requested level.

### Arguments: * message: str - Payload to log. * log_level: str - Severity key from LogsLevelKeys; defaults to INFO.

### Returns: None - Message enqueued when a queue is available.

### Raises: * TypeError: When log_level is not a string. * KeyError: When log_level is not recognised.

Parameters:
  • message (str)

  • log_level (str)

Return type:

None

property message_alert: None

Return None for the ALERT proxy property.

### Returns: None - Property exposed for write-only usage.

property message_critical: None

Return None for the CRITICAL proxy property.

### Returns: None - Property exposed for write-only usage.

property message_debug: None

Return None for the DEBUG proxy property.

### Returns: None - Property exposed for write-only usage.

property message_emergency: None

Return None for the EMERGENCY proxy property.

### Returns: None - Property exposed for write-only usage.

property message_error: None

Return None for the ERROR proxy property.

### Returns: None - Property exposed for write-only usage.

property message_info: None

Return None for the INFO proxy property.

### Returns: None - Property exposed for write-only usage.

property message_notice: None

Return None for the NOTICE proxy property.

### Returns: None - Property exposed for write-only usage.

property message_warning: None

Return None for the WARNING proxy property.

### Returns: None - Property exposed for write-only usage.

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

class jsktoolbox.logstool.logs.LoggerEngine[source]

Bases: BLoggerQueue, NoDynamicAttributes

Coordinate engines and dispatch queued log messages.

__init__()[source]

Initialise the logging engine with default outputs.

### Returns: None - Constructor.

Return type:

None

property logs_queue: LoggerQueue | None

Return the configured logging queue instance.

### Returns: [Optional[LoggerQueue]] - Logger queue or None when not set.

add_engine(log_level, engine)[source]

Attach an engine to a specific log level.

### Arguments: * log_level: str - Severity identifier from LogsLevelKeys. * engine: ILoggerEngine - Engine instance handling the level.

### Returns: None - Internal configuration updated.

### Raises: * TypeError: When log_level is not a string or engine is not an ILoggerEngine.

Parameters:
  • log_level (str)

  • engine (ILoggerEngine)

Return type:

None

send()[source]

Dequeue pending messages and dispatch them to engines.

### Returns: None - The queue is drained until empty.

Return type:

None

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

class jsktoolbox.logstool.logs.ThLoggerProcessor(debug=False)[source]

Bases: Thread, ThBaseObject, NoDynamicAttributes

Run a background thread that continually drains the log queue.

Parameters:

debug (bool)

__init__(debug=False)[source]

Initialise processing thread state.

### Arguments: * debug: bool - When True, emit diagnostic messages via the client.

### Returns: None - Constructor.

Parameters:

debug (bool)

Return type:

None

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

getName()

Return a string used for identification purposes only.

This method is deprecated, use the name attribute instead.

property ident

Thread identifier of this thread or None if it has not been started.

This is a nonzero integer. See the get_ident() function. Thread identifiers may be recycled when a thread exits and another thread is created. The identifier is available even after the thread has exited.

isDaemon()

Return whether this thread is a daemon.

This method is deprecated, use the daemon attribute instead.

is_alive()

Return whether the thread is alive.

This method returns True just before the run() method starts until just after the run() method terminates. See also the module function enumerate().

join(timeout=None)

Wait until the thread terminates.

This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception or until the optional timeout occurs.

When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened – if the thread is still alive, the join() call timed out.

When the timeout argument is not present or None, the operation will block until the thread terminates.

A thread can be join()ed many times.

join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.

property name

A string used for identification purposes only.

It has no semantics. Multiple threads may be given the same name. The initial name is set by the constructor.

property native_id

Native integral thread ID of this thread, or None if it has not been started.

This is a non-negative integer. See the get_native_id() function. This represents the Thread ID as reported by the kernel.

setDaemon(daemonic)

Set whether this thread is a daemon.

This method is deprecated, use the .daemon property instead.

setName(name)

Set the name string for this thread.

This method is deprecated, use the name attribute instead.

start()

Start the thread’s activity.

It must be called at most once per thread object. It arranges for the object’s run() method to be invoked in a separate thread of control.

This method will raise a RuntimeError if called more than once on the same thread object.

property started: bool

Return whether the thread has started.

### Returns: [bool] - True when the thread start event is set.

property daemon

A boolean value indicating whether this thread is a daemon thread.

This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when only daemon threads are left.

property sleep_period: float

Return configured sleep period in seconds.

### Returns: [float] - Sleep interval value.

property logger_engine: LoggerEngine | None

Return the associated logger engine instance.

### Returns: Optional[LoggerEngine] - Engine reference or None.

property logger_client: LoggerClient | None

Return the associated logger client instance.

### Returns: Optional[LoggerClient] - Client reference or None.

run()[source]

Process the logging queue until stopped.

### Raises: * ValueError: When required engine or client references are missing.

Return type:

None

stop()[source]

Request the background thread to stop.

### Returns: None - Signals the internal stop event.

Return type:

None

property stopped: bool

Return True when the stop event has been set.

### Returns: bool - Stop flag state.

Queue

Author: Jacek ‘Szumak’ Kotlarski –<szumak@virthost.pl> Created: 2024-09-06

Purpose: Provide a minimal FIFO queue implementation for the logging subsystem.

LoggerQueue stores log level/message pairs in memory when engines cannot dispatch immediately.

class jsktoolbox.logstool.queue.LoggerQueue[source]

Bases: BClasses, NoDynamicAttributes

In-memory FIFO storage for log messages.

__init__()[source]

Initialise an empty queue.

### Returns: None - Constructor does not return a value.

Return type:

None

get()[source]

Return and remove the next queued log entry.

### Returns: Optional[tuple[str, …]] - Tuple in form (level, message) or None when empty.

### Raises: * Exception: Re-raised as Raise.error when unexpected errors occur.

Return type:

tuple[str, …] | None

__setattr__(name, value)

Prevent dynamic attribute assignment on instances.

### Raises: * AttributeError: Attribute not previously declared.

Parameters:
Return type:

None

put(message, log_level='INFO')[source]

Append a new log entry to the queue.

### Arguments: * message: str - Log message payload. * log_level: str - Log severity; defaults to LogsLevelKeys.INFO.

### Returns: None - The queue is mutated in place.

### Raises: * KeyError: When log_level is not part of LogsLevelKeys.keys.

Parameters:
  • message (str)

  • log_level (str)

Return type:

None