Skip to content

Add structured verbose/debug request logging to Invoke-PfbApiRequest #148

Description

Summary

The module currently emits almost no diagnostics. Across 544 public cmdlets and 33 private functions there are 19 Write-Verbose calls in 10 files, and 27 Write-Warning calls. When a request fails, or succeeds but returns something unexpected, there is no supported way for a user to see what actually went on the wire short of attaching a proxy or editing the module.

This proposes adding structured verbose/debug logging at the single chokepoint every request passes through: Private/Invoke-PfbApiRequest.ps1.

Why that one function

Every cmdlet in Public/ reaches the array through Invoke-PfbApiRequest. Instrumenting it once covers the whole cmdlet surface, so this is a small diff with module-wide reach rather than a 544-file sweep. It also keeps the diagnostic output in one consistent shape, which matters if we ever want to parse it.

Proposed behaviour

At -Verbose, one line per request describing the call:

  • HTTP method and the resolved request URI, including the query string as actually sent
  • the REST API version the request resolved to
  • the response status code
  • elapsed time
  • for a context-carrying request, the resolved context

At -Debug, additionally the request and response bodies.

Redaction is a hard requirement, not a nicety

Invoke-PfbApiRequest handles the API token, and the login paths handle passwords, JWTs and OAuth2 client secrets. Any logging added here must redact:

  • the x-auth-token header value
  • api_token in a request or response body
  • passwords, private keys, client secrets and assertions in the login request bodies
  • the Authorization header on the OAuth2 path

A logging feature that leaks a token into a transcript or a CI log is worse than having no logging at all. The redaction list should be explicit and covered by tests, and the tests should assert the secret is absent from the emitted string rather than asserting the redaction marker is present — the latter passes even if the raw value is also emitted elsewhere in the same line.

Inspiration, and what we are deliberately not doing

The design idea here is borrowed from PSFramework, whose Write-PSFMessage unifies verbose/debug/warning output and can additionally route messages to file and other logging providers. That single-entry-point model is a good fit for what we want.

We are not taking PSFramework as a dependency. Reasons, for the record so this does not get relitigated:

  1. PSFramework ships a compiled assembly (PSFramework.dll). On Windows PowerShell 5.1 two versions of the same assembly cannot load side by side in one session. Other widely-used modules depend on PSFramework, so a user with a version mismatch would get a hard load failure — not our bug, but our support burden.
  2. The module has no RequiredModules today. That means it installs onto an offline or locked-down administrator workstation as a plain folder copy. A binary dependency would break that property, which is worth more to this module's audience than the convenience it buys us.
  3. The payoff does not justify the cost. The valuable part of Write-PSFMessage for a REST client is the single chokepoint, and we already have one. Native Write-Verbose and Write-Debug inside Invoke-PfbApiRequest gets essentially all of the benefit with no dependency and no new install story.

If a future need for pluggable log providers (log to file, log to event log) turns up, that is worth revisiting on its own merits — but it is not what this issue asks for.

Notes on scope

  • Test-only concern: the existing test suite mocks at the Invoke-PfbApiRequest boundary in 206 test files. Adding output inside that function should not change its return contract, but the change needs checking against the suite on both PowerShell editions.
  • This touches executable lines in Private/, so it is not wire-exempt and needs live verification against a real FlashBlade before it merges.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions