Repository navigation
Add opt-in per-instrument logger scope (default_logger_scope) - #8523
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Logger identity collisions and mutable scope resolution can break the promised isolation and hierarchy.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 1
Open (5)
Use module-qualified identities for per-driver logger isolation · New Store scope at root initialization for all descendants · New Avoid ambient logging levels in class logger test · New Clarify propagate=False and separate VISA logger behavior · New Document permanent logging-registry growth caveat · New
What changed in this PR
Adds opt-in per-instrument logger hierarchies while preserving shared logging by default.
Changes:
- Adds configurable logger scope and hierarchical names.
- Applies scoped naming to VISA loggers.
- Adds tests, documentation, and a newsfragment.
| File | Description |
|---|---|
instrument_base.py |
Defines logger scopes and scoped-name generation. |
visa.py |
Applies scoped VISA logging. |
ip_to_visa.py |
Applies scoped logging to simulated VISA instruments. |
test_logger.py |
Tests scope, inheritance, filtering, and VISA behavior. |
logging_example.ipynb |
Documents scoped logger usage. |
8523.new |
Announces the feature. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
One or more custom setup steps configured for this repository failed during this Copilot code review run: Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review. Note You can configure setup steps for Copilot code review separately from Copilot cloud agent with a |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8523 +/- ##
==========================================
+ Coverage 72.20% 72.36% +0.16%
==========================================
Files 307 307
Lines 32326 32386 +60
==========================================
+ Hits 23340 23436 +96
+ Misses 8986 8950 -36 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The permanent logging registry growth under the "instrument" scope was only described in the PR discussion, not in the user facing documentation. Add it to the caveats of the logging example notebook, together with the mitigation that instruments with stable names reuse their existing logger. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2a787d42-150d-48cb-8bc7-47add23e17ad
|
|
@microsoft-github-policy-service agree company="Microsoft" |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2a787d42-150d-48cb-8bc7-47add23e17ad
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2a787d42-150d-48cb-8bc7-47add23e17ad



Closes #8522
Summary
Every instrument currently shares one
logging.Loggerobject becauseInstrumentBase.__init__uses the module nameqcodes.instrument.instrument_base. VISA communication similarly uses theshared
qcodes.instrument.instrument_base.com.visalogger.This PR lets a driver opt in to module-qualified, per-instrument logger
hierarchies:
QCoDeS only selects logger names. It does not set levels, attach handlers, or
change
propagate; those remain application and driver policy.The default behavior is unchanged. Drivers that do not opt in continue to
use:
Final logger hierarchy
For a scoped instrument, the instrument logger is the parent of everything
belonging to that instrument: its submodules and its VISA traffic.
For the example driver used in the logging notebook:
This means setting the level or adding a handler at:
covers the instrument's own records, its VISA communication, and all of its
submodules. The VISA or submodule logger can still be configured more
specifically when needed.
For a packaged QCoDeS driver, the same structure starts with its defining
module and qualified class name. For example:
Because the class logger is also an ancestor, a level can be configured before
any instruments exist:
How names are selected
InstrumentBase._logger_namereceives the existing shared logger name as arequired fallback:
Regular instrument and module logging calls
_logger_name(__name__). VISAlogging calls
_logger_name(VISA_LOGGER, "com", "visa").For an unscoped driver,
_logger_nameimmediately returns__name__orVISA_LOGGER, preserving the existing names. For a scoped driver, the name isassembled from:
com.visa.The scope is resolved and stored once when the root instrument is initialized.
All channels and later-added submodules read the stored value from
root_instrument, preventing the hierarchy from splitting if the classattribute changes later.
Design notes
Why module plus qualified class name. A class name alone is not unique.
Drivers with the same class name in different modules receive distinct logger
trees.
Why the class comes from
root_instrument. Usingtype(self)would place achannel under its channel class rather than under its instrument. Using the root
class keeps the whole hierarchy together.
Why registration keys rather than types for submodules. The key passed to
add_submodule, such asswitch_heater, identifies the component as exposedby the driver. This distinguishes multiple channels of the same type. A
channel that only exists in a channel list falls back to its own name.
Why individual hierarchy parts rather than
full_name. Joining the partswith
.makes each submodule logger a real descendant of its parent logger.Why VISA follows the instrument name. Placing
com.visabelow theinstrument logger makes one instrument-level setting cover driver messages,
submodules, and wire traffic, while still allowing VISA traffic to be
configured independently.
Documented caveats
qcodes.instrument.instrument_basehierarchy andtherefore no longer inherit levels configured there or on its shared
com.visalogger.qcodes, for exampleqcodes_contrib_driversor__main__.<locals>in__qualname__.%(name)soutput field.Changes
src/qcodes/instrument/instrument_base.pysrc/qcodes/instrument/visa.py,ip_to_visa.pytests/test_logger.pydocs/examples/logging/logging_example.ipynbdocs/changes/newsfragments/8523.newValidation
.venv\Scripts\python.exe -m pytest tests\test_logger.py— 39 passed..venv\Scripts\python.exe -m pytest tests --reruns 1— 3262 passed,268 skipped.
.venv\Scripts\pyright.exe --pythonpath .venv\Scripts\python.exe— 0 errors,0 warnings.
pre-commit run --all— all hooks passed.docs/examples/logging/logging_example.ipynb— executed successfully end toend.