Cache failed Dynatrace entity lookups for the duration of a check run - #377
Conversation
Only successful lookups were cached, so every event referencing an unreachable entity cost a request. Over 97h of customer logs that was 12286 requests where 7211 would have done. The cache is reset each run, so an entity that becomes reachable is picked up on the next check. Persistent negative caching was declined for that reason and is not what this does. Removes the PROCESS_GROUP_INSTANCE skip this makes redundant. That special case also dropped events for entities that had not themselves failed, so one deleted entity blinded the run to the whole type.
There was a problem hiding this comment.
🟡 Changes recommended
Reusing cached exception objects causes their traceback chains to grow on every cache hit.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Caches failed Dynatrace entity lookups per check run, reducing duplicate requests without persisting failures across runs.
Changes:
- Caches and re-raises failed entity lookups.
- Removes
PROCESS_GROUP_INSTANCEtype-wide suppression. - Adds regression tests for request caching and independent entity processing.
File summaries
| File | Description |
|---|---|
dynatrace_health.py |
Implements run-scoped failure caching and removes type suppression. |
test_dynatrace_health.py |
Tests failed lookup caching and continued same-type processing. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Self-review notes before this goes further. One real defect, one cosmetic, one thing worth recording. Traceback growth on the cached exception. This is worst exactly where the change is aimed: the 7211 avoidable lookups in the description are repeats on a few dead entities, so one cached exception can accumulate thousands of frames in a single run of a long-lived agent. The fix has to keep the object rather than rebuild it, because if isinstance(cached, Exception):
cached.__traceback__ = None
raise cachedAsymmetric reset in Two 404 tallies now mean different things. Checked and holding up, so a reviewer need not re-derive:
|
Clear the previous traceback before raising a cached lookup failure so repeated events do not retain a growing chain of frames. Extend the request-deduplication regression test to check that only one lookup frame remains.
_get_entity_definitioncached only successful lookups, so every event referencing an unreachable entity cost a request. Over 97h of customer logs that was 12286 requests where 7211 would have done — 41% avoidable, and all 1165 runs re-queried at least one failing entity more than once.The cache is reset each run, so an entity that becomes reachable again is picked up on the next check a few minutes later. This is not the persistent negative caching that was declined in StackVista/stackstate#578; only the within-run repeats go away.
Also removes the
PROCESS_GROUP_INSTANCEskip this makes redundant. Worth a look from a reviewer: that special case was still losing data after #373, because a genuine 404 on one entity dropped every otherPROCESS_GROUP_INSTANCEevent in the run, including entities that had never failed.test_missing_entity_does_not_suppress_typecovers it.One changed number to expect:
get_entity_404_summary()now counts once per entity per run rather than once per referencing event.Fixes #376
Validation:
dynatrace_base22,dynatrace_health31,dynatrace_topology40 — all passing, flake8 clean. The caching test was confirmed to fail without the change.