Access logs
Zero-code sources: ship existing nginx/Caddy/Traefik/Bunny logs with Vector or Fluent Bit.
You can ship existing web-server access logs straight into MetrikStack with Vector or Fluent Bit, without touching your application or edge config at all. The configurations below are complete starting points.
| Setup | Endpoint |
|---|---|
| nginx / Caddy / Traefik logs with Vector | POST /v1/logs/generic |
| bunny.net Log Forwarding (syslog) with Vector | POST /v1/logs/bunny |
| nginx / Caddy / Traefik logs with Fluent Bit | POST /v1/logs/generic |
Both endpoints accept newline-delimited lines (Combined Log Format, or JSON
per line as produced by nginx escape=json, Caddy, or Traefik) or a JSON
array of strings. Fluent Bit's json_lines output wraps each line as {"log": "..."}; the endpoint unwraps log and message keys.
Create a source of kind logs (or edge_bunny for the Bunny variant) in the
dashboard to get an ingest token, used as METRIKSTACK_TOKEN below. Requests
are filtered server-side: only GET/HEAD page requests count; assets,
redirects and unparsable lines are skipped and reported in the response as
skipped / unparsed.
Supported formats
- Combined Log Format (nginx, Apache-style default log)
- JSON lines: nginx (
log_format ... escape=json), Caddy's default JSON access log, Traefik's JSON access log - Bunny pipe-delimited Log Forwarding format, via
/v1/logs/bunny
nginx / Caddy / Traefik with Vector
# Vector: tail nginx/Caddy/Traefik access logs and ship them to the
# MetrikStack log endpoint. Lines are forwarded verbatim; the endpoint parses
# Combined Log Format and JSON-per-line automatically and skips assets.
#
# METRIKSTACK_TOKEN=in_... METRIKSTACK_ENDPOINT=https://api.example.com vector --config vector-nginx.toml
[sources.access_logs]
type = "file"
include = ["/var/log/nginx/access.log", "/var/log/caddy/access.log"]
read_from = "end"
[transforms.only_lines]
type = "remap"
inputs = ["access_logs"]
source = '''
# Keep only the raw line; drop Vector metadata.
. = { "message": .message }
'''
[sinks.metrikstack]
type = "http"
inputs = ["only_lines"]
uri = "${METRIKSTACK_ENDPOINT}/v1/logs/generic"
method = "post"
encoding.codec = "text"
framing.method = "newline_delimited"
compression = "gzip"
batch.max_events = 500
batch.timeout_secs = 5
request.headers.Authorization = "Bearer ${METRIKSTACK_TOKEN}"
request.retry_attempts = 3Bunny Log Forwarding with Vector
# Vector: receive bunny.net Log Forwarding (syslog, RFC 5424) and ship the
# raw Bunny log lines to the MetrikStack Bunny endpoint.
#
# In the bunny.net panel: Pull Zone -> Logging -> Log Forwarding -> point it
# at this host on port 6514 (TCP). Bunny hashes/anonymises IPs when the
# pull zone's "Anonymize IPs" option is on; leave it off so visitors can be
# counted per day (IPs are never stored; see Privacy & data retention).
[sources.bunny]
type = "syslog"
address = "0.0.0.0:6514"
mode = "tcp"
[transforms.raw]
type = "remap"
inputs = ["bunny"]
source = '''
. = { "message": .message }
'''
[sinks.metrikstack]
type = "http"
inputs = ["raw"]
uri = "${METRIKSTACK_ENDPOINT}/v1/logs/bunny"
method = "post"
encoding.codec = "text"
framing.method = "newline_delimited"
compression = "gzip"
batch.max_events = 500
batch.timeout_secs = 5
request.headers.Authorization = "Bearer ${METRIKSTACK_TOKEN}"
request.retry_attempts = 3See Bunny for how to point a Bunny Pull Zone's Log Forwarding at this.
Fluent Bit
# Fluent Bit: tail an access log and POST newline-delimited lines to the
# MetrikStack log endpoint.
#
# METRIKSTACK_TOKEN=in_... METRIKSTACK_HOST=api.example.com fluent-bit -c fluent-bit.conf
[SERVICE]
Flush 5
Daemon Off
Log_Level info
[INPUT]
Name tail
Path /var/log/nginx/access.log
Tag access
Read_from_Head Off
Skip_Long_Lines On
[OUTPUT]
Name http
Match access
Host ${METRIKSTACK_HOST}
Port 443
tls On
URI /v1/logs/generic
# Fluent Bit cannot emit raw text; the endpoint accepts a JSON array and
# Fluent Bit's json_lines with the "log" key. Use json_lines + the
# `log` field, which the endpoint unwraps.
Format json_lines
Header Authorization Bearer ${METRIKSTACK_TOKEN}
Retry_Limit 3No request id, no problem (usually)
Log lines have no way to carry a request_id, so a log source relies on the
fallback dedupe window when combined with another source
for the same site: an event without a request_id from a non-primary source
is matched against events for the same site, visitor and path within a 2 s
window. If a site runs a log source as its only source, this doesn't apply:
every line becomes a pageview directly.