minorg.dynamic_logger module

class minorg.dynamic_logger.CustomFormatter(fmt=None, fmt_msg=None, datefmt=None, style='%')[source]

Bases: logging.Formatter

__init__(fmt=None, fmt_msg=None, datefmt=None, style='%')[source]

Initialize the formatter with specified format strings.

Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with the optional datefmt argument. If datefmt is omitted, you get an ISO8601-like (or RFC 3339-like) format.

Use a style parameter of ‘%’, ‘{’ or ‘$’ to specify that you want to use one of %-formatting, str.format() ({}) formatting or string.Template formatting in your format string.

Changed in version 3.2: Added the style parameter.

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.

exception minorg.dynamic_logger.DuplicateName(message)[source]

Bases: minorg.dynamic_logger.InvalidName, minorg.dynamic_logger.DuplicateObject

exception minorg.dynamic_logger.DuplicateObject(message)[source]

Bases: minorg.MINORgError

exception minorg.dynamic_logger.DuplicateWarning[source]

Bases: minorg.MINORgWarning

class minorg.dynamic_logger.DynamicFileHandler(filename, check_path=True)[source]

Bases: logging.FileHandler

__init__(filename, check_path=True)[source]

Open the specified file and use it as the stream for logging.

update_filename(filename, check_path=True)[source]
class minorg.dynamic_logger.DynamicFileLogger(filename, level=10, **config_defaults)[source]

Bases: minorg.dynamic_logger.DynamicFileLoggerBase

User specifies a group when passing message (E.g. DynamicFileLogger.cmdname(‘minimumset’) and the relevant handlers will do their job) (Note that this works by creating a Logger called ‘cmdname’ and handlers linked to that Logger

will do their job. Maybe a StreamHandler will not print it cuz it’s not relevant, but the FileHandler may wish to do so for thoroughness. There may be different formatting.)

User may also change log file location whenever desired (E.g. DynamicFileLogger.update_filename(‘/mnt/chaelab/rachelle/logs/loggertest.log’))

Groups are effectively Logger objects

__init__(filename, level=10, **config_defaults)[source]
property handlers[source]
class minorg.dynamic_logger.DynamicFileLoggerBase(filename, level=10, default_log_level=20, **config_defaults)[source]

Bases: minorg.dynamic_logger.GroupLogger

User specifies a group when passing message (E.g. DynamicFileLoggerBase.cmdname(‘minimumset’) and the relevant handlers will do their job) (Note that this works by creating a Logger called ‘cmdname’ and handlers linked to that Logger

will do their job. Maybe a StreamHandler will not print it cuz it’s not relevant, but the FileHandler may wish to do so for thoroughness. There may be different formatting.)

User may also change log file location whenever desired (E.g. DynamicFileLoggerBase.update_filename(‘/mnt/chaelab/rachelle/logs/loggertest.log’))

Groups are effectively Logger objects

__init__(filename, level=10, default_log_level=20, **config_defaults)[source]
property filename[source]
is_enabled_for(level)[source]
property level[source]
set_level(level)[source]
update_filename(filename, check_path=True)[source]

Closes connections from DynamicFileHandler to current logfile, replaces DynamicFileHandler.baseFilename, copies closed logfile to new location, and opens connection between all DynamicFileHandler objects to new location

class minorg.dynamic_logger.DynamicFileParasiticSingleLogger(name, filename, parent, level=10, **config_defaults)[source]

Bases: minorg.dynamic_logger.DynamicFileLoggerBase

__init__(name, filename, parent, level=10, **config_defaults)[source]
addHandler(handler, handler_name)[source]
property add_file_handler[source]
add_group(*groups)[source]

Positional ‘handlers’ for Handlers already added to DynamicFileLogger object.

add_handler(*handlers)[source]
Accepts both group names/obj and handler names/obj
  • if group name/obj is received, handlers will be added to file but group will NOT be

property add_logger[source]
property add_stream_handler[source]
property group_names[source]
property groups[source]
property handler_group_names[source]
property handler_groups[source]
is_enabled_for(level)[source]
property level[source]
removeHandler(handler)[source]
remove_group(*groups)[source]
remove_handler(*handlers)[source]
Accepts both group names/obj and handler names/obj
  • if group name/obj is received, handlers will be removed from file but group will NOT be

  • that is, if a handler already added to file is then added to group, group.emit will cause that newly added handler to write to this file

property remove_logger[source]
set_level(level)[source]
update(add=None, remove=None, level=None, filename=None)[source]

Both ‘add’ and ‘remove’ accept groups, not just handlers? Maybe? TODO If a name (provided to ‘add’ or ‘remove’ refers to both a handler and a group, handler is prioritised

update_filename(filename, check_path=True)[source]

Replaces DynamicMultiFileHandler records for current file with new location

property update_group[source]

Add or remove handlers from group

update_handlers(add=None, remove=None)[source]
update_level(level)[source]
class minorg.dynamic_logger.DynamicMultiFileHandler(*filenames, check_path=True)[source]

Bases: logging.FileHandler

Writes to multple files

__init__(*filenames, check_path=True)[source]

Open the specified file and use it as the stream for logging.

add_file(filename, name=None, check_path=True, replace=False, quiet=False)[source]
emit(record)[source]

Call FileHandler’s emit method for each filename

remove_file(name)[source]
update_filename(old, new, check_path=True, original_new=None)[source]
class minorg.dynamic_logger.DynamicMultiFileLogger(crosstalk=True)[source]

Bases: minorg.dynamic_logger.GroupLogger

Allows writing to multiple files simultaneously, while sharing group names and Formatters Possibly only really useful for reusing headers such as “–Initiating <subcmd>–”

dmflogger = DynamicMultiFileLogger() ## instantiate w/ dummy log location, close immediately & remove file dmflogger.add_file(“log1”, “/mnt/chaelab/rachelle/tmp/log1.log”) ## check & store filename in dict dmflogger.add_file(“log2”, “/mnt/chaelab/rachelle/tmp/log2.log”) ## check & store filename in dict dmflogger.add_format(“cmd”, “command: %(message)s”) dmflogger.add_format(“full”, “%(asctime)s - %(name)s - %(levelname)s:%(message)s”) dmflogger.add_stream_handler(“cheader”, level = logging.INFO, format = “cmd”) dmflogger.add_file_handler(“fheader”, level = logging.INFO, format = “cmd”) ## mk template DynamicFileHandler dmflogger.add_stream_handler(“cfull”, level = logging.INFO, format = “full”) dmflogger.add_file_handler(“ffull”, level = logging.INFO, format = “full”) ## mk template DynamicFileHandler dmflogger.add_group(“header”, “cheader”, “fheader”) dmflogger.add_group(“full”, “cfull”, “ffull”) dmflogger.add_group(“all”, *dmflogger.handlers) ## perhaps have a built-in ‘all’ group? # dmflogger.log1.add_handler(“header”) ## duplicate fheader’s DynamicFileHandler # dmflogger.log2.add_handler(“header”, “full”) ## duplicate ffull AND fheader’s DynamicFileHandlers dmflogger.header.info(“executing minimumset”) dmflogger.full.debug(“we’re doing something”) dmflogger.log2.update_filename(“/mnt/chaelab/rachelle/log3.log”)

IMPT: ensure no duplicate calls of StreamHandlers for groups w/ StreamHandler that are

associated with multiple files

  • each ‘file’ is represented by a DynamicFileLogger (allows file-specific logging) - ensure all changes to DynamicMultiFileLogger groups are propagated to each file’s DynamicFileLogger

  • if logging directly from DynamicMultiFileLogger, DON”T call each file’s DynamicFileLogger.error…

  • file handlers (DynamicFileHandlers) to be handled distinctly from StreamHandlers - when new file handlers are added, create template file handler w/ dummy log location, close, then rm - when file handlers are assigned to a file, duplicate handler template, update log location w/ filename, then add duplicated handler to group’s MultiLogger and file’s DynamicFileLogger - ensure that groups are also propagated to each file’s DynamicFileLogger

  • when removing handlers from groups, ensure that this is propagated to group’s MultiLogger AND file’s DynamicFileLogger

__init__(crosstalk=True)[source]
group_crosstalk:
  • if True, groups that were not added to file can write to file via shared handlers. - Handlers can be added by both add_group and add_handler.

  • if False, groups can only write to file if group has been added to file - Groups can only be added to file using:

    • DynamicMultiFileLogger.file1.add_group(<group>)

    • DynamicMultiFileLogger.update_file(<file1>, add = <group>)

    • DynamicMultiFileLogger.update_group(<file1>, add = <group>)

    • DynamicMultiFileLogger.file1.add_handler(<group>) and DynamicMultiFileLogger.update_file(<file1>, add = <group handlers>) DynamicMultiFileLogger.update_group(<file1>, add = <group handlers>) will link individual handlers in the group but not the group to file

add_file(name, filename, *handlers, replace=False, check_path=True)[source]

Positional ‘handlers’ for Handlers already added to DynamicFileLogger object.

add_file_handler(name, format='%(asctime)s %(message)s', level=None, replace=False, quiet=False)[source]
property crosstalk[source]
property handlers[source]
update_file(fname, add=None, remove=None, level=None, filename=None)[source]

Both ‘add’ and ‘remove’ accept groups, not just handlers If a name (provided to ‘add’ or ‘remove’ refers to both a handler and a group, handler is prioritised

update_filename(name, filename)[source]
update_group(group, add=None, remove=None, level=None)[source]

Add or remove handlers from group

class minorg.dynamic_logger.GroupLogger(**kwargs)[source]

Bases: minorg.dynamic_logger.MultiLogger

__init__(**kwargs)[source]
property active_handler_names[source]
property active_handlers[source]
add_file_handler(name, format='%(asctime)s %(message)s', level=None, replace=False, quiet=False)[source]
add_format(name, format, replace=False, quiet=False, format_msg=None)[source]
add_group(name, *handlers, level=10, default_log_level=None, format_msg=<function GroupLogger.<lambda>>)[source]

Positional ‘handlers’ for Handlers already added to DynamicFileLogger object.

add_stream_handler(name, format='%(asctime)s %(message)s', level=None, replace=False, quiet=False)[source]
property all_handlers[source]
property file_handler_names[source]
property file_handlers[source]
property format[source]
property format_children[source]
property format_map[source]
property format_names[source]
property formats[source]
get_handler(handler)[source]
property group_names[source]
groups(name=True, group_name=False, handler_name=False)[source]
property handler[source]
property handler_children[source]
property handler_map[source]
property handler_names[source]
property orphan_handler_names[source]
property orphan_handlers[source]
remove_group(name)[source]
property stream_handler_names[source]
property stream_handlers[source]
update_group(group, add=None, remove=None, level=None)[source]

Add or remove handlers from group

exception minorg.dynamic_logger.HiddenAttribute(attribute_type, method, method_bound_obj=None)[source]

Bases: minorg.MINORgError

Used to hide superclass attributes by throwing error upon attempted access to specific method names Used in conjuction with @property’ decorator, e.g.:

@property def method_to_hide: raise HiddenMethod(super().method_to_hide)

When the method to be hidden is already a property, use:

@property def method_to_hide: raise HiddenMethod(super(self.__class__, self.__class__).method_to_hide.fget, self)

__init__(attribute_type, method, method_bound_obj=None)[source]
exception minorg.dynamic_logger.HiddenMethod(method, method_bound_obj=None)[source]

Bases: minorg.dynamic_logger.HiddenAttribute

__init__(method, method_bound_obj=None)[source]
exception minorg.dynamic_logger.HiddenProperty(method, method_bound_obj=None)[source]

Bases: minorg.dynamic_logger.HiddenAttribute

__init__(method, method_bound_obj=None)[source]
exception minorg.dynamic_logger.InvalidArgs(message)[source]

Bases: minorg.MINORgError

exception minorg.dynamic_logger.InvalidName(message)[source]

Bases: minorg.MINORgError

exception minorg.dynamic_logger.InvalidType(message)[source]

Bases: minorg.MINORgError

class minorg.dynamic_logger.MultiChild(child_adj: str = 'child', child_obj: str = 'Child', child_alias: str = 'Child', child_class=None, make_child=None, unique: bool = False, children: dict = {}, **args_for_instantiating_children_upon_creation)[source]

Bases: object

__init__(child_adj: str = 'child', child_obj: str = 'Child', child_alias: str = 'Child', child_class=None, make_child=None, unique: bool = False, children: dict = {}, **args_for_instantiating_children_upon_creation)[source]
add_child(child=None, child_name: Optional[str] = None, replace=False, quiet=False, **kwargs)[source]

accepts Child obj or child_name (str)

property children[source]
property children_map[source]
property children_names[source]
filter_children(f)[source]
filter_children_map(f=<function MultiChild.<lambda>>)[source]
filter_children_names(f)[source]
get_child(child)[source]
get_child_name(child)[source]
is_child(other)[source]
is_child_class(other)[source]
name_available(name, raise_exception=False)[source]
remove_child(child, class_name=None)[source]

accepts both child_name (str) and Child obj

class minorg.dynamic_logger.MultiHandler(unique=True)[source]

Bases: minorg.dynamic_logger.MultiHandlerBase

__init__(unique=True)[source]
property handlers[source]
class minorg.dynamic_logger.MultiHandlerBase(**kwargs)[source]

Bases: minorg.dynamic_logger.MultiChild

__init__(**kwargs)[source]
add_handler(handler, handler_name, replace=False, ignore_duplicate=False, quiet=False)[source]

Accepts a Handler object (e.g. StreamHandler, FileHandler, DynamicFileHandler)

property all_handlers[source]
property file_handler_map[source]
property file_handler_names[source]
property file_handlers[source]
property handler_map[source]
property handler_names[source]
remove_handler(handler)[source]
property stream_handler_map[source]
property stream_handler_names[source]
property stream_handlers[source]
class minorg.dynamic_logger.MultiLogger(logger_class=<class 'minorg.dynamic_logger.PublicLogger'>, make_logger=<function MultiLogger.<lambda>>, default_log_level=20)[source]

Bases: minorg.dynamic_logger.MultiChild

__init__(logger_class=<class 'minorg.dynamic_logger.PublicLogger'>, make_logger=<function MultiLogger.<lambda>>, default_log_level=20)[source]
add_logger(logger, name: Optional[str] = None, replace=False, quiet=False, level=10, default_log_level=None, **kwargs)[source]
get_logger(logger)[source]
is_logger(other)[source]
property logger_map[source]
property logger_names[source]
property loggers[source]
remove_logger(logger)[source]
class minorg.dynamic_logger.PublicAwareLogger(name, parent, crosstalk=True, **kwargs)[source]

Bases: minorg.dynamic_logger.PublicLogger

Handles crosstalk and logging level

__init__(name, parent, crosstalk=True, **kwargs)[source]

Initialize the logger with a name and an optional level.

property crosstalk[source]
class minorg.dynamic_logger.PublicLogger(name, unique=True, default_log_level=20, format_msg=<function PublicLogger.<lambda>>)[source]

Bases: logging.Logger, minorg.dynamic_logger.MultiHandlerBase

Logger object, but it adds Handler objects as attributes for easy access

__init__(name, unique=True, default_log_level=20, format_msg=<function PublicLogger.<lambda>>)[source]

Initialize the logger with a name and an optional level.

addHandler(handler, handler_name, replace=False, ignore_duplicate=False, quiet=False)[source]

Add the specified handler to this logger.

removeHandler(handler)[source]

Remove the specified handler from this logger.

exception minorg.dynamic_logger.ReservedName(message)[source]

Bases: minorg.dynamic_logger.InvalidName

exception minorg.dynamic_logger.UnknownChild(message)[source]

Bases: minorg.MINORgError

exception minorg.dynamic_logger.UnknownInitialiser(message)[source]

Bases: minorg.MINORgError

exception minorg.dynamic_logger.UnknownReferenceWarning[source]

Bases: UserWarning

minorg.dynamic_logger.append_time(path)[source]
minorg.dynamic_logger.check_path_and_return(path)[source]
minorg.dynamic_logger.file_in_use(path)[source]
minorg.dynamic_logger.test_logger(test: str = 'dmfl', dir=None, test_getters: bool = True, logger=None)[source]