Connect your data

Server log formats

The access log formats that VitalSentinel Server Log Monitoring reads, the fields it needs, and how to configure Nginx, Apache and CDN logs.

View as Markdown

Server Log Monitoring reads the access logs of your web server, load balancer or CDN. This page lists the log formats that VitalSentinel reads, the fields that each log line must have, and example server settings. Use it before you connect an SFTP, FTPS, bucket or upload source. To connect a source, see Server logs.

The Cloudflare Worker does not use log files. If your site runs behind Cloudflare, the Worker collects the requests directly, and this page does not apply to it.

How VitalSentinel finds the log format

You do not select a log format. VitalSentinel examines the first lines of each file and finds the format automatically. Until it confirms the format, the Log source card in Server Log Monitoring Settings shows Log format as Auto-detect. After the first file, the card shows the format name, for example Combined (Apache/Nginx).

VitalSentinel also detects compression from the file content, not from the file name. It reads plain text files and gzip (.gz) files. For SFTP, FTPS and bucket sources, it also reads bzip2, zstd and zip files.

If VitalSentinel cannot detect the format of a custom Nginx log, the app asks for your Nginx log_format line. See Custom Nginx log formats.

Log formats that VitalSentinel reads

The Log format row of the Log source card uses these names:

Log formatWritten by
Combined (Apache/Nginx)Apache and Nginx with the default combined format
Custom Nginx log_formatNginx with your own log_format, when you give VitalSentinel the format line
IIS (W3C extended)Microsoft IIS, with a #Fields: header line in each file
Newline-delimited JSONServers and tools that write one JSON object for each request, on one line
Cloudflare log fieldsCloudflare Logpush, with the HTTP requests dataset
AWS Application Load BalancerAWS Application Load Balancer access logs
AWS CloudFrontAWS CloudFront standard logs in the W3C format

VitalSentinel does not read other formats, for example the Common log format, Parquet files or CSV exports.

The Common log format does not work

The Common log format (Apache common) has no User-Agent field. VitalSentinel uses the User-Agent to find the bot that sent each request, so it rejects Common logs. The error on the Log source card starts with "this log has no User-Agent or Referer field (Apache/Nginx Common format)."

To fix it, change your server to the Combined format. The next files that the server writes then work. Old files in the Common format stay unusable.

Fields that VitalSentinel needs

Each log line must have these fields:

  • Time of the request, with a time zone.
  • Request path, the URL that the client asked for.
  • Status code, the HTTP answer of your server, for example 200 or 404.
  • User-Agent, the name that the client sends. VitalSentinel uses it to identify Googlebot, AI crawlers and other bots.
  • Client IP address. VitalSentinel uses it to verify that a bot is real and not a fake bot.

These fields are optional, but each one unlocks more reports: request method, query string, referrer, response size and response time. Content type, cache status, host name, country and network (ASN) are also optional.

If a source does not record a field, the Log source card shows Capabilities, with the reports that the missing field disables. See Server logs.

Apache and Nginx combined format

The Combined format is the default format of Apache and Nginx. In most cases, you do not change anything. The Nginx combined format is:

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

The Apache combined format is:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
CustomLog "logs/access_log" combined

VitalSentinel also detects a Combined line with more quoted fields at the end. An example is the Nginx main format, which adds "$http_x_forwarded_for". VitalSentinel ignores these extra fields.

Make sure your server uses the combined format

Look at your server configuration:

  • Nginx: find the access_log line. If it ends with combined, main or no format name, the format works.
  • Apache: find the CustomLog line. If it ends with combined, the format works. If it ends with common, change it to combined.

Reload the server after a change. The new lines use the new format.

Custom Nginx log formats

You can use your own Nginx log_format, for example to record the response time. VitalSentinel cannot always detect a custom format automatically. If it cannot, the next collection run fails, and the Log source card shows the error.

To give VitalSentinel your format:

  1. On the Log source card, click Edit.
  2. Click Test connection. The form shows a warning and the field Nginx log_format directive.
  3. Paste the exact log_format line from your Nginx configuration.
  4. Click Test connection again, then click Save changes.

The warning starts with "The connection works, but the last collection run could not process this source's log format".

A custom format must include $time_local or $time_iso8601. Without a time variable, VitalSentinel cannot read the lines.

Example format with response time

This format adds the response time and the content type to the combined format:

log_format vitalsentinel '$remote_addr - $remote_user [$time_local] '
                         '"$request" $status $body_bytes_sent '
                         '"$http_referer" "$http_user_agent" '
                         '$request_time "$sent_http_content_type"';

access_log /var/log/nginx/access.log vitalsentinel;

When VitalSentinel asks for the format line, paste the whole log_format vitalsentinel ...; statement.

Nginx variables that VitalSentinel reads

VitalSentinel reads these Nginx variables in a custom format. It ignores other variables.

DataVariables
Time$time_local, $time_iso8601
Client IP$remote_addr, $http_x_forwarded_for
Request$request, $request_method, $request_uri, $uri, $document_uri, $args, $query_string
Answer$status, $body_bytes_sent, $bytes_sent, $sent_http_content_type, $upstream_cache_status
Time taken$request_time, $upstream_response_time
Client$http_user_agent, $http_referer
Host$host, $http_host

VitalSentinel uses $http_x_forwarded_for only when the format has no $remote_addr. Any client can write a false value into this header.

Log the real client IP behind a proxy or CDN

If a CDN, a load balancer or a reverse proxy is in front of your server, the server sees the address of the proxy. Then every log line shows the same few IP addresses. VitalSentinel cannot verify the bots, and it can mark real Googlebot requests as fake.

VitalSentinel reads the client address field of the log line ($remote_addr in Nginx, %h or %a in Apache). It does not read an extra X-Forwarded-For column of a Combined line. Thus, configure the server to put the real client IP into the client address field.

Trust only the IP addresses of your own proxy or CDN. If you trust all addresses, any client can send a false IP address in the header.

Nginx real client IP

Nginx sets the real client IP with the realip module. Nginx must include this module (--with-http_realip_module). To make sure, run nginx -V and look for the module in the output.

For a load balancer or proxy that sends X-Forwarded-For, add this to the http block:

set_real_ip_from  10.0.0.0/8;      # the address range of your proxy
real_ip_header    X-Forwarded-For;
real_ip_recursive on;

For Cloudflare, use the CF-Connecting-IP header. Add one set_real_ip_from line for each Cloudflare IP range. Cloudflare publishes the ranges at https://www.cloudflare.com/ips/ and changes them from time to time.

set_real_ip_from  192.0.2.0/24;    # repeat for each Cloudflare range
real_ip_header    CF-Connecting-IP;

After the change, $remote_addr in the combined format contains the real client IP.

Apache real client IP

Apache sets the real client IP with the mod_remoteip module.

  1. Turn on the module. On Debian and Ubuntu, run sudo a2enmod remoteip.
  2. Add RemoteIPHeader and one RemoteIPTrustedProxy line for each address range of your proxy.
  3. In the combined format, replace %h with %a.
  4. Restart Apache.
RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 10.0.0.0/8
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

For Cloudflare, use RemoteIPHeader CF-Connecting-IP and add each range from https://www.cloudflare.com/ips/.

IIS, JSON and other formats

IIS (W3C extended)

Use the W3C log file format of IIS. Each file must start with a #Fields: header line, because the header tells VitalSentinel the order of the columns. In the IIS logging fields, select at least date, time, cs-uri-stem, sc-status, c-ip and cs(User-Agent).

Newline-delimited JSON

Each line must be one JSON object for one request. VitalSentinel finds the fields by their names. These are some of the names that it reads:

DataField names
Timetimestamp, time, ts, @timestamp, datetime
Pathpath, uri, url, request_path, request_uri
Statusstatus, status_code, response_status
User-Agentuser_agent, ua, useragent, http_user_agent
Client IPip, remote_addr, client_ip, remote_ip
Methodmethod, http_method, request_method

The time must be an ISO 8601 (RFC 3339) value with a time zone, for example 2026-10-24T08:15:00Z, or a Unix timestamp in seconds or milliseconds. Each line must have a status field.

CDN and cloud provider logs

Cloudflare Logpush

If your site is on Cloudflare, the Cloudflare Worker is the simpler way to connect. As an alternative, Cloudflare Logpush can send the HTTP requests dataset to an R2, Amazon S3 or Google Cloud Storage bucket. Connect that bucket as a bucket source.

VitalSentinel reads the native Logpush field names, for example EdgeStartTimestamp, ClientRequestHost, ClientRequestURI, EdgeResponseStatus, ClientRequestUserAgent and ClientIP. Include these fields in the Logpush job. EdgeStartTimestamp can use the ISO 8601 or the Unix nanoseconds format.

Logpush availability and cost depend on your Cloudflare plan. Check the Cloudflare documentation.

AWS Application Load Balancer

AWS writes Application Load Balancer access logs to an S3 bucket. VitalSentinel reads these files as AWS writes them. Connect the bucket as an Amazon S3 source, with the log folder as the Prefix.

AWS CloudFront

CloudFront standard logging can write access logs to an S3 bucket. Use the W3C output format with tab-separated fields. Each file must have its #Fields: header line.

Include at least the fields date, time, cs-uri-stem, sc-status, c-ip and cs(User-Agent). Also include x-edge-location, because VitalSentinel uses it to tell CloudFront logs from IIS logs. VitalSentinel does not read the JSON or Parquet output of CloudFront.

Other CDNs

VitalSentinel has no format for other CDNs, for example Fastly, Akamai or Bunny CDN. If your CDN can write the Combined format or newline-delimited JSON to a bucket, connect that bucket. If not, click Request a connector in the setup. See Server logs.

Where servers and hosting panels keep access logs

Servers that you manage

ServerUsual location of the access log
Nginx/var/log/nginx/access.log, with rotated copies such as access.log.1 and access.log.2.gz
Apache on Debian and Ubuntu/var/log/apache2/access.log
Apache on RHEL and CentOS/var/log/httpd/access_log
IIS%SystemDrive%\inetpub\logs\LogFiles\W3SVC<site id>\

Your server can use a different path. The access_log line (Nginx) or the CustomLog line (Apache) shows the real path.

cPanel

In cPanel, go to Metrics > Raw Access. There you can download the access log of each domain as a .gz file. Upload this file with Manual upload. Your hosting provider can turn off this feature.

In Configure Logs, you can archive the logs to your home directory. cPanel then keeps them in /home/username/logs. If your host gives you SFTP access, you can connect this folder as an SFTP source.

Plesk

In Plesk, go to Websites and Domains, select the domain, then click Logs > Manage Log Files. Click the download icon next to a log file. Upload the file with Manual upload.

On Linux, Plesk keeps these access logs for each domain: access_log and access_ssl_log (Apache), and proxy_access_log and proxy_access_ssl_log (Nginx). Use the SSL logs for HTTPS traffic. In Log Rotation, Plesk can compress and delete old logs.

Managed hosting

Many managed hosts give a log download in their dashboard or SFTP access to a logs folder. The log format of a managed host can be different from the Combined format. Upload one file first, with Manual upload, to make sure that VitalSentinel can read it.

On this page

VitalSentinel

Catch issues before they cost you

Track SEO, performance, and uptime in one place and get alerted the moment something breaks – hours before it hits your traffic.

  • Free plan for 1 domain
  • Set up in minutes
  • No credit card required