Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Audit Handler

The AuditHandler is a middleware component responsible for logging request and response details for auditing purposes. It captures important information such as headers, execution time, status codes, and even request/response bodies if configured.

The audit logs are typically written to a separate log file (e.g., audit.log) via slf4j/logback, allowing them to be ingested by centralized logging systems like ELK or Splunk.

Configuration

The configuration is managed by AuditConfig and corresponds to audit.yml (or audit.json/audit.properties).

Configuration Properties

PropertyTypeDefaultDescription
enabledbooleantrueEnable or disable the Audit Handler.
maskbooleantrueEnable masking of sensitive data in headers and audit fields.
statusCodebooleantrueInclude response status code in the audit log.
responseTimebooleantrueInclude response time (latency) in milliseconds.
auditOnErrorbooleanfalseIf true, only log when the response status code is >= 400. If false, log every request.
logLevelIsErrorbooleanfalseIf true, logs at ERROR level. If false, logs at INFO level.
timestampFormatstringnullCustom format for the timestamp (e.g., yyyy-MM-dd'T'HH:mm:ss.SSSZ). If null, uses epoch timestamp.
headerslist[...]List of request headers to include in the log. Default: X-Correlation-Id, X-Traceability-Id, caller_id.
auditlist[...]List of specific audit fields to include. Default: client_id, user_id, scope_client_id, endpoint, serviceId.
requestBodyMaxSizeint4096Max size of request body to log (if requestBody is in audit list). Truncated if larger.
responseBodyMaxSizeint4096Max size of response body to log (if responseBody is in audit list). Truncated if larger.

Configuration Example (audit.yml)

# Enable Audit Logging
enabled: ${audit.enabled:true}

# Enable mask in the audit log
mask: ${audit.mask:true}

# Output response status code
statusCode: ${audit.statusCode:true}

# Output response time
responseTime: ${audit.responseTime:true}

# when auditOnError is true:
#  - it will only log when status code >= 400
# when auditOnError is false:
#  - it will log on every request
auditOnError: ${audit.auditOnError:false}

# log level; by default it is set to info. If you want to change it to error, set to true.
logLevelIsError: ${audit.logLevelIsError:false}

# timestamp format
timestampFormat: ${audit.timestampFormat:}

# headers to audit
headers: ${audit.headers:X-Correlation-Id, X-Traceability-Id,caller_id}

# audit fields. Add requestBody or responseBody here to enable payload logging.
audit: ${audit.audit:client_id, user_id, scope_client_id, endpoint, serviceId}

Values Example (values.yml)

You can customize the audit behavior per environment using values.yml. For example, to enable full body logging in a dev environment:

# audit.yml
audit.audit:
  - client_id
  - user_id
  - endpoint
  - requestBody
  - responseBody
  - queryParameters
  - pathParameters

Logging Body and Parameters

The AuditHandler supports logging additional details if they are added to the audit list in the configuration:

  • requestBody: Logs the request body.
  • responseBody: Logs the response body.
  • queryParameters: Logs query parameters.
  • pathParameters: Logs path parameters.
  • requestCookies: Logs request cookies.

Note: Enabling body logging (requestBody or responseBody) can significantly impact performance and is generally not recommended for production unless auditOnError is enabled or for specific debugging purposes.

Usage

Register the AuditHandler in your handler.yml chain. It is usually placed near the beginning of the chain to capture the start time and ensure it runs even if downstream handlers fail.

handler.handlers:
  .
  - com.networknt.audit.AuditHandler@audit

handler.chains.default:
  - exception
  - traceability
  - correlation
  - audit
  .

Logback Configuration

The AuditHandler writes to a logger named audit. You should configure a specific appender in your logback.xml to route these logs to a separate file or system.

Example logback.xml snippet:

<appender name="audit" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>log/audit.log</file>
    <encoder>
        <pattern>%msg%n</pattern>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
        <fileNamePattern>log/audit.log.%i.zip</fileNamePattern>
        <minIndex>1</minIndex>
        <maxIndex>10</maxIndex>
    </rollingPolicy>
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <maxFileSize>10MB</maxFileSize>
    </triggeringPolicy>
</appender>

<logger name="audit" level="INFO" additivity="false">
    <appender-ref ref="audit"/>
</logger>

Log Format

The audit log is written as a JSON object.

Example output:

{
  "timestamp": "2023-10-27T10:00:00.123-0400",
  "serviceId": "com.networknt.petstore-1.0.0",
  "X-Correlation-Id": "12345",
  "endpoint": "/v1/pets@get",
  "statusCode": 200,
  "responseTime": 45
}