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.