Skip to content

Classify Dynatrace entity errors by status code and report proxy error bodies - #375

Merged
LouisParkin merged 3 commits into
stackstate-7.78.2from
dynatrace-403-classification-and-error-body
Sep 14, 2026
Merged

LouisParkin merged 3 commits into
stackstate-7.78.2from
dynatrace-403-classification-and-error-body

Conversation

@LouisParkin

Copy link
Copy Markdown
Contributor

Two defects found while investigating Rabobank's Dynatrace connectivity report (StackVista/stackstate#578).

The health check decided an entity was missing by looking for 404 in the exception message, which embeds the request URL. An entity id whose hex contains 404 was therefore read as a missing entity, marked its type problematic, and suppressed every later event of that type in the run. In the customer's logs that fired in 1165 of 1165 runs, silently dropping PROCESS_GROUP_INSTANCE events. The client now raises DynatraceApiError carrying the status code, and both call sites branch on that.

Separately, only a Dynatrace-shaped {"error": ...} envelope produced a useful message, so a proxy sitting in front of Dynatrace was reduced to a status code and a URL. The body is now appended when error is absent, collapsed to one line and capped at 500 chars. The JSON parse also ran before the status check, so a non-JSON error page raised a decode error rather than being reported — guarded for non-200 responses.

Worth knowing before merge: the first fix increases API call volume. The broken classification was accidentally suppressing work, so a persistently-rejecting environment goes from stopping after the first bad entity to one lookup per referencing event. The fix is still correct — it was dropping real events — but the log-volume symptom gets worse. Negative caching was considered and declined (#373 records why); a per-run 403 suppression would address it and is not in this PR.

Fixes #373
Fixes #374

Validation: dynatrace_base 18, dynatrace_health 28, dynatrace_topology 40 — all passing, flake8 clean. The health regression test was confirmed to fail without the classification fix.

The health check decided an entity was missing by looking for '404' in the exception message. That message embeds the request URL, so an entity id whose hex contains 404 was read as a missing entity, which marked its type problematic and suppressed every later event of that type in the run.

Both call sites shared one problematic-type set, so the misclassification also suppressed health-state creation. The client now raises DynatraceApiError carrying the status code.
Only a Dynatrace-shaped envelope produced a useful message, so a proxy in front of it was reduced to a status code and a URL. The body is now appended when the error field is absent, collapsed to one line and capped.

The JSON parse ran before the status check, so a non-JSON error page raised a decode error instead of being reported. It is now guarded for non-200 responses.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Message-based classification, malformed error envelopes, and possible credential disclosure remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds reliable Dynatrace HTTP error classification and improved proxy diagnostics.

Changes:

  • Introduces status-aware DynatraceApiError.
  • Reports truncated, single-line proxy response bodies.
  • Adds regression tests for entity suppression and error handling.
File summaries
File Description
dynatrace_health/tests/test_dynatrace_health.py Tests rejected-entity event handling.
dynatrace_health/stackstate_checks/dynatrace_health/dynatrace_health.py Classifies missing entities using API errors.
dynatrace_base/tests/test_dynatrace_client.py Tests status codes and response-body diagnostics.
dynatrace_base/stackstate_checks/dynatrace/dynatrace_client.py Adds typed errors and body excerpts.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread dynatrace_base/stackstate_checks/dynatrace/dynatrace_client.py
Comment thread dynatrace_base/stackstate_checks/dynatrace/dynatrace_client.py Outdated
Comment thread dynatrace_health/stackstate_checks/dynatrace_health/dynatrace_health.py Outdated
Redact credentials before truncating the excerpt: a gateway can reflect the request headers, and truncation does not stop the token reaching the log.

Tolerate a non-dict error value. A proxy answering {"error": "Forbidden"} raised AttributeError, bypassing both the typed error and the body fallback.

Require a typed 404 for entity-not-found. The message-text fallback let a transport failure reading 'host not found' suppress later events of the same type, which is the failure mode this branch set out to remove.
@LouisParkin
LouisParkin merged commit 103ca32 into stackstate-7.78.2 Sep 14, 2026
8 checks passed
@LouisParkin
LouisParkin deleted the dynatrace-403-classification-and-error-body branch September 14, 2026 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants