trace - Trace/audit for class instances¶
Overview¶
This module provides trace/audit logging for functions or object methods through context-based
logging provided by logging module.
The trace logging is performed by traced decorator. You can use this decorator directly,
or use TracedMixin class to automatically decorate methods of class instances on creation.
Each decorated callable could log messages before execution, after successful execution or
on failed execution (when unhandled exception is raised by callable). The trace decorator
can automatically add agent and context information, and include parameters passed to
callable, execution time, return value, information about raised exception etc. to log messages.
Trace behavior can be configured dynamically at runtime using the TraceManager.
This includes:
Enabling/disabling tracing globally or for specific aspects (before/after/fail).
Registering classes whose methods should be traced.
Adding specific trace configurations (like custom messages or levels) for individual methods using
TraceManager.add_trace().Loading comprehensive trace configurations from
ConfigParserfiles usingTraceManager.load_config(), which allows specifying traced classes, methods, and decorator parameters via INI-style sections (seeTraceConfig).
Example¶
The following program is an example of small but complex enough code that you can use to experiment with code tracing options. The parts relevant to tracing are highlighted in the code by embedded comments.
# test-trace.py
from __future__ import annotations
import logging
from time import monotonic
from decimal import Decimal
from enum import IntEnum, auto
from firebird.base.types import *
from firebird.base.logging import LogLevel, LoggingIdMixin, get_logger
from firebird.base.trace import TracedMixin, add_trace, trace_manager, TraceFlag, traced
class Mood(IntEnum):
"Agent moods"
ANGRY = auto()
SAD = auto()
NEUTRAL = auto()
PLEASED = auto()
HAPPY = auto()
class Person(TracedMixin): # TRACE
"Sample virtual human agent"
def __init__(self, name: str, mood: Mood=Mood.NEUTRAL):
self.name: str = name
self.mood: Mood = mood
self.partners: List[Person] = []
# >>> LOGGING & TRACE
@property
def _agent_name_(self) -> str:
return f"{self.mood.name} {self.name}"
# <<< LOGGING & TRACE
def change_mood(self, offset: int) -> None:
result = self.mood + offset
if result < Mood.ANGRY:
self.mood = Mood.ANGRY
elif result > Mood.HAPPY:
self.mood = Mood.HAPPY
else:
self.mood = Mood(result)
def process(self, message: str) -> None:
msg = message.lower()
if msg == "what you are doing here":
self.change_mood(-1)
if 'awful' in msg:
self.change_mood(-1)
if ('nice' in msg) or ('wonderful' in msg) or ('pleased' in msg):
if self.mood != Mood.ANGRY:
self.change_mood(1)
if 'happy' in msg:
if self.mood != Mood.ANGRY:
self.change_mood(2)
if 'very nice' in msg:
if self.mood != Mood.ANGRY:
self.change_mood(1)
if 'get lost' in msg:
self.change_mood(-2)
if self.name.lower() in msg:
if self.mood == Mood.SAD:
self.change_mood(1)
if self.name.lower() not in msg:
if self.mood == Mood.NEUTRAL:
self.change_mood(-1)
def process_response(self, to: str, mood: Mood) -> None:
if to == 'greeting':
if self.mood == Mood.NEUTRAL:
if mood > Mood.NEUTRAL:
self.mood = Mood.PLEASED
elif mood == Mood.ANGRY:
self.mood = Mood.SAD
elif self.mood == Mood.SAD:
if mood == Mood.SAD:
self.mood = Mood.NEUTRAL
elif mood == Mood.HAPPY:
self.mood = Mood.ANGRY
elif self.mood == Mood.ANGRY and mood == Mood.SAD:
self.mood = Mood.NEUTRAL
elif to == 'chat':
if self.mood == Mood.SAD and mood > Mood.NEUTRAL:
self.mood = Mood.NEUTRAL
elif self.mood == Mood.ANGRY and mood == Mood.SAD:
self.mood = Mood.NEUTRAL
elif self.mood == Mood.PLEASED and mood == Mood.ANGRY:
self.mood = Mood.NEUTRAL
elif self.mood == Mood.HAPPY and mood == Mood.ANGRY:
self.mood = Mood.SAD
elif to == 'bye':
if self.mood == Mood.NEUTRAL:
if mood == Mood.ANGRY:
self.mood = Mood.ANGRY
elif mood > Mood.NEUTRAL:
self.mood = Mood.PLEASED
elif self.mood == Mood.HAPPY and mood == Mood.ANGRY:
self.mood = Mood.NEUTRAL
def meet(self, other: Person) -> None:
self.partners.append(other)
self.greeting(other)
def interact(self, other: Person, message: str) -> Mood:
print(f"[{other.name}] {message}")
self.process(message)
return self.mood
def greeting(self, other: Person) -> None:
if self.mood == Mood.NEUTRAL:
msg = f"Hi {other.name}, I'm {self.name}"
elif self.mood == Mood.ANGRY:
msg = "Hi"
elif self.mood == Mood.SAD:
msg = f"Hi {other.name}"
else:
msg = f"Hi {other.name}, I'm {self.name}. I'm {self.mood.name} to meet you."
self.process_response('greeting', other.interact(self, msg))
def chat(self) -> None:
for other in self.partners:
if self.mood == Mood.ANGRY:
msg = "What you are doing here?"
elif self.mood == Mood.SAD:
msg = "The weather is awful today, don't you think?"
elif self.mood == Mood.NEUTRAL:
msg = "It's a fine day, don't you think?"
elif self.mood == Mood.PLEASED:
msg = "It's a very nice day, don't you think?"
else:
msg = "Today is a wonderful day!"
self.process_response('chat', other.interact(self, msg))
def bye(self) -> str:
while self.partners:
other = self.partners.pop()
if self.mood == Mood.ANGRY:
msg = "Get lost!"
elif self.mood == Mood.SAD:
msg = "Bye"
elif self.mood == Mood.NEUTRAL:
msg = f"Bye, {other.name}."
elif self.mood == Mood.PLEASED:
msg = f"See you, {other.name}!"
else:
msg = f"Bye, {other.name}. Have a nice day!"
self.process_response('bye', other.interact(self, msg))
if self.mood == Mood.ANGRY:
result = "I hate this meeting!"
elif self.mood == Mood.SAD:
result = "It was a waste of time!"
elif self.mood == Mood.NEUTRAL:
result = "It was OK."
elif self.mood == Mood.PLEASED:
result = "Nice meeting, I think."
else:
result = "What a wonderful meeting!"
return result
def __repr__(self) -> str:
# Replace "..Person object at .." with something more suitable for trace
return f"Person('{self.name}', {self.mood.name})"
def meeting(name: str, persons: List[Person]):
"Simulation of virtual agents meeting"
for person in persons:
person.log_context = name
start = monotonic()
print("Meeting started...")
print(f"Attendees: {', '.join(f'{x.name} [{x.mood.name}]' for x in persons)}")
for person in persons:
for other in persons:
if other is not person:
person.meet(other)
for person in persons:
person.chat()
for person in persons:
person.bye()
e = str(Decimal(monotonic() - start))
print(f"Meeting closed in {e[:e.find('.')+6]} sec.")
print(f"Outcome: {', '.join(f'{x.name} [{x.mood.name}]' for x in persons)}")
def test_trace(name: str, first: Mood, second: Mood) -> None:
print("- without trace ----------")
meeting(name, [Person('Alex', first), Person('David', second)])
print("- trace ------------------")
# >>> TRACE
add_trace(Person, 'greeting')
add_trace(Person, 'bye')
add_trace(Person, 'chat')
add_trace(Person, 'change_mood')
add_trace(Person, 'process', with_args=False)
add_trace(Person, 'process_response')
# <<< TRACE
meeting(name, [Person('Alex', first), Person('David', second)])
if __name__ == '__main__':
# >>> LOGGING
logger = logging.getLogger()
logger.setLevel(LogLevel.NOTSET)
sh = logging.StreamHandler()
sh.setFormatter(logging.Formatter('%(levelname)-10s: [%(topic)s][%(agent)s][%(context)s] %(message)s'))
logger.addHandler(sh)
# <<< LOGGING
# >>> TRACE
trace_manager.flags |= TraceFlag.ACTIVE
trace_manager.flags |= (TraceFlag.FAIL | TraceFlag.BEFORE | TraceFlag.AFTER)
# <<< TRACE
test_trace('TEST-1', Mood.SAD, Mood.PLEASED)
Output from sample code:
> python test-trace.py
- without trace ----------
Meeting started...
Attendees: Alex [SAD], David [PLEASED]
[Alex] Hi David
[David] Hi Alex, I'm David. I'm PLEASED to meet you.
[Alex] It's a fine day, don't you think?
[David] It's a very nice day, don't you think?
[Alex] Bye, David. Have a nice day!
[David] Bye, Alex. Have a nice day!
Meeting closed in 0.00014 sec.
Outcome: Alex [HAPPY], David [HAPPY]
- trace ------------------
Meeting started...
Attendees: Alex [SAD], David [PLEASED]
DEBUG : [trace][SAD Alex][TEST-1] >>> greeting(other=Person('David', PLEASED))
DEBUG : [trace][PLEASED David][TEST-1] >>> interact(other=Person('Alex', SAD), message='Hi David')
[Alex] Hi David
DEBUG : [trace][PLEASED David][TEST-1] >>> process
DEBUG : [trace][PLEASED David][TEST-1] <<< process[0.00002]
DEBUG : [trace][PLEASED David][TEST-1] <<< interact[0.00020] Result: <Mood.PLEASED: 4>
DEBUG : [trace][SAD Alex][TEST-1] >>> process_response(to='greeting', mood=<Mood.PLEASED: 4>)
DEBUG : [trace][SAD Alex][TEST-1] <<< process_response[0.00000]
DEBUG : [trace][SAD Alex][TEST-1] <<< greeting[0.00060]
DEBUG : [trace][PLEASED David][TEST-1] >>> greeting(other=Person('Alex', SAD))
DEBUG : [trace][SAD Alex][TEST-1] >>> interact(other=Person('David', PLEASED), message="Hi Alex, I'm David. I'm PLEASED to meet you.")
[David] Hi Alex, I'm David. I'm PLEASED to meet you.
DEBUG : [trace][SAD Alex][TEST-1] >>> process
DEBUG : [trace][SAD Alex][TEST-1] >>> change_mood(offset=1)
DEBUG : [trace][SAD Alex][TEST-1] <<< change_mood[0.00000]
DEBUG : [trace][SAD Alex][TEST-1] <<< process[0.00016]
DEBUG : [trace][SAD Alex][TEST-1] <<< interact[0.00030] Result: <Mood.NEUTRAL: 3>
DEBUG : [trace][PLEASED David][TEST-1] >>> process_response(to='greeting', mood=<Mood.NEUTRAL: 3>)
DEBUG : [trace][PLEASED David][TEST-1] <<< process_response[0.00000]
DEBUG : [trace][PLEASED David][TEST-1] <<< greeting[0.00061]
DEBUG : [trace][NEUTRAL Alex][TEST-1] >>> chat()
DEBUG : [trace][PLEASED David][TEST-1] >>> interact(other=Person('Alex', NEUTRAL), message="It's a fine day, don't you think?")
[Alex] It's a fine day, don't you think?
DEBUG : [trace][PLEASED David][TEST-1] >>> process
DEBUG : [trace][PLEASED David][TEST-1] <<< process[0.00000]
DEBUG : [trace][PLEASED David][TEST-1] <<< interact[0.00013] Result: <Mood.PLEASED: 4>
DEBUG : [trace][NEUTRAL Alex][TEST-1] >>> process_response(to='chat', mood=<Mood.PLEASED: 4>)
DEBUG : [trace][NEUTRAL Alex][TEST-1] <<< process_response[0.00000]
DEBUG : [trace][NEUTRAL Alex][TEST-1] <<< chat[0.00042]
DEBUG : [trace][PLEASED David][TEST-1] >>> chat()
DEBUG : [trace][NEUTRAL Alex][TEST-1] >>> interact(other=Person('David', PLEASED), message="It's a very nice day, don't you think?")
[David] It's a very nice day, don't you think?
DEBUG : [trace][NEUTRAL Alex][TEST-1] >>> process
DEBUG : [trace][NEUTRAL Alex][TEST-1] >>> change_mood(offset=1)
DEBUG : [trace][NEUTRAL Alex][TEST-1] <<< change_mood[0.00000]
DEBUG : [trace][PLEASED Alex][TEST-1] >>> change_mood(offset=1)
DEBUG : [trace][PLEASED Alex][TEST-1] <<< change_mood[0.00000]
DEBUG : [trace][NEUTRAL Alex][TEST-1] <<< process[0.00027]
DEBUG : [trace][NEUTRAL Alex][TEST-1] <<< interact[0.00039] Result: <Mood.HAPPY: 5>
DEBUG : [trace][PLEASED David][TEST-1] >>> process_response(to='chat', mood=<Mood.HAPPY: 5>)
DEBUG : [trace][PLEASED David][TEST-1] <<< process_response[0.00000]
DEBUG : [trace][PLEASED David][TEST-1] <<< chat[0.00068]
DEBUG : [trace][HAPPY Alex][TEST-1] >>> bye()
DEBUG : [trace][PLEASED David][TEST-1] >>> interact(other=Person('Alex', HAPPY), message='Bye, David. Have a nice day!')
[Alex] Bye, David. Have a nice day!
DEBUG : [trace][PLEASED David][TEST-1] >>> process
DEBUG : [trace][PLEASED David][TEST-1] >>> change_mood(offset=1)
DEBUG : [trace][PLEASED David][TEST-1] <<< change_mood[0.00000]
DEBUG : [trace][PLEASED David][TEST-1] <<< process[0.00013]
DEBUG : [trace][PLEASED David][TEST-1] <<< interact[0.00024] Result: <Mood.HAPPY: 5>
DEBUG : [trace][HAPPY Alex][TEST-1] >>> process_response(to='bye', mood=<Mood.HAPPY: 5>)
DEBUG : [trace][HAPPY Alex][TEST-1] <<< process_response[0.00000]
DEBUG : [trace][HAPPY Alex][TEST-1] <<< bye[0.00052] Result: 'What a wonderful meeting!'
DEBUG : [trace][HAPPY David][TEST-1] >>> bye()
DEBUG : [trace][HAPPY Alex][TEST-1] >>> interact(other=Person('David', HAPPY), message='Bye, Alex. Have a nice day!')
[David] Bye, Alex. Have a nice day!
DEBUG : [trace][HAPPY Alex][TEST-1] >>> process
DEBUG : [trace][HAPPY Alex][TEST-1] >>> change_mood(offset=1)
DEBUG : [trace][HAPPY Alex][TEST-1] <<< change_mood[0.00000]
DEBUG : [trace][HAPPY Alex][TEST-1] <<< process[0.00013]
DEBUG : [trace][HAPPY Alex][TEST-1] <<< interact[0.00024] Result: <Mood.HAPPY: 5>
DEBUG : [trace][HAPPY David][TEST-1] >>> process_response(to='bye', mood=<Mood.HAPPY: 5>)
DEBUG : [trace][HAPPY David][TEST-1] <<< process_response[0.00000]
DEBUG : [trace][HAPPY David][TEST-1] <<< bye[0.00052] Result: 'What a wonderful meeting!'
Meeting closed in 0.00432 sec.
Outcome: Alex [HAPPY], David [HAPPY]
Trace configuration¶
New in version 1.1.0.
Trace supports configuration based on config.
Sample configuration file:
[trace]
flags = ACTIVE | FAIL
;flags = ACTIVE | BEFORE | AFTER | FAIL
classes = trace_ChannelManager, trace_Channel, trace_TextIOServiceImpl, trace_PipeServerHandler
[trace_PipeServerHandler]
source = saturnin.core.protocol.fbdp.PipeServerHandler
methods = close, send_ready, send_close
[trace_ChannelManager]
source = saturnin.core.base.ChannelManager
special = trace_defer
[trace_Channel]
source = saturnin.core.base.Channel
methods = send, receive, close, bind, unbind, connect, disconnect
[trace_DealerChannel]
source = saturnin.core.base.DealerChannel
methods = send, receive, close, bind, unbind, connect, disconnect
[trace_SimpleService]
source = saturnin.core.classic.SimpleService
methods = validate, run, initialize, start
with_args = no
[trace_TextIOServiceImpl]
source = saturnin.sdk.micro.textio.service.TextIOServiceImpl
methods = initialize, configure, validate, finalize
with_args = no
[trace_defer]
method = defer
max_param_length = 50
See also
load_config(), BaseTraceConfig,
TracedMethodConfig, TracedClassConfig and
TraceConfig.
Enums & Flags¶
- class firebird.base.trace.TraceFlag(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Bases:
IntFlagFlags controlling the behavior of the
traceddecorator andTraceManager.These flags determine whether tracing is active and which parts of a call (before, after success, after failure) should be logged.
- ACTIVE = 1¶
Master switch; tracing is performed only if ACTIVE is set.
- AFTER = 4¶
Log message after the decorated callable successfully returns.
- BEFORE = 2¶
Log message before the decorated callable executes.
- FAIL = 8¶
Log message if the decorated callable raises an exception.
- NONE = 0¶
No tracing enabled by default flags.
Functions¶
- firebird.base.trace.add_trace(cls: type, method: str, /, *args, **kwargs) None¶
Shortcut for
trace_manager.add_trace()
- firebird.base.trace.remove_trace(cls: type, method: str) None¶
Shortcut for
trace_manager.remove_trace()
Trace manager¶
- class firebird.base.trace.TraceManager[source]¶
Bases:
objectTrace manager.
- add_trace(cls: type, method: str, /, *args, **kwargs) None[source]¶
Store or update the trace specification for a specific class method.
Registers how a method should be decorated (using
self.decorator) whentrace_objectis called on an instance ofclsor its registered descendants. This specification can be overridden or augmented by settings loaded viaload_config.
- clear_flag(flag: TraceFlag) None[source]¶
Clear flag specified by
flagmask.- Parameters:
flag (TraceFlag) –
- Return type:
None
- load_config(config: ConfigParser, section: str = 'trace') None[source]¶
Load and apply trace configurations from a
ConfigParserinstance.Parses the specified
section(and referenced sub-sections) using theTraceConfig,TracedClassConfig, andTracedMethodConfigstructures. Updates theTraceManager’s flags and trace specifications (add_trace).- Parameters:
config (ConfigParser) –
ConfigParserinstance containing the trace configuration.section (str) – Name of the main trace configuration section (default: ‘trace’).
- Return type:
None
Note
This method adds to or updates existing trace specifications. It does not clear previous configurations unless the loaded configuration explicitly overwrites specific settings.
- Raises:
Error – If configuration references a class that is not registered and
autoregisteris False, or if the class cannot be loaded viaload().KeyError, ValueError – If the configuration file structure is invalid or contains invalid values according to the
Optiontypes.
- Parameters:
config (ConfigParser) –
section (str) –
- Return type:
None
- register(cls: type) None[source]¶
Register class for trace.
- Parameters:
cls (type) – Class to be registered.
- Return type:
None
Does nothing if class is already registered.
- set_flag(flag: TraceFlag) None[source]¶
Set flag specified by
flagmask.- Parameters:
flag (TraceFlag) –
- Return type:
None
- trace_object(obj: Any, *, strict: bool = False) Any[source]¶
Apply registered trace decorators to the methods of an object instance.
Iterates through the trace specifications (
TracedItem) registered for the object’s class (viaadd_traceorload_config). For each specification, it wraps the corresponding method on theobjinstance using the specified decorator and arguments. Modifies the object in place.- Parameters:
- Returns:
The (potentially modified) object instance
obj.- Raises:
TypeError – If
obj’s class is not registered andstrictis True.- Return type:
Trace/audit decorator¶
- class firebird.base.trace.traced(*, agent: Any | DEFAULT = DEFAULT, topic: str = 'trace', msg_before: str | DEFAULT = DEFAULT, msg_after: str | DEFAULT = DEFAULT, msg_failed: str | DEFAULT = DEFAULT, flags: TraceFlag = TraceFlag.NONE, level: LogLevel = LogLevel.DEBUG, max_param_length: int | UNLIMITED = UNLIMITED, extra: dict | None = None, callback: Callable[[Any], bool] | None = None, has_result: bool | DEFAULT = DEFAULT, with_args: bool = True)[source]¶
Bases:
objectDecorator factory for adding trace/audit logging to callables.
Creates a decorator that wraps a function or method to log messages before execution, after successful execution, and/or upon failure, based on configured flags and messages. Integrates with the
firebird.base.loggingcontext logger.Note
The decorator is only applied if tracing is globally enabled via the
FBASE_TRACEenvironment variable or if__debug__is true (i.e., Python is not run with -O). If disabled globally, the original un-decorated function is returned. Runtime behavior (whether logs are actually emitted) is further controlled byTraceManager.flags.- Parameters:
agent (Any | DEFAULT) – Agent identifier for logging context (object or string). If
DEFAULT, usesselffor methods or'function'otherwise.topic (str) – Logging topic (default: ‘trace’).
msg_before (str | DEFAULT) – Format string (f-string style) for log message before execution. If
DEFAULT, a standard message is generated.msg_after (str | DEFAULT) – Format string for log message after successful execution. Available context includes
_etime_(execution time string) and_result_(return value, ifhas_resultis true). IfDEFAULT, a standard message is generated.msg_failed (str | DEFAULT) – Format string for log message on exception. Available context includes
_etime_and_exc_(exception string). IfDEFAULT, a standard message is generated.flags (TraceFlag) –
TraceFlagvalues to overrideTraceManager.flagsfor this specific decorator instance. Allows fine-grained control per traced callable.level (LogLevel) –
LogLevelfor trace messages (default:LogLevel.DEBUG).max_param_length (int | UNLIMITED) – Max length for string representation of parameters/result in logs. Longer values are truncated (default:
UNLIMITED).extra (dict | None) – Dictionary of extra data to add to the
LogRecord.callback (Callable[[Any], bool] | None) – Optional callable
func(agent) -> bool. If provided, it’s called before logging to check if tracing is permitted for this specific call.has_result (bool | DEFAULT) – Boolean or
DEFAULT. If True, include result inmsg_after. IfDEFAULT, inferred from function’s return type annotation (considered True unless annotation isNone).with_args (bool) – If True (default), make function arguments available by name for interpolation in
msg_before.
- log_after(logger: ContextLoggerAdapter, params: dict) None[source]¶
Log the ‘after’ message using the configured template and logger.
- Parameters:
logger (ContextLoggerAdapter) –
params (dict) –
- Return type:
None
- log_before(logger: ContextLoggerAdapter, params: dict) None[source]¶
Log the ‘before’ message using the configured template and logger.
- Parameters:
logger (ContextLoggerAdapter) –
params (dict) –
- Return type:
None
- log_failed(logger: ContextLoggerAdapter, params: dict) None[source]¶
Log the ‘failed’ message using the configured template and logger.
- Parameters:
logger (ContextLoggerAdapter) –
params (dict) –
- Return type:
None
- set_after_msg(fn: Callable, sig: Signature) None[source]¶
Generate the default log message template for successful execution.
- set_before_msg(fn: Callable, sig: Signature) None[source]¶
Generate the default log message template for before execution.
- set_fail_msg(fn: Callable, sig: Signature) None[source]¶
Generate the default log message template for failed execution.
- callback: Callable[[Any], bool]¶
Callback function that gets the agent identification as argument, and must return True/False indicating whether trace is allowed.
- has_result: bool | DEFAULT¶
Indicator whether function has result value. If True,
_result_is available for interpolation inmsg_after.
- with_args: bool¶
If True, function arguments are available for interpolation in
msg_before
Mixins¶
- class firebird.base.trace.TracedMixin(*args, **kwargs)[source]¶
Bases:
objectMixin class to automatically enable tracing for descendants.
Subclasses inheriting from
TracedMixinare automatically registered with thetrace_managerupon definition. When instances of these subclasses are created, their methods are automatically instrumented bytrace_objectaccording to the currently active trace specifications in thetrace_manager.
Globals¶
- firebird.base.trace.trace_manager: TraceManager¶
Trace manager singleton instance.
Trace configuration classes¶
- class firebird.base.trace.BaseTraceConfig(name: str)[source]¶
Bases:
ConfigBase class defining common configuration options for trace settings.
Used as a base for global trace config, per-class config, and per-method config. Corresponds typically to settings within a section of a configuration file.
- Parameters:
name (str) –
- flags: FlagOption¶
Trace flags override
- has_result: BoolOption¶
Indicator whether function has result value
- level: EnumOption¶
Logging level for trace/audit messages
- with_args: BoolOption¶
If True, function arguments are available for interpolation in
msg_before
- class firebird.base.trace.TracedMethodConfig(name: str)[source]¶
Bases:
BaseTraceConfigDefines the structure for a configuration section specifying trace settings specific to a single class method.
Used within
TracedClassConfig.speciallist. The section name itself is referenced in the parentTracedClassConfigsection.- Parameters:
name (str) –
- class firebird.base.trace.TracedClassConfig(name: str)[source]¶
Bases:
BaseTraceConfigDefines the structure for a configuration section specifying trace settings for a Python class and its methods.
The section name itself is referenced in the main
TraceConfigsection. See the module documentation for an example INI structure.- Parameters:
name (str) –
- apply_to_descendants: BoolOption¶
True].
- Type:
Wherher configuration should be applied also to all registered descendant classes [default
- methods: ListOption¶
Names of traced class methods
- special: ConfigListOption¶
Configuration sections with extended config of traced class methods
- class firebird.base.trace.TraceConfig(name: str)[source]¶
Bases:
BaseTraceConfigDefines the structure for the main trace configuration section (typically ‘[trace]’).
Holds global default trace settings and lists the sections defining specific traced classes. See the module documentation for an example INI structure.
- Parameters:
name (str) –
- autoregister: BoolOption¶
True].
- Type:
When True, unregistered classes are registered automatically [default
- classes: ConfigListOption¶
Configuration sections with traced Python classes [required].
Dataclasses¶
- class firebird.base.trace.TracedItem(method: str, decorator: ~collections.abc.Callable, args: list[~typing.Any] = <factory>, kwargs: dict[str, ~typing.Any] = <factory>)[source]¶
Bases:
DistinctHolds the trace specification for a single method within a registered class.
Stored by
TraceManagerfor each method configured viaadd_traceorload_config. Applied bytrace_object.- Parameters:
- class firebird.base.trace.TracedClass(cls: type, traced: ~firebird.base.collections.Registry = <factory>)[source]¶
Bases:
DistinctRepresents a class registered for tracing within the
TraceManager.Holds a registry (
Registry[TracedItem]) of trace specifications for methods belonging to this class.- Parameters:
cls (type) – The class type registered for tracing.
traced (Registry) – A registry mapping method names to
TracedItemspecifications.
- traced: Registry¶
A registry mapping method names to
TracedItemspecifications.