@@ -118,6 +118,77 @@ belong to default domain specifid in `.LoggingManager.default_domain`, which is
118118It's also possible to change agent identification used for logger name mapping porposes to
119119different value with `.set_agent_mapping` function.
120120
121+ Lazy Formatting Messages
122+ ------------------------
123+ This module also provides message wrapper classes (`FStrMessage`, `BraceMessage`,
124+ `DollarMessage`) that defer string formatting until the log record is actually
125+ processed by a handler. This avoids the performance cost of formatting messages
126+ that might be filtered out due to log levels.
127+
128+ Basic Setup Example
129+ -------------------
130+
131+ .. code-block:: python
132+
133+ import logging
134+ from firebird.base.logging import (
135+ get_logger, LogLevel, ContextFilter, logging_manager,
136+ DOMAIN, TOPIC # For logger_fmt
137+ )
138+
139+ # 1. Configure standard logging (handlers, formatters)
140+ log_format = "[%(levelname)-8s] %(asctime)s %(name)s (%(agent)s) - %(message)s"
141+ formatter = logging.Formatter(log_format)
142+ handler = logging.StreamHandler()
143+ handler.setFormatter(formatter)
144+
145+ # 2. Add ContextFilter to handler(s) to ensure context fields exist
146+ handler.addFilter(ContextFilter())
147+
148+ # 3. Get the root logger or specific standard loggers and add the handler
149+ root_logger = logging.getLogger()
150+ root_logger.addHandler(handler)
151+ root_logger.setLevel(LogLevel.DEBUG) # Use LogLevel enum or logging constants
152+
153+ # 4. (Optional) Configure logging_manager mappings
154+ logging_manager.logger_fmt = ['app', DOMAIN, TOPIC] # Logger name format
155+ logging_manager.default_domain = 'web' # Default domain if not mapped
156+ logging_manager.set_domain_mapping('db', ['myapp.database.Connection']) # Map agent to domain
157+
158+ # 5. Use in your code
159+ class RequestHandler:
160+ _agent_name_ = 'myapp.web.RequestHandler' # Optional explicit agent name
161+ log_context = None # Can be set per request, e.g., client IP
162+
163+ def handle(self, request_id):
164+ self.log_context = f"ReqID:{request_id}"
165+ logger = get_logger(self, topic='requests') # Get context logger
166+ logger.info("Handling request...")
167+ # ... processing ...
168+ logger.debug("Request handled successfully.")
169+
170+ class DbConnection:
171+ _agent_name_ = 'myapp.database.Connection'
172+ log_context = None # e.g., DB user
173+
174+ def query(self, sql):
175+ self.log_context = "user:admin"
176+ logger = get_logger(self) # Use default topic (None)
177+ logger.debug("Executing query: %s", sql) # Standard formatting works too
178+ # ... execute ...
179+
180+ # --- Execution ---
181+ handler_instance = RequestHandler()
182+ db_conn = DbConnection()
183+
184+ handler_instance.handle("12345")
185+ db_conn.query("SELECT * FROM T")
186+
187+ # --- Example Output ---
188+ # [INFO ] 2023-10-27... app.web.requests (myapp.web.RequestHandler) - Handling request...
189+ # [DEBUG ] 2023-10-27... app.web.requests (myapp.web.RequestHandler) - Request handled successfully.
190+ # [DEBUG ] 2023-10-27... app.db (myapp.database.Connection) - Executing query: SELECT * FROM T
191+
121192Enums & Flags
122193=============
123194.. autoclass:: FormatElement
0 commit comments