Skip to content

nginx

GeoMetrikks reads a keyed JSON access log. Add this log_format to the http block in your nginx.conf (nginx 1.11.8 or later for escape=json):

log_format geometrikks_json escape=json
'{'
'"client_ip":"$remote_addr",'
'"timestamp":"$time_iso8601",'
'"method":"$request_method",'
'"path":"$request_uri",'
'"protocol":"$server_protocol",'
'"status":"$status",'
'"bytes":"$body_bytes_sent",'
'"host":"$host",'
'"referrer":"$http_referer",'
'"user_agent":"$http_user_agent",'
'"remote_user":"$remote_user",'
'"request_time":"$request_time",'
'"upstream_time":"$upstream_response_time",'
'"request_raw":"$request"'
'}';

Then use it on the access log you want GeoMetrikks to tail:

access_log /config/log/nginx/access.log geometrikks_json;

Keep every value quoted, including the numbers: nginx has no typed output, and an unquoted empty variable breaks the line. escape=json is required; without it a quote inside a user agent produces invalid JSON, and the line is skipped and counted as unparseable. escape=json leaves bytes above 0x7f raw, so a probe line can carry undecodable bytes; GeoMetrikks replaces them with U+FFFD and still classifies the line. client_ip and timestamp are the only required keys. Drop any other key and the feature it feeds goes empty (host feeds the host filter, request_time and upstream_time feed the response-time analytics). Add your own keys freely; GeoMetrikks ignores the ones it does not know.

LOGPARSER_LOG_FORMATS=geometrikks-json pins the parser to this format instead of detecting it per file.

$remote_addr is only the visitor’s address if nginx sees the visitor directly. Behind a CDN, tunnel, or another proxy, see docs/proxy-setup.md for the realip config that logs the visitor instead of that hop.

Earlier versions documented this positional format. It keeps working for both live tailing and import-logs, so an existing install needs no change, and archives already written in it import as before. Use the JSON format above for new setups.

log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" $host "$http_user_agent" '
'"$request_time" "$upstream_response_time"';

The parser matches this format on position and quoting rather than on field names, so a rearranged format can land values in the wrong columns instead of failing outright. Four rules:

  • Use $time_local. $time_iso8601 does not match at all, and a file that uses it produces no rows.
  • Keep $host unquoted and between "$http_referer" and "$http_user_agent". Writing "$host" still parses, but the hostname ends up in the user-agent column and host comes out empty.
  • Keep $request_time and $upstream_response_time quoted. Unquoted, both are dropped and read as 0.
  • Append extra fields only after both timing fields. The parser fills the two timing slots by quoting alone, so on a format without them an extra quoted field lands in $request_time. A non-numeric value such as "$http_x_forwarded_for" is discarded, but a numeric one is recorded and charted as a response time.

LOGPARSER_LOG_FORMATS=nginx pins the parser to this format.

Backfilling logs written in another format

Section titled “Backfilling logs written in another format”

Lines in nginx’s built-in combined format also parse, so you can import archives you have on disk without having changed your nginx config first. Three fields are absent from those lines and cannot be recovered after the fact:

Missing field What it costs you
$host The host filter on the access-log and analytics pages has nothing to list
$request_time Response-time cards show n/a for those rows; rows imported by earlier versions carry a placeholder 0.0 that backfill-timings clears
$upstream_response_time Upstream timing stays empty in the access-log detail view

The map, geo analytics, status codes, URLs, referrers, user agents and bytes are unaffected.

LOGPARSER_LOG_PATHS accepts a single path or a JSON list, so nginx can log to more than one file and GeoMetrikks tails all of them:

access_log /config/log/nginx/somepage/access.log geometrikks_json;
access_log /config/log/nginx/access.log geometrikks_json;
Terminal window
LOGPARSER_LOG_PATHS=["/var/log/access/access.log", "/var/log/access/somepage/access.log"]