Loading…
Loading…
Explains the asynchronous logging service that writes runtime and debug trace records to the database without blocking API request processing.
The RuntimeLogAsyncWriter is a service component responsible for writing runtime transaction logs and debug traces to the database in a "fire-and-forget" manner.
This component solves a performance problem where synchronous database writes for logging would block the main request-handling thread, adding 5–30 ms of latency to an API call after the response from the upstream backend was already available. By moving these database INSERT operations to a dedicated background thread pool, the RuntimeLogAsyncWriter allows the request handler to return the HTTP response to the API consumer immediately, improving overall response time.
The writer is invoked by the primary runtime request handler. It takes a set of captured metrics and payload data from the API transaction and persists them to the s2r_runtime_log and, conditionally, the s2r_debug_trace database tables.
The RuntimeLogAsyncWriter leverages Spring's asynchronous method execution capabilities. The core logic is in the writeAsync method, which is annotated with @Async("runtimeLogExecutor").
When the request handler calls writeAsync, the following sequence occurs:
runtimeLogExecutor thread pool.runtimeLogExecutor pool picks up the task and executes the writeAsync method.runtimeLogRepository.insertRuntimeLog to insert the main transaction record into the s2r_runtime_log table.writeDebugTrace flag is true, it uses the logId returned by the first insert to call runtimeLogRepository.insertDebugTrace, writing the detailed trace to the s2r_debug_trace table.sequenceDiagram
participant API Consumer
participant Request Handler
participant RuntimeLogAsyncWriter
participant Database
API Consumer->>Request Handler: Sends API request
Note over Request Handler: Processes request and calls backend
Request Handler-->>API Consumer: Returns HTTP response
Request Handler->>RuntimeLogAsyncWriter: writeAsync(...)
activate RuntimeLogAsyncWriter
Note over RuntimeLogAsyncWriter: Execution on background thread
RuntimeLogAsyncWriter->>Database: INSERT into s2r_runtime_log
Database-->>RuntimeLogAsyncWriter: Returns logId
alt If writeDebugTrace is true
RuntimeLogAsyncWriter->>Database: INSERT into s2r_debug_trace
end
deactivate RuntimeLogAsyncWriterIMPORTANT
The asynchronous behavior only activates when writeAsync is called through the Spring-managed proxy. For this reason, RuntimeLogAsyncWriter is implemented as a separate Service bean. If it were a private method within the calling controller, the proxy would be bypassed, and the database writes would silently revert to being synchronous.
WARNING
All arguments passed to writeAsync must be captured and finalized on the request thread before the call is made. Do not pass live, mutable objects tied to the HTTP request lifecycle (like HttpServletRequest). For example, request headers must be snapshotted into a standard Map by the caller.
The component exposes a single method, writeAsync, for internal invocation by the runtime.
writeAsync MethodThis method asynchronously writes one runtime log record and, optionally, one debug trace record. It is designed to not propagate exceptions, as the client request has already completed by the time it executes.
The following table details all parameters for the writeAsync method.
| Parameter | Java Type | Description |
|---|---|---|
correlationId | UUID | A unique identifier for the entire transaction. |
direction | String | The direction of the traffic (e.g., inbound, outbound). |
environment | String | The name of the environment where the transaction occurred. |
serviceKey | String | The key identifying the service that was invoked. |
operationKey | String | The key identifying the operation within the service. |
httpStatus | int | The HTTP status code returned to the API consumer. |
resultCode | String | A platform-specific code indicating the transaction outcome. |
latencyMs | int | The total latency of the request in milliseconds, from start to finish. |
backendLatencyMs | Integer | The latency of the upstream backend call in milliseconds. |
converterOverheadMs | Integer | The time spent in request/response transformation logic in milliseconds. |
requestSizeBytes | long | The size of the incoming request payload in bytes. |
responseSizeBytes | Long | The size of the final response payload in bytes. |
payloadLogged | boolean | A flag indicating if the full payload was logged. |
errorCode | String | A platform-specific error code if the transaction failed. |
errorMessage | String | A descriptive error message if the transaction failed. |
writeDebugTrace | boolean | If true, a detailed debug trace record will also be written. |
requestHeaders | Map<String, String> | A map of the headers from the incoming request. |
requestPayload | String | The raw payload of the incoming request. |
soapRequest | String | The transformed SOAP request sent to a SOAP backend. |
soapResponse | String | The SOAP response received from a SOAP backend. |
responsePayload | String | The final response payload sent to the API consumer. |
retentionDays | int | The number of days the debug trace record should be retained. |
monitorViolationsJson | String | A JSON string detailing any monitoring violations that occurred. |
serviceVersionId | UUID | The ID of the specific service version that handled the call. This may be null if no route was resolved. |
If the RuntimeLogAsyncWriter fails to write to the database (e.g., due to a database connection issue or constraint violation), the failure is handled internally to prevent it from affecting the platform's stability.
RuntimeException is thrown during the call to runtimeLogRepository.insertRuntimeLog or runtimeLogRepository.insertDebugTrace.WARN-level log message is emitted with the following format:
S2R-RUN-LOG-ASYNC failed cid={} svc={} op={} err={}
cid: The correlationId of the transaction.svc: The serviceKey.op: The operationKey.err: The string representation of the caught exception.