This is the multi-page printable view of this section. Click here to print.
Observability
1 - Trickster Metrics
Trickster exposes a Prometheus /metrics endpoint with a customizable listener port number (default is 8481). For more information on customizing the metrics configuration, see configuring.md.
The following metrics are available for polling with any Trickster configuration:
trickster_build_info(Gauge) - This gauge is always 1 when Trickster is running- labels:
goversion- the version of go under which the running Trickster binary was builtrevision- the commit ID on which the running Trickster binary was builtversion- semantic version of the running Trickster binary
- labels:
trickster_config_last_reload_successful(Gauge) - The value is 1 when true (the last config reload was successful) or 0 when falsetrickster_config_last_reload_success_time_seconds(Gauge) - Epoch timestamp of the last successful configuration reloadtrickster_frontend_requests_total(Counter) - Count of front end requests handled by Trickster- labels:
backend_name- the name of the configured backend handling the proxy requestprovider- the type of the configured backend handling the proxy requestmethod- the HTTP Method of the proxied requesthttp_status- The HTTP response code provided by the backendpath- the Path portion of the requested URL
- labels:
trickster_frontend_requests_duration_seconds(Histogram) - Histogram of front end request durations handled by Trickster- labels:
backend_name- the name of the configured backend handling the proxy requestprovider- the type of the configured backend handling the proxy requestmethod- the HTTP Method of the proxied requesthttp_status- The HTTP response code provided by the backendpath- the Path portion of the requested URL
- labels:
trickster_frontend_written_byte_total(Counter) - Count of bytes written in front end requests handled by Trickster- labels:
backend_name- the name of the configured backend handling the proxy requestprovider- the type of the configured backend handling the proxy requestmethod- the HTTP Method of the proxied requesthttp_status- The HTTP response code provided by the backendpath- the Path portion of the requested URL
- labels:
trickster_proxy_requests_total(Counter) - The total number of requests Trickster has handled.- labels:
backend_name- the name of the configured backend handling the proxy requestprovider- the type of the configured backend handling the proxy requestmethod- the HTTP Method of the proxied requestcache_status- status codes are described herehttp_status- The HTTP response code provided by the backendpath- the Path portion of the requested URL
- labels:
trickster_proxy_upstream_retries_total(Counter) - The number of upstream requests retried under a path’sretrypolicy.- labels:
backend_name- the name of the configured backend handling the proxy requestpath- the configured path whose policy retried the request
- labels:
trickster_proxy_mirror_requests_total(Counter) - The number of requests copied to a path’smirrorbackend.- labels:
backend_name- the name of the configured backend handling the proxy requestmirror_backend- the backend receiving the copiesresult-sent, ordroppedwhen the mirror’s in-flight bound was reached
- labels:
trickster_accesslog_dropped_lines_total(Counter) - The number of access and error log lines dropped because the log could not accept them.- labels:
backend_name- the name of the configured backend whose logger dropped the linelog-accessorerror
- labels:
trickster_proxy_points_total(Counter) - The total number of data points Trickster has handled.- labels:
backend_name- the name of the configured backend handling the proxy requestprovider- the type of the configured backend handling the proxy requestcache_status- status codes are described herepath- the Path portion of the requested URL
- labels:
trickster_proxy_request_duration_seconds(Histogram) - Time required to proxy a given Prometheus query.- labels:
backend_name- the name of the configured backend handling the proxy requestprovider- the type of the configured backend handling the proxy requestmethod- the HTTP Method of the proxied requestcache_status- status codes are described herehttp_status- The HTTP response code provided by the backendpath- the Path portion of the requested URL
- labels:
trickster_proxy_max_connections(Gauge) - Trickster max number of allowed concurrent connectionstrickster_proxy_active_connections(Gauge) - Trickster number of concurrent connectionstrickster_proxy_requested_connections_total(Counter) - Trickster total number of connections requested by clients.trickster_proxy_accepted_connections_total(Counter) - Trickster total number of accepted client connections.trickster_proxy_closed_connections_total(Counter) - Trickster total number of administratively closed client connections.trickster_proxy_failed_connections_total(Counter) - Trickster total number of failed client connections.trickster_proxy_stream_connections_total(Counter) - The number of connections and UDP sessions accepted bytcp,tlsandudplisteners.- labels:
listener_name- the name of the configured listenerprotocol-tcp,tlsorudpresult-proxied, or why the connection was closed instead:not_tls(atlslistener received no ClientHello),no_route(no backend routes the server name),no_upstream(the backend’s pool has no dialable member, or the member chosen refuses its share),dial_failed, orrefused(audplistener at its session limit, or a connection arriving as the listener closes)
- labels:
trickster_proxy_stream_active_connections(Gauge) - The number of connections and UDP sessions stream listeners are relaying.- labels:
listener_name- the name of the configured listenerprotocol-tcp,tlsorudp
- labels:
trickster_proxy_stream_dropped_datagrams_total(Counter) - The number of datagramsudplisteners dropped rather than relayed.- labels:
listener_name- the name of the configured listenerreason-queue_full(the client’s flow, or every flow together, already held its allowance of datagrams waiting to be written) orwrite_timeout(the write to the backend blocked for the whole write bound)
- labels:
trickster_proxy_stream_bytes_total(Counter) - The bytes relayed by stream listeners.- labels:
listener_name- the name of the configured listenerprotocol-tcp,tlsorudpdirection-infrom the client to the backend,outfrom the backend to the client
- labels:
trickster_proxy_query_range_rejected_total(Counter) - Trickster total number of queries rejected due to exceeding themax_query_rangelimit.- labels:
backend- the name of the configured backend rejecting the query
- labels:
trickster_graphite_resolution_lookups_total(Counter) - Count of Graphite step-resolution lookups. Labels never include a metric path or target expression.- labels:
backend_name- the name of the configured Graphite backendconfidence- how the step was established:exact(read from an origin response for this leaf set and age),derived(computed from known leaf ladders),configured(fromstatic_retentions, not yet probe-confirmed), orunknown(no usable step; the request is served unaccelerated)source- where it came from:registry,response,probe,static,function, ornone
- labels:
trickster_graphite_probes_total(Counter) - Count of synthetic requests issued to learn a metric’s archive ladder. Expect a spike at startup that collapses toward zero as ladders are learned.- labels:
backend_name- the name of the configured Graphite backendkind-narrow(a one-second window that also discovers the retention edge),wide(what a real query at that age receives), orfind(a/metrics/expandlookup)result-step(a stepped series came back),empty(no series: beyond retention, or no such metric), orerror
- labels:
trickster_graphite_ladders(Gauge) - Number of distinct archive ladders known to the resolution registry. Ladders come fromstorage-schemas.confpatterns, so this should flatten at a small number.- labels:
backend_name- the name of the configured Graphite backend
- labels:
trickster_graphite_registry_entries(Gauge) - Number of entries in each layer of the resolution registry.- labels:
backend_name- the name of the configured Graphite backendlayer-leaf(metric path to ladder),ladder(the ladders themselves),target(cached wildcard expansions), ornegative(paths in resolution backoff)
- labels:
trickster_graphite_step_mispredictions_total(Counter) - Count of origin responses whose step differed from the predicted step. This should always be zero. A non-zero value means a cached ladder was wrong; Trickster discards the prediction, relearns and re-serves the request unaccelerated, so clients still receive correct data.- labels:
backend_name- the name of the configured Graphite backend
- labels:
trickster_graphite_fallbacks_total(Counter) - Count of render requests served without delta caching. Labels never include a target expression.- labels:
backend_name- the name of the configured Graphite backendreason-parse_error,non_series_format,function_not_allowlisted,unknown_step,missing_target,multi_target_step_mismatch,passthrough_max_data_points,misprediction,client_identity,tz_unavailable, orresolution_identity
- labels:
trickster_sql_query_analysis_total(Counter) - Count of SQL query cache-eligibility classifications. Labels never include query text.- labels:
backend_name- the name of the configured backend analyzing the querydialect- the SQL dialect of the analyzing backend (e.g.,clickhouse)cache_mode- the strongest cache mode supported by the query (delta,object, ornone)reason- the stable classification reason code (e.g.,delta_cacheable,unsafe_predicate,unsupported_bucket)
- labels:
trickster_sql_query_rewrite_failures_total(Counter) - Count of SQL cache-miss extent rewrite failures. Labels never include query text.- labels:
backend_name- the name of the configured backend rendering the querydialect- the SQL dialect of the rendering backendreason- the fixed internal failure category
- labels:
trickster_druid_query_analysis_total(Counter) - Count of native Druid query cache-eligibility classifications. Labels never include query text or datasource names.- labels:
backend_name- the configured Druid backendcache_mode-delta,object, orproxyreason- the stable classification reason code
- labels:
trickster_druid_query_rewrite_failures_total(Counter) - Count of Druid cache-miss extent rewrite failures.- labels:
backend_name- the configured Druid backendreason- the fixed internal failure category
- labels:
trickster_cache_operation_objects_total(Counter) - The total number of objects upon which the Trickster cache has operated.- labels:
cache_name- the name of the configured cache performing the operationprovider- the type of the configured cache performing the operationoperation- the name of the operation being performed (read, write, etc.)status- the result of the operation being performed
- labels:
trickster_cache_operation_duration_seconds(Histogram) - The time, in seconds, required to perform an operation on the Trickster cache. Deletions include both requested removals and index reaper evictions.- labels:
cache_name- the name of the configured cache performing the operationprovider- the type of the configured cache performing the operationoperation- the name of the operation being performed (get,set,setDirect,del)status- the result of the operation being performed (e.g.,hit,kmissfor a full key miss,none)
- labels:
trickster_cache_operation_bytes_total(Counter) - The total number of bytes upon which the Trickster cache has operated. Deletions (del) record bytes only for cache providers that use an index, since other providers don’t track object sizes.- labels:
cache_name- the name of the configured cache performing the operationprovider- the type of the configured cache performing the operationoperation- the name of the operation being performed (read, write, etc.)status- the result of the operation being performed
- labels:
trickster_alb_pool_admits_failing(Gauge) - 1 when an ALB pool’shealthy_flooradmits members in theunavailablestate, 0 otherwise. See alb.md for the recommended floor.- labels:
backend_name- the name of the configured ALB backend
- labels:
trickster_alb_pool_floor_reset(Gauge) - 1 when an ALB pool’shealthy_floorwas reset to 0 at startup because pool members have no health check and could never reach the configured floor, 0 otherwise. See alb.md.- labels:
backend_name- the name of the configured ALB backend
- labels:
The following metrics are available when ALB Autodiscovery is configured:
trickster_alb_discovery_members(Gauge) - Current number of discovered ALB pool members- labels:
alb_name- the name of the discovery-backed ALB backenddiscoverer- the name of the discoverer serving the ALB
- labels:
trickster_alb_discovery_member_changes_total(Counter) - Count of discovered pool member additions and removals- labels:
alb_name- the name of the discovery-backed ALB backenddiscoverer- the name of the discoverer serving the ALBevent-addorremove
- labels:
trickster_alb_discovery_snapshots_total(Counter) - Count of membership snapshots processed, by result- labels:
alb_name- the name of the discovery-backed ALB backenddiscoverer- the name of the discoverer serving the ALBresult-applied(membership updated),unchanged(no-op),rejected(guardrail-refused, e.g.min_members), orpartial(applied with member instantiation failures)
- labels:
trickster_alb_discovery_last_refresh_success_time_seconds(Gauge) - Epoch timestamp of the last successfully processed snapshot, for staleness alerting- labels:
alb_name- the name of the discovery-backed ALB backenddiscoverer- the name of the discoverer serving the ALB
- labels:
trickster_discovery_refresh_errors_total(Counter) - Count of provider-side refresh/watch errors (DNS resolution failures, Kubernetes list/sync failures, member-file read/parse failures)- labels:
discoverer- the name of the discoverer experiencing the errorprovider- the discoverer’s provider type
- labels:
trickster_tls_certificate_expiration_time_seconds(Gauge) - NotAfter time of a serving TLS certificate, as unix seconds. See tls.md.- labels:
listener- the name of the listener serving the certificateentry- the certificate’s source identity
- labels:
trickster_tls_certificate_last_load_time_seconds(Gauge) - Epoch timestamp a serving TLS certificate was last loaded from its source- labels:
listener- the name of the listener serving the certificateentry- the certificate’s source identity
- labels:
trickster_tls_certificate_swaps_total(Counter) - Count of TLS certificates hot-swapped into a live listener by rotation detection- labels:
listener- the name of the listener serving the certificateentry- the certificate’s source identity
- labels:
trickster_tls_certificate_validation_failures_total(Counter) - Count of detected TLS certificate source changes that failed pair validation (e.g. a mid-rotation partial write) and were not swapped in- labels:
entry- the certificate’s source identity
- labels:
trickster_tls_watcher_errors_total(Counter) - Count of errors reading watched TLS certificate source files- labels:
entry- the certificate’s source identity
- labels:
trickster_tls_certificate_store_size(Gauge) - Number of certificates in a listener’s TLS certificate store- labels:
listener- the name of the listener
- labels:
The following metrics are available only for Caches Types whose object lifecycle Trickster manages internally (Memory, Filesystem and bbolt):
trickster_cache_events_total(Counter) - The total number of events that change the Trickster cache, such as retention policy evictions.- labels:
cache_name- the name of the configured cache experiencing the event$provider- the type of the configured cache experiencing the eventevent- the name of the event being performedreason- the reason the event occurred
- labels:
trickster_cache_usage_objects(Gauge) - The current count of objects in the Trickster cache.- labels:
cache_name- the name of the configured cache$provider- the type of the configured cache$
- labels:
trickster_cache_usage_bytes(Gauge) - The current count of bytes in the Trickster cache.- labels:
cache_name- the name of the configured cache$provider- the type of the configured cache$
- labels:
trickster_cache_max_usage_objects(Gauge) - The maximum allowed size of the Trickster cache in objects.- labels:
cache_name- the name of the configured cache$provider- the type of the configured cache
- labels:
trickster_cache_max_usage_bytes(Gauge) - The maximum allowed size of the Trickster cache in bytes.- labels:
cache_name- the name of the configured cache$provider- the type of the configured cache
- labels:
The following metrics are available when the Kubernetes Gateway/Ingress controller is enabled (the top-level kubernetes section; see kubernetes-gateway.md):
trickster_kgw_reconciles_total(Counter) - Count of controller reconcile passes, by result- labels:
result-applied(the data plane was reloaded),unchanged(the generated configuration was already running), orerror(the pass failed to compile or apply)
- labels:
trickster_kgw_reconcile_duration_seconds(Histogram) - Duration of a whole reconcile pass, from reading the caches to writing statustrickster_kgw_reconcile_errors_total(Counter) - Count of reconcile passes that failed in a stage- labels:
stage-compile,apply,certificates(a certificate a listener’s store refused) orstatus(a status write the API server refused)
- labels:
trickster_kgw_watch_events_total(Counter) - Count of Kubernetes watch events received by the controller- labels:
kind- the object kind (Gateway,HTTPRoute,Ingress,Secret,Service, …)event-add,updateordelete
- labels:
trickster_kgw_translate_duration_seconds(Histogram) - Duration of translating the watched objects into the routing modeltrickster_kgw_apply_duration_seconds(Histogram) - Duration of applying generated configuration to the data plane, observed only on passes that reload ittrickster_kgw_generated_objects(Gauge) - Size of the routing model the last pass produced- labels:
kind-listeners,routes,backends,certificatesorpolicies
- labels:
trickster_kgw_status_write_failures_total(Counter) - Count of status writes the API server refused, after conflict retries- labels:
kind- the kind of the object whose status could not be written
- labels:
trickster_kgw_leader(Gauge) - 1 when this replica holds the leader election Lease and so writes status and Events, 0 otherwisetrickster_kgw_last_successful_sync_time_seconds(Gauge) - Epoch timestamp of the last reconcile pass whose generated configuration is running, for staleness alertingtrickster_kgw_route_info(Gauge) - A constant 1 per generated backend, joining it to the Kubernetes object it serves- labels:
kind-HTTPRouteorIngressroute- the object’s namenamespace- the object’s namespacebackend_name- the generated backend’s name, as thebackend_namelabel of the request metrics carries it
For example, request rates per Kubernetes route:
sum by (kind, namespace, route) ( rate(trickster_proxy_requests_total[5m]) * on (backend_name) group_left (kind, namespace, route) trickster_kgw_route_info )- labels:
In addition to these custom metrics, Trickster also exposes the standard Prometheus metrics that are part of the client_golang metrics instrumentation package, including memory and cpu utilization, etc.
2 - Distributed Tracing via OpenTelemetry
Trickster instruments Distributed Tracing with OpenTelemetry. We import the OpenTelemetry golang packages to instrument support for tracing.
As OpenTelemetry evolves to support additional exporter formats, we will work to extend Trickster to support those as quickly as possible. We also make a best effort to update our otel package imports to the latest releases, whenever we publish a new Trickster release. You can check the go.mod file to see which release of opentelemetry-go we are is using. In this view, to see which version of otel a specific Trickster release imports, use the branch selector dropdown to switch to the tag corresponding to that version of Trickster.
Supported Tracing Backends
- Jaeger (via OTLP)
- Console/Stdout (printed locally by the Trickster process)
Trickster’s OTLP exporter supports OTLP over HTTP and gRPC. HTTP is the default
for existing OTLP configs. For Jaeger over OTLP/HTTP, configure Trickster with
the collector’s HTTP endpoint, for example http://jaeger:4318/v1/traces. For
Jaeger over OTLP/gRPC, set protocol: grpc and use the collector’s gRPC
endpoint, for example http://jaeger:4317 from another Compose service or
http://127.0.0.1:4317 from the host when using the developer Compose
environment.
Configuration
Trickster allows the operator to configure multiple tracing configurations, which can be associated into each Backend configuration by name.
The example config has exhaustive examples of configuring Trickster for distributed tracing.
For OTLP tracing, protocol selects the exporter transport. Supported values
are http and grpc; when omitted, Trickster uses http for backward
compatibility with existing configs.
Context Propagation
When tracing is enabled for a Backend, Trickster uses the W3C Trace Context and Baggage propagators. It extracts incoming traceparent, tracestate, and baggage headers from client requests and injects the active outbound origin request span into the proxied request. This lets downstream Origins continue the same distributed trace instead of starting an unrelated trace.
Sampling
Trickster uses parent-based sampling for traced requests. The configured sample_rate controls root traces that Trickster starts when there is no sampled upstream trace context. When an incoming request already has a remote parent trace, Trickster follows the parent’s sampling decision so sampled upstream traces continue across the proxy boundary and unsampled upstream traces remain unsampled.
Span List
Trickster can insert several spans to the traces that it captures, depending upon the type and cacheability of the inbound client request, as described in the table below.
| Span Name | Observes when Trickster is: |
|---|---|
| request | initially handling the client request by a Backend |
| QueryCache | querying the cache for an object |
| WriteCache | writing an object to the cache |
| DeltaProxyCacheRequest | handling a Time Series-based client request |
| FetchFastForward | making a Fast Forward request for time series data |
| FetchTimeSeries | retrieving time series data from an Origin |
| FetchRange | retrieving one sharded time range from an Origin |
| Fetch | retrieving one object or range from an Origin |
| FetchRevalidation | revalidating a stale cache object against its Origin |
| ProxyRequest | communicating with an Origin server to fulfill a client request |
| PrepareFetchReader | preparing a client response from a cached or Origin response |
| CacheRevalidation | revalidating a stale cache object against its Origin |
| FetchObject | retrieving a non-time-series object from an Origin |
Tags / Attributes
Trickster supports adding custom tags to every span via the configuration. Depending upon your preferred tracing backend, these may be referred to as attributes. See the example config for examples of adding custom attributes.
Trickster also supports omitting any tags that Trickster inserts by default. The list of default tags are below. For example on the “request” span, an http.url tag is attached with the current full URL. In deployments where that tag may introduce too much cardinality in your backend trace storage system, you may wish to omit that tag and rely on the more concise path tag. Each tracer config can be provided a string list of tags to omit from traces.
Attributes added to request and core proxy/cache/fetch spans
backend.namebackend.providercache.namecache.providerrouter.path- request path trimmed to the route match path for the request (e.g.,/api/v1/query), good for aggregating when there are large variations in the full URL pathrouter.handler
These resource attributes are attached when the corresponding backend, cache, or route configuration is available to the request flow.
Attributes added to top level (request) span
http.url- the full HTTP request URL
Attributes added to cache/proxy spans
cache.status- the lookup or proxy cache status where available. See the cache status reference for a description of the attribute values.
Attributes added to proxy/fetch spans
http.status_code- the HTTP status returned by the Origin or generated proxy response, when available.
Attributes added to the FetchRevalidation span
isRange- is true if the client request includes an HTTPRangeheader
Attributes added to the FetchObject span
isPCF- is true if the origin is configured for Progressive Collapsed Forwarding
3 - Access and Error Logs
Trickster can write HTTP access logs and error logs, per backend or for the
whole process, with customizable formats, rotation and retention. Both logs
are off by default; each is enabled by configuring its filename, which may be
a file path or the stdout or stderr stream.
Basic Configuration
backends:
example1:
provider: rp
origin_url: http://example.com/
access_log:
filename: /var/log/trickster/example1.access.log
error_filename: /var/log/trickster/example1.error.log
- The access log receives one line per request handled by the backend and is
written only when
filenameis set. - The error log receives one line per request whose response status is at or
above
error_threshold(default400) and is written only whenerror_filenameis set. An error-logged request also appears in the access log when both are configured. - Two backends may share a filename; they will safely share the underlying file and its rotation.
- When
instance_idis set in the main config, it is inserted into log filenames just as with the application log (e.g.,example1.access.1.log).
Default Access Log
A top-level access_log section applies to every backend that does not define its own access_log, and also captures requests that no backend route handled: router 404s and the built-in ping, readiness, health and management endpoints. Those unmatched lines report - for the backend and provider. Requests on the metrics listener are never access-logged.
access_log:
filename: stdout
format: json
backends:
api:
provider: rp
origin_url: http://api:8080/
quiet:
provider: rp
origin_url: http://quiet:8080/
access_log: {}
A backend’s own access_log replaces the default entirely rather than merging with it, so the empty block on quiet disables access logging for that backend. Lines for a backend carry its name and provider whichever configuration produced them, and a request is logged exactly once even when both the backend and the default write to the same target.
Logging to Standard Output
filename and error_filename accept the special values stdout and stderr in place of a path, for container platforms that collect logs from the process streams. A stream is never rotated or pruned, ignores rotation, retention, compress and instance_id, and may be shared by any number of backends and the default access log regardless of their other settings. Lines are still buffered for up to one second before being written.
access_log:
filename: stdout
error_filename: stderr
Log Format
The format option accepts either a named preset or a custom format string
using Apache-style % tokens, so the well-known conventions from Apache
HTTP Server, Apache Traffic Server, Lighttpd, and similar servers apply
directly.
Presets
| Name | Description |
|---|---|
common | NCSA Common Log Format: %h %l %u %t "%r" %>s %b |
combined | Apache/Nginx Combined format: common + Referer and User-Agent. This is the default. |
extended | combined + duration (ms), cache status and backend name |
json | One JSON object per line with a fixed field set (see below) |
Custom Formats
access_log:
filename: /var/log/trickster/example1.access.log
format: '%h %u %t "%r" %>s %b %{ms}T %{cache-status}x'
Supported tokens:
| Token | Description |
|---|---|
%h, %a | client IP address, resolved through the listener’s trusted_proxies when configured |
%{c}a | IP address of the connection peer, which is the proxy when one is trusted |
%l | remote logname (always -) |
%u | authenticated username (from HTTP Basic Auth), else - |
%t | request start time in CLF format: [26/Aug/2026:10:30:00 +0000] |
%{sec}t, %{msec}t, %{usec}t | request start time as a Unix epoch value |
%{LAYOUT}t | request start time in a custom Go time layout |
%r | first line of the request: GET /path?query HTTP/1.1 |
%m | request method |
%U | request URL path |
%q | query string, prefixed with ?, or empty when none |
%H | request protocol (e.g., HTTP/1.1) |
%s, %>s | response status code |
%b | response body bytes, or - when zero (CLF style) |
%B | response body bytes, numeric |
%D | request duration in microseconds |
%T | request duration in whole seconds |
%{us}T, %{ms}T, %{s}T | request duration in the given unit |
%{Name}i | request header value |
%{Name}o | response header value |
%{Name}c | request cookie value |
%v | requested virtual host |
%p | listener port that served the request |
%A | listener IP address that served the request |
%% | a literal % |
Trickster-specific values use the %{key}x extension namespace:
| Token | Description |
|---|---|
%{backend}x | backend name |
%{provider}x | backend provider type |
%{cache-status}x | cache result (hit, phit, kmiss, …); see Cache Status |
%{engine}x | proxy engine that handled the request (e.g., DeltaProxyCache) |
%{path-config}x | the matched path config path |
%{upstream-addr}x | host:port of the origin the request was proxied to, or - when none was contacted |
%{upstream-status}x | status code the origin answered with |
%{upstream-duration}x | duration of the origin exchange in milliseconds |
%{trace-id}x, %{span-id}x | the request’s trace and span identifiers when tracing is enabled |
%{request-id}x | the request’s X-Request-ID; see below |
%{key}e | a static value declared under extra; see below |
Missing values render as -. Values derived from the request (like headers
and usernames) are backslash-escaped so they cannot corrupt the log line
structure. Unknown tokens fail validation at startup.
The json preset emits these fields per line: time, client_ip,
remote_ip, user, method, path, query, proto, status, bytes,
duration_ms, host, referer, user_agent, backend, provider,
path_config, cache_status, engine, upstream_addr, upstream_status,
upstream_duration_ms, trace_id, span_id, request_id, and an extra
object holding the declared extra values when there are any.
Client Address
%h and %a are the client’s address as Trickster resolved it. Without
trusted_proxies on the listener that is the address of the connection
peer. With it, a connection from a trusted proxy is attributed to the
nearest address in Forwarded or X-Forwarded-For that is not itself a
trusted proxy, or to X-Real-IP when neither is present, so a log line
names the client behind a load balancer rather than the balancer. %{c}a
is always the connection peer. See Trusted Proxies
for the listener settings.
Request ID
A format that logs %{request-id}x gives every request an identifier: the
X-Request-ID header the client sent, or a random 128-bit hexadecimal
value assigned on arrival. The identifier is set on the request, so the
origin receives it in X-Request-ID, and echoed on the response, so a
client can quote it. A format that does not log it assigns none.
Extra Values
extra declares static values for a backend’s log lines, rendered by
%{key}e and emitted as the json preset’s extra object:
backends:
example:
access_log:
filename: /var/log/trickster/example.access.log
format: '%h %t "%r" %>s %b %{team}e'
extra:
team: payments
A key may not contain %, { or }. A token naming an undeclared key
renders -. The Kubernetes controller declares route_kind,
route_namespace and route_name on every backend it generates, so a line
names the Ingress, HTTPRoute or GRPCRoute it served.
Dropped Lines
A log line the writer cannot accept, because its bounded buffer is full or
the file cannot be opened, is dropped rather than blocking the request, and
counted in the trickster_accesslog_dropped_lines_total metric by backend
and log (access or error).
Rotation and Retention
Access and error logs are rotated and pruned automatically, using
nginx/logrotate-style numbered archives (example1.access.log.1.gz is the
most recent archive, .2.gz the next, and so on).
access_log:
filename: /var/log/trickster/example1.access.log
rotation:
size: 256MB # rotate when the live file would exceed this size (default 256MB)
interval: 1d # also rotate when the live file is older than this (default off)
retention:
count: 3 # keep at most 3 archives (default 80)
age: 7d # also prune archives older than this (default 7d)
compress: true # gzip archives (default true)
sizeandintervalmay be combined; the log rotates when either threshold is reached. Setting both to0disables rotation.- Sizes accept
KB,MB,GBandTBsuffixes (binary multiples), or a plain byte count. retention.count: 0disables count-based pruning and keeps all archives.- Writes are buffered for up to one second or 64 KiB. A process or machine crash can lose the buffered tail; an orderly shutdown flushes it.
- Interval rotation keeps its epoch in a
<filename>.rotationsidecar so a restart does not reset the interval clock.
Archives created by older Trickster releases use timestamped lumberjack names and are not included in numbered-archive retention. They form a bounded legacy set and may be removed manually after upgrading.
When upgrading from the original logging implementation, note these filename and retention changes:
retention.count: 0now keeps all archives; configure a positive count to bound archive retention.- With
main.instance_idenabled, filenames without a.logsuffix now also include the instance ID (trickster.outbecomestrickster.2.out). Update log shippers that still follow the unsuffixed filename.
The same rotation, retention and compress options are also available
in the main logging: config section to control rotation of the Trickster
application log, with the same defaults.
Error Log Settings
Each error_* option inherits its value from the corresponding access log
option when unset:
access_log:
filename: /var/log/trickster/example1.access.log
format: combined
error_filename: /var/log/trickster/example1.error.log
error_format: '' # default: inherits format
error_threshold: 400 # log responses with status >= this (default 400)
error_rotation: # default: inherits rotation
size: 64MB
error_retention: # default: inherits retention
count: 7
error_compress: true # default: inherits compress
4 - X-Trickster-Result Header
Trickster adds the X-Trickster-Result response header to describe how it handled a request. The header is intended for debugging cache behavior, proxy fallbacks, and partial origin fetches. A path may withhold it from the client with hide_result_header: true (paths.md); the access log and metrics still record the result.
Example:
X-Trickster-Result: engine=DeltaProxyCache; status=phit; fetched=[1612804980000-1612808580000]; ffstatus=hit
The header value is a semicolon-separated list of fields. Optional fields are included only when Trickster has a value for them.
| Field | Description |
|---|---|
engine | The proxy engine that handled the response, such as HTTPProxy, ObjectProxyCache, or DeltaProxyCache. |
status | The cache or proxy result. See Cache Status. |
fetched | Time ranges fetched from the origin to satisfy the response. Ranges are formatted as start-end; multiple ranges are separated by semicolons inside the brackets. |
ffstatus | Fast Forward cache result for time series requests. Possible values are hit, miss, off, or err. |
failed | Time ranges that Trickster attempted to fetch but could not fetch successfully. This usually appears with proxy-error or partial fanout failures. |
Result Statuses
status uses the same values reported in metrics, logs, and tracing. Common examples are:
| Status | Meaning |
|---|---|
hit | The response was served fully from cache. |
phit | Part of the response was served from cache and part was fetched from the origin. |
kmiss | Trickster had no object for the cache key and fetched the response from the origin. |
rmiss | Trickster had an object for the cache key, but not for the requested range. |
rhit | Trickster revalidated a stale cached object against the origin and served it as a hit. |
nchit | The response was served from the Negative Cache. |
purge | The cache key was purged as directed by a request or response header. |
proxy-hit | The request joined an in-flight origin fetch for the same cache key. |
proxy-only | The request was proxied to the origin without writing or reading a cache object. |
proxy-error | An upstream request needed for the response returned an error. |
error | Trickster encountered a cache lookup or cache handling error. |
Proxy-Only Results
status=proxy-only means the response came from the origin through Trickster’s proxy path, without a cache read or cache write for that request. It does not necessarily mean the origin response was wrong.
Common reasons include:
| Cause | Example |
|---|---|
| Backend or path is configured to bypass caching | provider: reverseproxy or proxy_only: true. |
| Client request prevents caching | A request such as Cache-Control: no-cache can force Trickster to proxy and remove the existing object for that cache key. |
| Origin response is not cacheable | For example, response cache headers do not provide cacheability, or the response includes headers that Trickster treats as not cacheable. |
| Time series request cannot be parsed for delta caching | Trickster may fall back to object proxy cache for compatible requests, or proxy the request directly when it cannot safely cache the query shape. |
| Time series range is outside the retained cache window | Old data may be proxied without caching while newer ranges remain cacheable. |
When investigating proxy-only, check the backend provider, any proxy_only setting, request and response Cache-Control headers, and whether the request shape is supported by the configured backend provider.
Fetched And Failed Ranges
fetched and failed describe the ranges Trickster fetched or failed to fetch while serving the response.
Example:
X-Trickster-Result: engine=DeltaProxyCache; status=phit; fetched=[1612804980000-1612808580000;1612812180000-1612815780000]
For time series responses, range values are Unix timestamps in milliseconds. A phit result with fetched ranges usually means Trickster had some of the requested data cached and fetched the missing ranges from the origin.
failed ranges indicate the origin request for those ranges failed. Depending on the proxy engine and fanout behavior, Trickster may return an error response or a partial response with failure metadata.
Fast Forward Status
ffstatus appears on time series responses when the Delta Proxy Cache checks Fast Forward data:
| Fast Forward Status | Meaning |
|---|---|
hit | Fast Forward data was served from cache. |
miss | Fast Forward data was fetched from the origin. |
off | Fast Forward was not attempted for this request. |
err | Fast Forward was attempted but failed or returned unusable data. |
Fast Forward is only relevant for supported time series backends and only when the request is eligible for the latest datapoint optimization.