Access Logs - WunderGraph
Access or Request Logs
Access or request logs provide valuable insights into the traffic passing through your router instances. By default, logs are output to stdout, but logging to a file is also supported, which is recommended for high-load scenarios. However, only one logging mode—either stdout or file—can be enabled at any given time. The logs include a predefined set of fields that help identify HTTP requests. Additionally, custom fields can be configured to capture more detailed information from the GraphQL requests.
Logging to stdout
The following configuration enables logging to stdout:
access_logs:
enabled: true
output:
stdout:
enabled: true
Logging to file
For environments with high traffic, logging to a file is recommended. Below is an example configuration for logging to a file:
access_logs:
enabled: true
output:
file:
enabled: true
path: /var/log/gateway/access.log
Setting file permissions
By default, the file will be created with permissions 0640. You can change this by setting the mode field:
access_logs:
output:
file:
mode: '0644'
The mode uses Linux-style octal permissions. For example, 0644 means -rw-r—r—:
- The first digit (
6) is for the owner (read + write) - The second digit (
4) is for the group (read only) - The third digit (
4) is for others (read only)
Log level
You can control the verbosity of access logs. The default is info, and based on the log level, any log entry that would be printed above the set log level would be excluded. For example, if “error” was the level set, “info”, “debug” and “warn” log entries would be excluded.
access_logs:
level: debug # Default: info
Add stack traces
You have the option of adding stack traces to all error logs. Note that by default even if this feature is disabled panics will contain stack traces.
access_logs:
add_stacktrace: true # Default: false
As of router 0.258.3 any requests that caused an error are logged as “error” on the access logs. Previously all non-panic access logs were marked as “info” logs.
Default Log Fields
The default log fields provide essential details about each HTTP request. These fields include:
- hostname: The hostname of the machine handling the request.
- pid: The process ID of the router instance.
- request_id: The request ID generated by the router instance.
- trace_id: The Trace ID propagated or generated by the router instance.
- status: The HTTP status code of the request.
- method: The HTTP method used (e.g.,
GET,POST). - path: The request path (e.g.,
/graphql). - query: The query string included in the request URL (e.g.,
/?param=1). Certain parameters can be skipped using the ignore_query_params_list option. - ip: The client’s IP address (redacted by default).
- user_agent: The
User-Agentheader value provided by the client. - config_version: The version of the router configuration used to handle the request.
- latency: The time taken to process the request, in float seconds.
- log_type: Identifies the type of log (useful for distinguishing access logs from other log types).
Example Log Entry
An example of a log entry is shown below:
12:21:37 PM INFO /graphql {
"hostname": "dustins-MacBook-Pro.local",
"pid": 13616,
"log_type": "request",
"method": "POST",
"path": "/graphql",
"query": "",
"ip": "[REDACTED]",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
"config_version": "6c6b3f36-99b9-4632-84e1-ca24d95eee8d",
"trace_id": "cc4bccf2e981fecc3f8f3b87257c1ce6",
"latency": 0.019332208,
"status": 200,
"request_id": "dustins-MacBook-Pro.local/TBOXjJsAo5-000007"
}
Filtering Query Parameters
The query field above by default will print the raw query string if present. However, this can potentially include sensitive information, especially if the GraphQL request was made over GET. Users can ignore specific query parameters using the following configuration, which will skip printing the “extensions” query parameter:
access_logs:
router:
ignore_query_params_list:
- "extensions"
Note that if no ignore_query_params_list is specified, “variables” is ignored by default.
Custom Fields
In addition to the default fields, you can extend the log with custom fields. These can include values extracted from request headers or additional information generated after the GraphQL operation has been processed. Let’s take the following example:
log_level: info
dev_mode: true
access_logs:
enabled: true
output:
file:
enabled: true
path: "access.log"
router:
fields:
- key: "service"
value_from:
request_header: "x-service"
- key: "operationName"
value_from:
context_field: operation_name
- key: "operationSha256"
value_from:
context_field: operation_sha256
- key: "requestError"
value_from:
context_field: request_error
- key: "responseErrorMessage"
value_from:
context_field: response_error_message
- key: "serviceNames"
value_from:
context_field: operation_service_names
- key: "operationHash"
value_from:
context_field: operation_hash
- key: "operationType"
value_from:
context_field: operation_type
- key: "persistentOperationSha256"
value_from:
context_field: persisted_operation_sha256
- key: "operationParsingTime"
value_from:
context_field: operation_parsing_time
- key: "operationPlanningTime"
value_from:
context_field: operation_planning_time
- key: "operationNormalizationTime"
value_from:
context_field: operation_normalization_time
- key: "operationValidationTime"
value_from:
context_field: operation_validation_time
Explanation of Each Field's Meaning
- service: Logs the name of the service making the request, extracted from the request header “x-service”. It helps identify which specific service is making the API call.
- operationName: Logs the name of the GraphQL operation being performed. It is extracted from the context of the request and indicates which query or mutation is being executed.
- operationSha256: Logs the SHA-256 hash of the original GraphQL operation, serving as a unique identifier for the operation’s structure. It helps to identify operations in a secure and consistent way.
- requestError: Present when an error has been encountered with the request, and will be
trueif so. - responseErrorMessage: Logs any error message returned in the response, capturing detailed information about what went wrong during the execution of the operation.
- serviceNames: Logs the names of all services involved in processing the operation.
- operationHash: Logs a unique hash generated for the normalized operation.
- operationType: Logs the type of GraphQL operation being executed, such as a query, mutation, or subscription.
- persistentOperationSha256: Logs the SHA-256 hash of the persisted GraphQL operation.
- operationParsingTime: Logs the amount of time spent parsing the GraphQL operation.
- operationPlanningTime: Logs the time taken for planning the execution of the operation.
- operationNormalizationTime: Logs the time spent normalizing the GraphQL operation.
- operationValidationTime: Logs the time spent validating the GraphQL operation.
Conclusion
By configuring access logs, you can gather vital data on the traffic processed by your router. This helps in monitoring performance, debugging issues, and understanding request patterns. Whether logging to stdout or to a file, the logs provide flexibility with both default and custom fields to suit your specific needs.