RSDK-10329: Apply log_configuration level on reconfigure for modular resources#1173
RSDK-10329: Apply log_configuration level on reconfigure for modular resources#1173claude[bot] wants to merge 1 commit intomainfrom
Conversation
…resources When a Reconfigurable resource was reconfigured, the log_configuration.level from the new config was not applied to the resource's logger. Only the non-Reconfigurable path (which re-adds the resource) applied the log level. This adds update_log_level() after reconfigure() in the Reconfigurable branch of reconfigure_resource(), so that clicking "Enable debug logs" in the UI actually takes effect. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
Summary
The fix is correct and minimal. The Reconfigurable branch of reconfigure_resource() was the only path missing a call to update_log_level. The non-Reconfigurable branch already worked because it delegates to add_resource, which already had the call. The added line exactly mirrors the existing call in add_resource and is in the right place (after reconfigure() so the new config is applied before the log level is updated).
update_log_level gracefully handles the default case — when log_configuration is absent, config.log_configuration.level returns "", "".upper() stays "", and update_log_level falls back to the global LOG_LEVEL. Behavior is therefore consistent with add_resource.
gen/ was not modified.
Observations (not blocking)
tests/test_module.py:172 — assert gizmo.logger.level != logging.DEBUG
This is a weak negative assertion. It passes if the level is WARNING, ERROR, NOTSET, or any value other than 10. A positive assertion like assert gizmo.logger.level == logging.INFO would more precisely document the expected initial state and catch any future regression where the default silently shifts to a different level.
tests/test_module.py:158–188 — Missing edge case: debug → (no log_configuration)
There is no test verifying that reconfiguring a resource from level="debug" to a config with no log_configuration resets the level back to INFO. The update_log_level empty-string path handles this correctly in the implementation, but it is not exercised. Adding this case would complete the coverage of the three transitions: none→debug, debug→debug, and debug→none.
|
@claude Why does reconfiguring a resource with removing log_configuration set it back to info? how are debug logs handled differently than other logs? |
|
Claude finished @allisonschiang's task in 1m 6s —— View job
Why removing
|
| Scenario | config.log_configuration.level |
level passed to update_log_level |
Logger + handler level set to | DEBUG messages emitted? |
|---|---|---|---|---|
| UI sets "Enable debug logs" | "debug" |
"DEBUG" |
DEBUG (10) |
✅ Yes |
log_configuration removed |
"" (proto default) |
"" |
LOG_LEVEL = INFO (20) |
❌ No — filtered at both logger and handler |
| Never set | "" |
"" |
LOG_LEVEL = INFO |
❌ No |
Because the logger level is the first gate, a logger.debug("…") call from a resource's code is checked against logger.level. If logger.level == INFO (20) and DEBUG == 10, the record is dropped immediately and never reaches the handlers. That's the core reason debug logs disappear when log_configuration is removed: update_log_level raises the threshold from 10 back to 20.
|
@claude makes sense, can you add this edge case tests/test_module.py:158–188 — Missing edge case: debug → (no log_configuration) |
|
Claude finished @allisonschiang's task in 1m 35s —— View job
Change ready but push blockedI've written and committed the new test locally, but the push was denied ( What the test does:
|
|
@claude try pushing your changes again |
|
Claude finished @allisonschiang's task in 58s —— View job
Push still blockedThe commit was created successfully locally, but the push is denied with the same This is a repository permission issue — the GitHub Actions bot token used to run this job doesn't have write access to To apply the change, please add the following test to async def test_reconfigure_resource_resets_log_level_to_default(self, module: Module):
# Add a resource with debug log level
req = AddResourceRequest(
config=ComponentConfig(
name="gizmo_reset_log",
namespace="acme",
type="gizmo",
model="acme:demo:mygizmo",
attributes=dict_to_struct({"arg1": "arg1", "motor": "motor1"}),
api="acme:component:gizmo",
log_configuration=LogConfiguration(level="debug"),
)
)
await module.add_resource(req)
gizmo = module.server.get_resource(MyGizmo, Gizmo.get_resource_name("gizmo_reset_log"))
assert gizmo.logger.level == logging.DEBUG
# Reconfigure without log_configuration — should reset to INFO
req = ReconfigureResourceRequest(
config=ComponentConfig(
name="gizmo_reset_log",
namespace="acme",
type="gizmo",
model="acme:demo:mygizmo",
attributes=dict_to_struct({"arg1": "arg2", "motor": "motor1"}),
api="acme:component:gizmo",
)
)
await module.reconfigure_resource(req)
assert gizmo.my_arg == "arg2"
assert gizmo.logger.level == logging.INFOYou may also want to check the FAQ for information on granting the bot write access. |
Summary
reconfigure_resource()inModuleto applylog_configuration.levelwhen reconfiguring aReconfigurableresource"log_configuration": {"level": "debug"}to the resource config, but the log level was never applied during reconfigure — only during initialadd_resourceadd_resourceandreconfigure_resourceDRI
@allisonschiang is the responsible engineer for this PR.
Test plan
test_add_resource_applies_log_level— verifies log level is set when adding a resource withlog_configurationtest_reconfigure_resource_applies_log_level— verifies log level is updated when reconfiguring aReconfigurableresource withlog_configuration🤖 Generated with Claude Code