Skip to content

Compose the trace and log message

ApiResponseHandler.BuildTraceMessage (private) builds the newline-joined trace/log payload used by the trace call (emitted only when ILogService is resolved) and the error-logging calls.

Field Value
Operation ID OP-05
Trigger Post-process an API response, steps 13, 14, 15.
Inputs request/response context, debugMode flag
Outputs newline-joined string
Primary components ApiResponseHandler.BuildTraceMessage
Entry point src/SAIF.Web.API/ApiResponseHandler.cs

Steps

  1. Build the base message array: method + timestamp, request URI, MessageID, Splunk URL, elapsed ms, exception message, authenticated user ID (or literal anonymous when empty), client IP (or anonymous), response status (BR-WEBAPI-009).
  2. Add the client-identity headers Client-Name, Client-Is-Web, Client-User, Application-ID via TryGetFirstHeader (BR-WEBAPI-019).
  3. Missing headers render as empty strings, never throw.
  4. This step delegates to a locally-implemented operation.

Origin: Step 2 is implemented in Read the first value of a request header (SAIF.Web.API) and executed on behalf of this operation. 3. If debugMode is false, join and return (BR-WEBAPI-009). 4. If debugMode is true: obtain the HttpContextBase, Seek(0, Begin) on context.Request.InputStream, copy it to a MemoryStream, and UTF-8 decode it (BR-WEBAPI-009). - Risk: GetHttpContext(request) is dereferenced without a null check here — a self-hosted or context-less request would raise NullReferenceException.* 5. Redact the decoded body with Regex.Replace(inputStream, @"password[^,\n]*", @"""Password"": ""********""", IgnoreCase) (BR-WEBAPI-007). - Only the input stream copy is redacted — Request Content and Response Content (step 6) are not run through the redaction regex. 6. Append request content, redacted input stream, request headers, request content headers, response content, response headers, response content headers (BR-WEBAPI-009). - All null-conditional with ?? "" fallbacks. - SAIF.Common.Extensions.ToStringAll is implemented in SAIF.Framework.Core; its internal steps could not be embedded — the package is not indexed for this run.**

Process flow

flowchart TD
    Start(["Called from OP-01 steps<br>13-15"]) --> Base["Build base message<br>fields"]
    Base --> Headers["Add client-identity<br>headers via<br>TryGetFirstHeader"]
    Headers --> Debug{debugMode?}
    Debug -->|No| Join[Join and return]
    Debug -->|Yes| InputStream["Read and copy request<br>InputStream"]
    InputStream --> Redact["Redact password-like<br>content"]
    Redact --> Append["Append bodies, headers,<br>content headers"]
    Append --> Join
    Join --> End([Return trace message])

Failure and edge-case behavior

  • Debug-mode tracing on a context-less request (no ambient HttpContextBase) can raise NullReferenceException at step 4.*
  • Request/response headers and bodies (including any Authorization header) are written to the trace un-redacted when debug logging is on — only the input-stream copy is redacted.

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.

Sources

  • src/SAIF.Web.API/ApiResponseHandler.cs