Nginx access logs contain a wealth of information about who is visiting your site, which URLs are being requested, what errors users encounter, and where your traffic originates. Raw log files are difficult to interpret at a glance, but GoAccess transforms them into actionable, visually rich reports in seconds — either in the terminal for real-time monitoring during incidents or as a standalone HTML dashboard that you can host and share. GoAccess is fast, lightweight, and does not require a database or web framework. This tutorial covers installing GoAccess on RHEL 7 from the EPEL repository, running interactive terminal analysis, generating static HTML reports, setting up a live real-time HTML dashboard via WebSocket, serving the report through Nginx, and automating report generation with cron.

Prerequisites

  • RHEL 7 server running Nginx with access logs at /var/log/nginx/access.log
  • EPEL repository enabled, or internet access to add the GoAccess repository
  • Root or sudo access
  • Port 7890 available if using the real-time WebSocket dashboard

Step 1: Install GoAccess from EPEL

The EPEL repository provides a version of GoAccess for RHEL 7. First enable EPEL if you have not already done so:

yum install -y epel-release
yum install -y goaccess
goaccess --version

The EPEL version may be older than the latest release. If you need the most recent GoAccess with full GeoIP and WebSocket support, add the official GoAccess repository instead:

cat > /etc/yum.repos.d/goaccess.repo << 'EOF'
[goaccess]
name=GoAccess - Enhanced Web Log Analyzer
baseurl=https://packages.goaccess.io/rpm/rhel7/x86_64/
enabled=1
gpgcheck=1
gpgkey=https://packages.goaccess.io/rpm/RPM-GPG-KEY-goaccess
EOF

yum install -y goaccess
goaccess --version

Step 2: Verify Nginx Log Format

Before running GoAccess, confirm the log format that Nginx is using. Open the Nginx configuration:

grep -A5 'log_format' /etc/nginx/nginx.conf

The default combined format looks like this:

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

Confirm your access log is using this format:

tail -5 /var/log/nginx/access.log

A typical combined-format line looks like:

203.0.113.42 - - [17/May/2026:14:32:01 +0000] "GET /index.html HTTP/1.1" 200 1523 "https://example.com/" "Mozilla/5.0 (X11; Linux x86_64)"

Step 3: Run GoAccess in Interactive Terminal Mode

The simplest way to use GoAccess is to point it at an access log and launch the interactive curses-based terminal UI. This is ideal for quick analysis during an incident:

goaccess /var/log/nginx/access.log --log-format=COMBINED

The COMBINED preset corresponds to the Nginx combined log format. Once the TUI launches, navigate using these keyboard shortcuts:

  • Tab / Shift+Tab — move between panels
  • Enter — expand a panel to full screen
  • q — quit full-screen mode or exit GoAccess
  • / — scroll within a panel
  • o / O — open sub-items within an expanded panel
  • s — sort the current panel

GoAccess provides panels for: Unique Visitors, Requested Files, Static Requests, Not Found (404s), Hosts, Operating Systems, Browsers, Time Distribution, Virtual Hosts, Referrers, and HTTP Status Codes.

To analyse a compressed rotated log alongside the current log:

zcat /var/log/nginx/access.log.1.gz | goaccess - --log-format=COMBINED

To merge multiple log files into a single analysis:

cat /var/log/nginx/access.log /var/log/nginx/access.log.1 | goaccess - --log-format=COMBINED

Step 4: Generate a Static HTML Report

GoAccess can generate a fully self-contained HTML report with embedded JavaScript charts. No external dependencies or CDN calls are required:

mkdir -p /var/www/reports

goaccess /var/log/nginx/access.log 
  --log-format=COMBINED 
  --output=/var/www/reports/report.html 
  --html-report-title="Web Traffic Report - $(date +%Y-%m-%d)"

ls -lh /var/www/reports/report.html

The HTML file is completely self-contained and can be opened directly in a browser or transferred to another machine for review. To generate a report covering the last 7 days of logs:

cat /var/log/nginx/access.log* | 
  goaccess - 
  --log-format=COMBINED 
  --output=/var/www/reports/weekly.html 
  --html-report-title="7-Day Traffic Report"

Step 5: Set Up the Real-Time HTML Dashboard

GoAccess can keep an HTML report continuously updated via a WebSocket connection, allowing you to watch traffic metrics update in real time in a browser. Start GoAccess with the --real-time-html flag:

goaccess /var/log/nginx/access.log 
  --log-format=COMBINED 
  --output=/var/www/reports/realtime.html 
  --real-time-html 
  --ws-url=ws://YOUR_SERVER_IP:7890 
  --port=7890 
  --daemonize 
  --pid-file=/var/run/goaccess.pid

Open the firewall for the WebSocket port:

firewall-cmd --permanent --add-port=7890/tcp
firewall-cmd --reload

The HTML file at /var/www/reports/realtime.html will now receive live updates in the browser as long as the GoAccess process is running. To stop the GoAccess daemon:

kill $(cat /var/run/goaccess.pid)

Step 6: Configure Nginx to Serve the Report

Add an Nginx location block to serve the reports directory. Restrict access to trusted IP addresses to protect the report from public viewing:

cat > /etc/nginx/conf.d/goaccess-report.conf << 'EOF'
server {
    listen 8080;
    server_name _;

    root /var/www/reports;
    index report.html;

    location / {
        allow 192.168.1.0/24;
        allow 127.0.0.1;
        deny all;
        autoindex on;
    }

    # Proxy WebSocket connections for real-time dashboard
    location /ws {
        proxy_pass http://127.0.0.1:7890;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }
}
EOF

nginx -t
systemctl reload nginx

Set correct ownership so Nginx can read the reports:

chown -R nginx:nginx /var/www/reports
chmod 755 /var/www/reports

Step 7: Automate Report Generation with Cron

Schedule hourly report regeneration so the static HTML report stays reasonably current without requiring the real-time WebSocket process:

cat > /etc/cron.d/goaccess-report << 'EOF'
# Generate GoAccess HTML report every hour
0 * * * * nginx /usr/bin/goaccess /var/log/nginx/access.log 
  --log-format=COMBINED 
  --output=/var/www/reports/report.html 
  --html-report-title="Hourly Traffic Report" 
  --no-progress 2>>/var/log/goaccess.log

# Generate a daily combined report at midnight
0 0 * * * nginx /bin/cat /var/log/nginx/access.log* | 
  /usr/bin/goaccess - 
  --log-format=COMBINED 
  --output=/var/www/reports/daily-$(date +%Y-%m-%d).html 
  --html-report-title="Daily Traffic Report" 
  --no-progress 2>>/var/log/goaccess.log

# Clean up daily reports older than 30 days
0 2 * * * root /usr/bin/find /var/www/reports -name 'daily-*.html' -mtime +30 -delete
EOF

Verify the cron jobs are installed:

cat /etc/cron.d/goaccess-report

Step 8: Useful GoAccess Options

Several additional flags are worth knowing for production use:

# Ignore specific bots and crawlers
goaccess /var/log/nginx/access.log 
  --log-format=COMBINED 
  --output=/var/www/reports/report.html 
  --ignore-crawlers 
  --unknowns-as-crawlers

# Filter to only show 404 errors
goaccess /var/log/nginx/access.log 
  --log-format=COMBINED 
  --output=/var/www/reports/404s.html 
  --http-method=GET

# Use a config file to avoid repeating flags
cat > /etc/goaccess/goaccess.conf << 'EOF'
log-format COMBINED
output /var/www/reports/report.html
html-report-title "Production Traffic Report"
ignore-crawlers true
EOF

goaccess /var/log/nginx/access.log --config-file=/etc/goaccess/goaccess.conf

GoAccess gives RHEL 7 administrators a fast, dependency-free window into Nginx traffic patterns without requiring Elasticsearch, Kibana, or any cloud service. The interactive terminal mode makes it invaluable during incident response — you can identify the source of a spike, the most-requested broken URLs, or the top consumer of bandwidth in seconds. The HTML report feature provides a shareable artifact for management reviews, while the real-time dashboard satisfies the need for continuous visibility. Combined with cron scheduling and Nginx serving, you have a complete lightweight log analytics pipeline running entirely on the server itself.