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¶
- Build the base message array: method + timestamp, request URI,
MessageID, Splunk URL, elapsed ms, exception message, authenticated user ID (or literalanonymouswhen empty), client IP (oranonymous), response status (BR-WEBAPI-009). - Add the client-identity headers
Client-Name,Client-Is-Web,Client-User,Application-IDviaTryGetFirstHeader(BR-WEBAPI-019). - Missing headers render as empty strings, never throw.
- 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. IfdebugModeis false, join and return (BR-WEBAPI-009). 4. IfdebugModeis true: obtain theHttpContextBase,Seek(0, Begin)oncontext.Request.InputStream, copy it to aMemoryStream, 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 raiseNullReferenceException.* 5. Redact the decoded body withRegex.Replace(inputStream, @"password[^,\n]*", @"""Password"": ""********""", IgnoreCase)(BR-WEBAPI-007). - Only the input stream copy is redacted —Request ContentandResponse 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.ToStringAllis implemented inSAIF.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 raiseNullReferenceExceptionat step 4.* - Request/response headers and bodies (including any
Authorizationheader) 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.
Related documentation¶
Sources¶
src/SAIF.Web.API/ApiResponseHandler.cs