stratified_packager.toolbelt.logging_records
Record-level machinery for the QGIS logging suite: targets, filters, configs, level mapping.
The dependency-free lower layer of logging: the Target routing flag, the
QgisContextFilter / TargetFilter filters, the MessageBarConfig
/ MessageBoxConfig per-target configs, the EmitPayload cross-thread
snapshot, the SUCCESS level and the level_to_qgis() mapping.
QgisHandler and QgisLoggerWrapper build on these;
nothing here depends on the handler or wrapper, so the import edge runs one way only.
Module Attributes
Custom logging level between |
Functions
|
Convert a stdlib logging level to the nearest |
Classes
|
Immutable snapshot of everything needed to render a log record on the main thread. |
|
Configuration for the |
|
Configuration for the |
|
A |
|
Bit-flag enum selecting which QGIS outputs receive log records. |
|
|
- class stratified_packager.toolbelt.logging_records.EmitPayload(targets, plugin_name, tag, message, level, bar_config, box_config)[source]
Immutable snapshot of everything needed to render a log record on the main thread.
Constructed inside
emit()(possibly on a worker thread) and consumed by_render(). Per-call overrides — if present on the record — take precedence over the handler’s own defaults before this object is built, so the render path never needs to inspect the record again.- Parameters:
targets (
Target)plugin_name (
str)tag (
str)message (
str)level (
int)bar_config (
MessageBarConfig)box_config (
MessageBoxConfig)
- __init__(targets, plugin_name, tag, message, level, bar_config, box_config)
- Parameters:
targets (
Target)plugin_name (
str)tag (
str)message (
str)level (
int)bar_config (
MessageBarConfig)box_config (
MessageBoxConfig)
- bar_config: MessageBarConfig
Resolved
MessageBarConfigfor this record.
- box_config: MessageBoxConfig
Resolved
MessageBoxConfigfor this record.
- tag: str
Tag / topic for
qgis.core.QgsMessageLog.
- class stratified_packager.toolbelt.logging_records.MessageBarConfig(duration=5, buttons=<factory>, show_progress=False, progress_value=0, progress_format='%p%')[source]
Configuration for the
qgis.gui.QgsMessageBartarget.- Parameters:
- __init__(duration=5, buttons=<factory>, show_progress=False, progress_value=0, progress_format='%p%')
- buttons: list[qgis.PyQt.QtWidgets.QPushButton]
Extra
QPushButtoninstances to embed in the bar.They are created by the caller and passed here so that signal connections can be set up before the bar shows them.
- progress_format: str = '%p%'
Format string for the progress bar.
Passed to
setFormat()(e.g."%p%").
- show_progress: bool = False
Whether the message bar shows a progress indicator.
When
True, aQProgressBaris added to the bar widget.
- class stratified_packager.toolbelt.logging_records.MessageBoxConfig(title=None, standard_buttons=qgis.PyQt.QtWidgets.QMessageBox.StandardButton.Ok, default_button=qgis.PyQt.QtWidgets.QMessageBox.StandardButton.Ok, detailed_text=None)[source]
Configuration for the
QMessageBoxtarget.- Parameters:
standard_buttons (
StandardButton)default_button (
StandardButton)
- __init__(title=None, standard_buttons=qgis.PyQt.QtWidgets.QMessageBox.StandardButton.Ok, default_button=qgis.PyQt.QtWidgets.QMessageBox.StandardButton.Ok, detailed_text=None)
- Parameters:
standard_buttons (
StandardButton)default_button (
StandardButton)
- default_button: qgis.PyQt.QtWidgets.QMessageBox.StandardButton
The button that receives focus by default.
- detailed_text: str | None = None
Optional detailed-text string shown via the Show Details expander.
- standard_buttons: qgis.PyQt.QtWidgets.QMessageBox.StandardButton
Combination of
StandardButtonflags to display.
- title: str | None = None
Window title of the dialog.
When
None, the plugin name supplied toQgisHandleris used.
- class stratified_packager.toolbelt.logging_records.QgisContextFilter(static_fields=None, name='', iface=None)[source]
A
logging.Filterthat stamps QGIS context and static fields onto records.Attach this filter to a
logging.Logger(or to any of its handlers) to have the fields below stamped onto everylogging.LogRecordautomatically, without any changes to call sites.Dynamic fields (evaluated lazily at emit time):
qgis_versionThe running QGIS version string (e.g.
"4.2.0-Belém do Pará").qgis_project_pathAbsolute path of the currently open project file, or an empty string if no project is loaded.
qgis_active_layer_idID of the layer currently selected in the layer panel, or an empty string when no layer is active or
ifaceisNone.qgis_localeThe QGIS UI locale string (e.g.
"pt_BR").
Static fields (set once at construction, stamped on every record):
Any key/value pairs passed via static_fields are merged onto every record verbatim. This is the intended replacement for call-site
extra=dicts: plugin-level constants such as a plugin version, task name, or environment tag belong here rather than being repeated on everylog.info(...)call. Static fields are stamped before dynamic fields, so dynamic fields take precedence on name collision.Example:
log = QgisLoggerWrapper.get_logger("MyPlugin") context_filter = QgisContextFilter(static_fields={"plugin_version": "1.4.2"}, iface=iface) log.logger.addFilter(context_filter) # Every record now carries qgis_version, qgis_project_path, # qgis_active_layer_id, qgis_locale, and plugin_version. log.info("Processing started.") # Per-record context that varies per call still goes in extra=. log.warning("Bad geometry.", extra={"feature_id": feat.id()})
- Parameters:
static_fields (dict[str, object] | None)
name (str)
iface (QgisInterface | None)
- __init__(static_fields=None, name='', iface=None)[source]
Initialize the filter.
- Parameters:
static_fields (dict[str, object] | None) – Plugin-level constant attributes to stamp on every record (e.g.
{"plugin_version": "1.4.2", "task": "import"}). Keys must not clash with standardlogging.LogRecordattributes.name (str) – Passed to
logging.Filter; restricts the filter to records from loggers whose name starts with this prefix. An empty string (the default) matches all loggers.iface (QgisInterface | None) – The QGIS interface instance, used to obtain the active layer id.
- filter(record)[source]
Stamp static and dynamic QGIS context fields onto record.
This filter never blocks records — it always returns
True. Static fields supplied at construction time are applied first; dynamic QGIS fields are applied second and take precedence on name collision.- Parameters:
record (
LogRecord) – Thelogging.LogRecordto enrich.- Return type:
- Returns:
Always
True.
- _iface: QgisInterface | None
- class stratified_packager.toolbelt.logging_records.Target(*values)[source]
Bit-flag enum selecting which QGIS outputs receive log records.
Members can be combined with
|:Target.LOG | Target.BAR
- static _generate_next_value_(name, start, count, last_values)
Generate the next value when not given.
name: the name of the member start: the initial start value or None count: the number of existing members last_values: the last value assigned or None
- BAR = 2
Route to
qgis.gui.QgsMessageBar.
- DIALOG = 4
Route to a
QMessageBoxmodal dialog.
- LOG = 1
Route to
qgis.core.QgsMessageLog.
- _all_bits_ = 7
- _boundary_ = 'strict'
- _flag_mask_ = 7
- _inverted_ = None
- _singles_mask_ = 7
- class stratified_packager.toolbelt.logging_records.TargetFilter(allowed_targets, min_level=0, name='')[source]
logging.Filterthat gates records based onTargetand minimum logging level.Intended to be attached to a
QgisHandler.This filter expresses permanent, handler-level routing rules — complementing the per-call overrides available through
QgisLoggerWrappermethods. A typical use is to restrict aQgisHandlerconfigured withTarget.DIALOGto only show modal dialogs forERRORand above, while the same handler (or a sibling one) routesINFOandWARNINGrecords to the message bar or log panel.When the record carries a per-call
Targetoverride (injected byQgisLoggerWrapper), that override is compared against allowed_targets: the record is allowed through only if the two share at least one flag in common. Records emitted by a plainlogging.Logger(no override) are always allowed through, since target routing is the handler’s responsibility in that case.Example — restrict a DIALOG handler to errors only:
handler = QgisHandler( plugin_name="MyPlugin", targets=Target.DIALOG, box_config=MessageBoxConfig(title="Error"), ) handler.addFilter( TargetFilter( allowed_targets=Target.DIALOG, min_level=logging.ERROR, ) )
Example — a BAR handler that ignores records explicitly routed elsewhere:
bar_handler = QgisHandler( plugin_name="MyPlugin", targets=Target.BAR, bar=iface.messageBar(), ) bar_handler.addFilter(TargetFilter(allowed_targets=Target.BAR))
- __init__(allowed_targets, min_level=0, name='')[source]
Initialize the filter.
- Parameters:
allowed_targets (
Target) – TheTargetflags this handler is permitted to process. Records whose per-call target override shares no flag with this value are dropped.min_level (
int) – Minimumlogginglevel to allow through. Records below this level are dropped regardless of target. Defaults tologging.NOTSET(no additional level gate beyond the logger’s own).name (
str) – Passed tologging.Filter; restricts the filter to records from loggers whose name starts with this prefix.
- filter(record)[source]
Allow the record through only if it passes both gates.
The two gates, applied in order:
Level gate — the record’s level must be
>=min_level.Target gate — if the record carries a per-call
Targetoverride, it must share at least one flag withallowed_targets. Records without an override always pass this gate.
- Parameters:
record (
LogRecord) – Thelogging.LogRecordto evaluate.- Return type:
- Returns:
Trueif the record should be processed,Falseif it should be silently dropped.
- stratified_packager.toolbelt.logging_records._qmsgbox_icon(level)[source]
Return the
Iconfor a stdlib logging level.Delegates to
level_to_qgis()and then looks up the result in_QGIS_TO_QMSGBOX_ICON, so the two mappings stay in sync.- Parameters:
level (
int) – Numeric stdlib level (e.g.logging.WARNING).- Return type:
- Returns:
The corresponding
Icon.
- stratified_packager.toolbelt.logging_records.level_to_qgis(level)[source]
Convert a stdlib logging level to the nearest
qgis.core.Qgis.MessageLevel.- Parameters:
level (
int) – Numeric stdlib level (e.g.logging.WARNING) orSUCCESS.- Return type:
- Returns:
The closest matching
qgis.core.Qgis.MessageLevel.
- stratified_packager.toolbelt.logging_records.SUCCESS: Final = 25
Custom logging level between
logging.INFOandlogging.WARNING.Intended for successful operations that deserve user attention.
- stratified_packager.toolbelt.logging_records._K_BAR_CFG: Final = '_qgis_bar_config'
Key under which a per-call
MessageBarConfigoverride is stored.
- stratified_packager.toolbelt.logging_records._K_BOX_CFG: Final = '_qgis_box_config'
Key under which a per-call
MessageBoxConfigoverride is stored.
- stratified_packager.toolbelt.logging_records._K_TARGETS: Final = '_qgis_targets'
Key under which a
Targetoverride is stored in the record’s__dict__.
- stratified_packager.toolbelt.logging_records._QGIS_TO_QMSGBOX_ICON: Final[dict[Qgis.MessageLevel, QMessageBox.Icon]] = {qgis.core.Qgis.MessageLevel.Critical: qgis.PyQt.QtWidgets.QMessageBox.Icon.Critical, qgis.core.Qgis.MessageLevel.Info: qgis.PyQt.QtWidgets.QMessageBox.Icon.Information, qgis.core.Qgis.MessageLevel.NoLevel: qgis.PyQt.QtWidgets.QMessageBox.Icon.NoIcon, qgis.core.Qgis.MessageLevel.Success: qgis.PyQt.QtWidgets.QMessageBox.Icon.Information, qgis.core.Qgis.MessageLevel.Warning: qgis.PyQt.QtWidgets.QMessageBox.Icon.Warning}
Per-level icon used for modal dialogs.
Maps each
qgis.core.Qgis.MessageLevelto aIcon.