Analytics

The Analytics configuration defines where tilegroxy records lightweight events describing successful tile usage. Where telemetry aggregates counters for operating the service, analytics records individual events that can be attributed to a layer, a coordinate and optionally a user, written to a destination you own and can query. This is useful for understanding which layers are actually consumed, attributing usage to tenants or users, and tracking consumption of a metered upstream provider.

Like other entities, the analytics configuration uses a parameter called "name" to dictate the type of analytics module which controls the specific list of configuration parameters available.

Analytics is disabled by default; with no analytics section configured the none module is used, no events are produced and the cost to each request is a single check.

An event is produced when, and only when, a tile is successfully served over HTTP. Requests that fail, such as a bad layer name, invalid coordinates, an out-of-bounds tile or a provider error, produce no event, nor do requests rejected by authentication. Tiles produced by the seed and test commands and health check tiles produce no events since they don’t represent real usage. A layer rendered indirectly through the ref provider isn’t recorded separately; only the layer that was actually requested is. A cache hit still produces an event; the event reflects that a user consumed a tile, not that a provider generated one.

The event is emitted after the response has been written, so recording never adds latency to the request. Individual layers can be excluded by setting skipAnalytics on the layer, see Layer.

Analytics is best-effort. A failing or slow destination must never degrade tile serving, therefore errors from an analytics module are logged and discarded; they never reach the user and never change a response. Events are buffered in memory and written in batches. If the buffer fills because the destination cannot keep up, events are dropped by default instead of delaying requests. Set batch.onFull to block if you would rather apply backpressure than lose events. Buffered events are flushed on shutdown and when configuration is hot reloaded, so an orderly restart doesn’t lose the current batch, however events still buffered during an abrupt termination are lost. If you need a complete, auditable record of every request, use access logs instead.

Every module accepts the same batch parameters. A batch is written when either maxSize events have accumulated or the oldest event in the buffer reaches maxAge. Note the age of a partial batch is only checked periodically so a batch may be written up to 25% later than maxAge.

Parameter Description Type Required Default

MaxSize

Write a batch once this many events have accumulated

uint

No

1000

MaxAge

Write a partial batch after this many seconds so low-traffic layers still report promptly

uint

No

10

QueueSize

The number of events held in memory awaiting a write. Raise this to absorb larger bursts at the cost of memory

uint

No

10000

Workers

How many batches may be written concurrently

uint

No

1

OnFull

What to do when the queue is full. Can be drop or block. Drop discards the event and logs a periodic warning; block makes the request wait for room

string

No

drop

Event Contents

Every event always includes the following, which cannot be disabled:

Field Description

time

When the tile was served

layer

The ID of the layer as configured. When a layer uses a pattern this is the configured ID, not the name from the URL, matching how per-layer telemetry metrics are recorded

z, x, y

The tile coordinates

user

The authenticated user, or empty when the request was anonymous. Only the jwt and custom authentication modules establish a user identity

Additional attributes are opt-in via fields, which accepts any of the following names:

Name Description

layername

The layer name exactly as it appeared in the URL, which differs from the layer ID when the layer uses a pattern

layerparams

The placeholder values extracted from a patterned layer name, as a map

ip

The client IP address

useragent

The User-Agent header

referer

The Referer header

host

The Host header

method

The HTTP method

path

The request path

query

The raw query string

duration

How long the request took, in milliseconds

bytes

The size of the served tile in bytes

contenttype

The MIME type of the served tile

An unrecognized name causes startup to fail, so a typo surfaces when you run tilegroxy config check instead of producing a column of empty values.

Be aware that ip, useragent and user IDs are personal data in many jurisdictions. They are off by default; enable them only if you have a basis to record them and consider your retention policy for the destination.

Custom Attributes

The extraFields parameter records arbitrary additional attributes. Each key is the attribute name in the destination and each value selects where it comes from:

Value form Description

ctx.<key>

A value from the request context. Includes ip, path, method, host, query, query-string, proto and uri

hdr.<name>

A request header. The name is canonicalized to Header-Case before lookup

anything else

Used as a literal constant, useful for tagging events with an environment or region name

Because env. and secret. are handled generically for all configuration, they also work here and resolve once at startup instead of per request.

Metrics

When telemetry is enabled, analytics reports three counters: tilegroxy.analytics.recorded for events successfully written to a destination, tilegroxy.analytics.dropped for events discarded because a queue was full, and tilegroxy.analytics.error for events in batches that failed to write. A steadily increasing dropped or error count means analytics is losing data even though tiles are being served normally, so alert on these separately from tile metrics.

Example:

analytics:
  name: clickhouse
  id: warehouse
  datastore: ch-0
  table: tile_events
  fields:
    - duration
    - bytes
  extraFields:
    tenant: hdr.X-Tenant-Id
    environment: production
  batch:
    maxSize: 5000
    maxAge: 30

A runnable demo combining tilegroxy, a PostgreSQL destination, a map and a dashboard over the recorded events is available in examples/analytics-demo.