Query logs
You can use query logs to monitor the performance of your Fauna databases and diagnose issues.
Log format
Fauna outputs query logs in a JSON+L format. Each line contains a JSON object that represents a log entry for a single query.
An example query log object formatted for readability:
{
"API_VERSION": "10",
"BYTES_IN": 43,
"BYTES_OUT": 2692,
"BYTE_READ_OPS": 21,
"BYTE_WRITE_OPS": 0,
"COMPUTE_OPS": 1,
"DATABASE": ["ECommerce"],
"FQL_SHAPE":"Product.sortedByPriceLowToHigh()\n",
"QUERY_TIME_MS": 64,
"REGION_GROUP": "us-std",
"REQUEST_HEADERS": "{\"user_agent\":\"curl/8.4.0\",\"x_forwarded_for\":\"108.83.200.91, 10.1.1.124\"}",
"REQUEST_METHOD": "POST",
"RESPONSE_CODE": "200",
"TAGS": { "request_type": "product_search", "sort_by": "price" },
"TRACEPARENT": "00-00000000000000000992df31c81cc1c8-481003b57ce0897f-00",
"TS": "2099-05-10 18:05:42.871 Z",
"TXN_RETRIES": 0
}
Reference: Log record format |
---|
Instrument queries for query logs
You can instrument your queries for query logs by including query tags and traces in query requests.
Query tags
You can instrument your queries with query tags to better identify their source and context in query logs.
A query tag is an arbitrary key-value pair. Query log entries include query tags
in the TAGS
property:
{
...
// Query tags
"TAGS": { "request_type": "product_search", "sort_by": "price" },
...
}
Add query tags in API requests
If you use the Query HTTP API
endpoint, you can pass query tags for a request using the
x-query-tags
request
header:
curl -X POST \
'https://db.fauna.com/query/1' \
-H 'Authorization: Bearer $FAUNA_SECRET' \
-H 'Content-Type: application/json' \
-H 'x-query-tags: request_type=product_search,sort_by=price' \
-d '{"query": "Product.sortedByPriceLowToHigh()"}'
Query API responses include query tags in the query_tags
property:
{
"data": {
...
},
"static_type": "Set<Product>",
"summary": "",
"txn_ts": 1720713675611973,
"stats": {
...
},
// Query tags are returned in the response.
"query_tags": "sort_by=price,request_type=product_search",
"schema_version": 1720712455226000
}
Add query tags using a client driver
The Fauna client drivers let you pass query tags as query options:
{
"sort_by": "price",
"request_type": "product_search"
}
You can use your programming language’s native variables to dynamically populate the keys and values of query tags. For example, you can include an end user ID as a query tag:
Query tag constraints
-
A query can include up to 25 query tags.
-
Query tag keys and values must be alphanumeric strings. The strings can include the underscore (
_
) character. Empty strings are not supported. -
A tag key can be up to 40 characters. A tag value can be up to 80 characters.
A query with invalid query tags fails and returns an error with a 400 HTTP status code.
Traces
You can identify queries triggered by a specific service, component, or process using a traceparent header.
Query log entries include the header’s traceparent identifier in the
TRACEPARENT
property. If you don’t include a traceparent identifier in a query
request or use an invalid identifier, Fauna generates a valid identifier.
Add a traceparent in API requests
If you use the Query HTTP API
endpoint, you can include a traceparent
header in the request. For example:
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
Access query logs
You can access query logs using the:
Query Logs API endpoints
You can use the Query Logs endpoints of the Fauna Account HTTP API to request and download query logs programmatically.
See Access query logs using the HTTP API |
---|
Fauna dashboard
You can manually request and download raw query logs using the Fauna Dashboard. If wanted, you can then upload the logs to a third-party service for visualization or analysis.
See Access query logs in the Fauna Dashboard |
---|
Aggregate query logs
You can aggregate query logs on entry properties using a script or JSON-processing tool, such as jq.
Example: Aggregate logs by query tags
The following example uses jq to aggregate query
log entries by the user_id
query tag in the TAGS
property:
jq -s '
# Filter out log entries without a `user_id` query tag.
map(select(.TAGS.user_id != null)) |
# Group all entries by `user_id`.
group_by(.TAGS.user_id) |
# For each group, create an object with aggregated data
map({
user_id: .[0].TAGS.user_id,
query_count: length,
total_bytes_in: map(.BYTES_IN // 0) | add,
total_bytes_out: map(.BYTES_OUT // 0) | add,
total_query_time_ms: map(.QUERY_TIME_MS // 0) | add,
databases_accessed: map(.DATABASE[]) | unique
}) |
# Transform the array into an object with `user_id`s as keys.
map({key: .user_id, value: .}) |
from_entries
# Replace `input.jsonl` with the path to your query log file.
' input.jsonl > output.json
{
"403221241075335241": {
"user_id": "403221241075335241",
"query_count": 25,
"total_bytes_in": 12194,
"total_bytes_out": 43789,
"total_query_time_ms": 1157,
"databases_accessed": [
"ECommerce"
]
},
...
}
Example: Aggregate logs by query shape
The following example aggregates query logs that include the Product
collection name in the FQL_SHAPE
property:
jq -s '
# Filter entries where `FQL_SHAPE` references the "Product" collection.
map(select(.FQL_SHAPE | contains("Product"))) |
# Group all entries. In this case, it will be a single group.
group_by(true) |
# Create a single object with aggregated data
map({
query_count: length,
total_bytes_in: map(.BYTES_IN // 0) | add,
total_bytes_out: map(.BYTES_OUT // 0) | add,
total_query_time_ms: map(.QUERY_TIME_MS // 0) | add,
databases_accessed: map(.DATABASE[]) | unique,
unique_shapes: map(.FQL_SHAPE) | unique,
response_codes: map(.RESPONSE_CODE) | group_by(.) | map({key: .[0], value: length}) | from_entries
}) |
# Extract the single group.
.[0]
# Replace `input.jsonl` with the path to your query log file.
' input.jsonl > output.json
{
"query_count": 6,
"total_bytes_in": 4663,
"total_bytes_out": 8981,
"total_query_time_ms": 340,
"databases_accessed": [
"ECommerce"
],
"unique_shapes": [
"Product.sortedByPriceLowToHigh()\n",
...
],
"response_codes": {
"200": 4,
"400": 2
}
}
Limitations
-
A log entry is available approximately 30 seconds to 10 minutes after a query’s execution.
-
You can request up to 90 days of query logs. You can specify future times in the request.
-
You can’t get query logs for queries run more than one year ago.
-
You can’t request query logs for a database nested 10 or more levels below a top-level parent database.
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!