Skip to content

[App Service] az webapp troubleshoot config: provide application config evaluation summary#33709

Draft
aamos-company wants to merge 17 commits into
Azure:devfrom
aamos-company:developer/amberamos/configtroubleshootcommand
Draft

[App Service] az webapp troubleshoot config: provide application config evaluation summary#33709
aamos-company wants to merge 17 commits into
Azure:devfrom
aamos-company:developer/amberamos/configtroubleshootcommand

Conversation

@aamos-company

@aamos-company aamos-company commented Jul 7, 2026

Copy link
Copy Markdown

Related command

az webapp troubleshoot config
az webapp troubleshoot status

Description

Introduces the az webapp troubleshoot config for diagnosing Linux web apps without leaving the terminal.

az webapp troubleshoot config

Runs the KuduLite built-in configuration checks and pairs them with the most recent runtime error from ARM.

Data sources

• Configuration diagnostics — KuduLite GET https://{scm-host}/api/troubleshoot/config
• Site runtime error — ARM GET .../sites/{name}[/slots/{slot}]/siteStatus?api-version=2024-11-01

What it surfaces

• Every setting KuduLite evaluated with its value, details message, and severity (info/warning/error).
• A separate "Site runtime error recommendation" section that appears only when the last ARM error is within the last 15 minutes, so stale errors don't pollute the output.
• Prints a single-line "Configuration check feature is currently unavailable." message when the SCM /api/troubleshoot /config endpoint returns 404 (older KuduLite builds), then still renders the runtime-error section if a fresh error is available.

Output modes (both commands)

• Default: structured JSON/YAML/TSV payload — the standard CLI formatters handle it.
• -o table : focused per-instance / per-setting projection with - for empty cells; the status table also prints an "▶ Hint:" trailer with the recommended az webapp log tail / az webapp log startup show follow-ups when at least one instance shows a visible error.
• --report : full color-coded human-readable report, rendered by the new _troubleshoot_status_report.py / _troubleshoot_config_report.py helper modules so custom.py stays focused on the command's control flow.

Testing Guide
See screenshots below

This checklist is used to make sure that common guidelines for a pull request are followed.

@azure-client-tools-bot-prd

Copy link
Copy Markdown
Validation for Azure CLI Full Test Starting...

Thanks for your contribution!

@azure-client-tools-bot-prd

Copy link
Copy Markdown
Validation for Breaking Change Starting...

Thanks for your contribution!

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@aamos-company aamos-company changed the title [App Service] az webapp troubleshoot config: provide latest application startup attempt data [App Service] az webapp troubleshoot config: provide application config diagnosis Jul 7, 2026
@microsoft-github-policy-service microsoft-github-policy-service Bot added the customer-reported Issues that are reported by GitHub users external to the Azure organization. label Jul 7, 2026
@microsoft-github-policy-service

Copy link
Copy Markdown
Contributor

Thank you for your contribution @aamos-company! We will review the pull request and get back to you soon.

@aamos-company aamos-company changed the title [App Service] az webapp troubleshoot config: provide application config diagnosis [App Service] az webapp troubleshoot config: provide application config evaluation summary Jul 7, 2026
@yonzhan

yonzhan commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

App Service

aamos-company and others added 12 commits July 8, 2026 13:56
…t mode

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t rendered

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add extra blank line above SITE RUNTIME ERROR RECOMMENDATION.
- Render 'No runtime error reported.' in primary (white) instead of green.
- Reword SCM failure message to lead with retry before restart.
- Drop trailing horizontal rule at end of report.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Retry SCM config fetch on transient 5xx / connection errors (3 attempts, 1.5s backoff).
- Read KuduLite's new DetailsLevel field (info/warning/error) with legacy IssueDetected fallback; map to SUCCESS/WARNING/ERROR styles.
- Restyle the built-in checks table: HIGHLIGHT header, SECONDARY underlines, per-row Details colored by level.
- Wrap Details column so long values hang-indent under the Details column instead of overflowing.
- Runtime error section: hanging-indent wrapping for State / Last Error / Last Error Details / Last Error Timestamp, plus relative age (e.g. '2h 18m ago') next to the timestamp.
- Gate runtime section on last-error-within-15-min OR config-check-failed (never on stale flagged settings alone).
- Add 'Hint:' footer with az webapp config appsettings set / az webapp config set / az webapp log tail commands when any check is warning/error.
- _help.py: drop KuduLite / ARM implementation details from the long-summary and reword for consistency.
- Tests: add transient-5xx retry cases, config-check-failed keeps runtime section case; refresh stale-timestamp fixtures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: da04b3ec-d5e4-4ab8-aeea-58dd7010ac84
KuduLite now always emits DetailsLevel (info|warning|error) for every check, so the IssueDetected string flag is no longer part of the contract. Removing the legacy fallback in _details_level to keep the mapping single-sourced.

- custom.py: _details_level reads only DetailsLevel/detailsLevel (defaults to 'info'); dropped the IssueDetected/issueDetected fallback branch.

- custom.py: refreshed the stale comment above the runtime section to match the current show_runtime gating (fresh ARM error OR config fetch failed).

- tests: migrated three test fixtures from IssueDetected: 'False'/'True' to DetailsLevel: 'info'/'warning' so they exercise the current contract.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: da04b3ec-d5e4-4ab8-aeea-58dd7010ac84
Previously the SITE RUNTIME ERROR RECOMMENDATION section would render whenever the built-in config check fetch failed, regardless of how old the ARM lastErrorTimestamp was. This produced inconsistent output: a 3-hour-old runtime error would surface on the attempt where SCM failed but not on adjacent successful attempts against the same site.

The section now renders if and only if lastErrorTimestamp is within the last 15 minutes, applied uniformly whether the built-in checks succeeded, failed, or reported no issues. A stale error should not be resurrected just because the SCM fetch timed out.

- custom.py: show_runtime = _last_error_within(15); dropped the 'or config_check_failed' short-circuit.

- custom.py: refreshed comments on both the assignment and the section header.

- tests: rewrote test_troubleshoot_config_report_shows_runtime_when_config_check_failed to use a fresh timestamp; added test_troubleshoot_config_report_suppresses_runtime_when_config_check_failed_and_error_is_stale as its negative counterpart.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: da04b3ec-d5e4-4ab8-aeea-58dd7010ac84
… 404

When the SCM built-in-check endpoint returns 404 the site is on a stamp where the KuduLite config-check route hasn't rolled out yet -- there is no actionable remediation the user can take, so the verbose 'retry-and-restart' guidance is misleading. Replace it with a compact, definitive message.

- custom.py: added 'configCheckStatus' to the payload so the renderer can distinguish 404 from other failure modes.

- custom.py: in --report mode, when configCheck is None and configCheckStatus == 404, print 'Feature is currently unavailable.'; otherwise keep the existing 'Failed to retrieve...' guidance.

- custom.py: in JSON mode, collapsed both 404 warning branches (with-body and without-body) to the same 'Feature is currently unavailable.' logger.warning call.

- tests: extended test_troubleshoot_config_scm_404_returns_empty_settings to assert the exact warning text; added test_troubleshoot_config_report_shows_feature_unavailable_on_404 for the styled report path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: da04b3ec-d5e4-4ab8-aeea-58dd7010ac84
- Drop group scaffolding collision with Azure#33673: remove
  helps['webapp troubleshoot'] and the shared argument_context('webapp
  troubleshoot') block; status PR owns the group + shared args. The
  webapp-troubleshoot-config subcommand keeps its own argument_context
  (name / resource_group_name / slot / report).
- Fix payload/report asymmetry on runtime-error freshness: annotate the
  runtimeError dict with 'isRecent' (bool) and 'freshnessWindowMinutes'
  (int) so structured-payload consumers can apply the same 15-minute
  gate the --report view uses. Move the freshness helper to module
  scope and drive both the payload annotation and the report gate off
  the shared _RUNTIME_ERROR_FRESHNESS_MINUTES constant.
- Pin troubleshoot_config api-version to literal '2024-11-01' (both
  the /siteStatus fetch and the /instances retry-on-404 fallback)
  instead of reading protected client._config.api_version.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: da04b3ec-d5e4-4ab8-aeea-58dd7010ac84
Move the human-readable --report presentation for
'az webapp troubleshoot config' out of custom.py into a dedicated
module _troubleshoot_config_report.py so custom.py stays focused on
the command flow (fetch config, fetch runtime status, build payload)
and reviewers can see the presentation layer in isolation.

- New module _troubleshoot_config_report.py hosts render_report(payload)
  along with the private helpers it depends on: _format_dt (timestamp
  formatter), _relative_age (age humanizer), and the local closures
  that render the built-in-checks table, the runtime error
  recommendation section, and the suggested-next-steps hint.
- custom.py's troubleshoot_config now lazily imports the module and
  calls render_report(payload) instead of calling the in-file
  _render_troubleshoot_config helper.
- Tests re-target print_styled_text patches to the new module so the
  mock intercepts calls at the lookup site (unchanged behavior; 18
  troubleshoot tests pass).

Pure refactor -- no behavior change to either the structured payload
or the rendered --report output.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: da04b3ec-d5e4-4ab8-aeea-58dd7010ac84
…ection

The site runtime error recommendation section reports the freshest error
seen on any single instance, but until now the report didn't identify
which instance or how many were failing. Users seeing 'BootFailure' on a
3-instance app couldn't tell whether it was a stamp-wide outage or a
single stuck worker.

Tag the runtime error block returned by _extract_runtime_error with
failingInstanceCount (the number of instances that reported lastError),
and render a new 'Instance' row above 'State' in the report showing
the shortened ARM instanceId plus '(1 out of N failing instances)'.
The count is also included in the structured JSON payload for scripting
consumers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: da04b3ec-d5e4-4ab8-aeea-58dd7010ac84
aamos-company and others added 4 commits July 13, 2026 12:45
…ate in help

Users have been asking why the SITE RUNTIME ERROR RECOMMENDATION section
sometimes disappears even though the JSON payload still contains a
runtimeError block. Add a note to 'az webapp troubleshoot config --help'
explaining that the recommendation section is only rendered for errors
that occurred within the last 15 minutes, while the structured payload
carries older errors tagged with isRecent=false.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: da04b3ec-d5e4-4ab8-aeea-58dd7010ac84
The structured payload leaked three implementation details:

- top-level configCheckStatus (HTTP status of the last SCM attempt)
- runtimeError.freshnessWindowMinutes (the 15-minute constant)
- runtimeError.isRecent (freshness gate used by --report)

These were only useful to the --report renderer, not to script consumers,
and made the JSON output noisier than necessary. Compute them internally,
pass them to the renderer as before, then pop them from the payload
before it is returned to the CLI framework. Update tests to assert the
fields are absent, and update the config command help so it no longer
promises an isRecent flag on the payload.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: da04b3ec-d5e4-4ab8-aeea-58dd7010ac84
Changed the SCM-404 warning from the generic "Feature is currently
unavailable." to "Configuration check feature is currently unavailable."
so the message stands on its own without surrounding context — e.g. in a
CI log tail or a support ticket paste.

Applied to both the logger.warning() emitted in JSON/YAML/table mode and
the Style.WARNING row rendered in --report mode. Tests updated to assert
against the new string.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: da04b3ec-d5e4-4ab8-aeea-58dd7010ac84
- _runtime_error_is_recent: reject future timestamps (clock skew)
- HISTORY.rst: add tracking PR number
- _params.py: grammar Default to -> Defaults to

Adds a regression test covering the freshness gate edge case.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: da04b3ec-d5e4-4ab8-aeea-58dd7010ac84
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

"""Human-readable report rendering for 'az webapp troubleshoot config --report'.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Examples:
Note: there is a PR out that will improve the suggestions for the last error details

  • Built in checks is unavailable but runtime status still shows (if the error time is within the last 15 mins)
Image
  • Built in checks available (**test data, not actual value. Corresponding Json from Kudu below). If any of the details level is error, hints will be shown
Image Image
  • Built in checks + site runtime recommendation
Image

]) for r in result]


def transform_troubleshoot_config_output(result):

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The table output will only show the config checks:
Image

JSON
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

act-observability-squad Auto-Assign Auto assign by bot customer-reported Issues that are reported by GitHub users external to the Azure organization. Web Apps az webapp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants