More detailed Apache logging turns intermittent 5xx responses, TLS handshake failures, reverse-proxy timeouts, and rewrite loops into actionable evidence. Raising verbosity makes module decisions and connection state visible in the error log, and richer access logs help correlate slow requests with specific clients, headers, and URLs.
Apache writes two primary log streams: the error log and one or more access logs. Error logging is controlled by the LogLevel directive, which supports global settings plus module-specific overrides (for example ssl:info). Access logging is controlled by mod_log_config using LogFormat strings (field selection) paired with CustomLog directives (file destination and format nickname).
High verbosity increases disk writes and can grow log files quickly on busy servers, and verbose formats can capture sensitive data embedded in query strings or headers. Keep debug or trace levels temporary on production systems, prefer module-scoped verbosity, and confirm log rotation covers any new log files. Commands and paths below assume a Ubuntu or Debian layout using /etc/apache2/ and the apache2 systemd unit.
Steps to configure verbose Apache logging:
- Open a terminal with sudo privileges.
$ whoami root
- List configuration files loaded by Apache.
$ sudo apache2ctl -t -D DUMP_INCLUDES Included configuration files: (*) /etc/apache2/apache2.conf (146) /etc/apache2/mods-enabled/access_compat.load (146) /etc/apache2/mods-enabled/alias.load (146) /etc/apache2/mods-enabled/auth_basic.load ##### snipped ##### (225) /etc/apache2/sites-enabled/000-default.conf (225) /etc/apache2/sites-enabled/host.example.net.confRelated: Location for Apache configuration
RHEL-style systems commonly use /etc/httpd/ and the httpd service name.
- Find the active LogLevel directive.
$ sudo grep --recursive --line-number --extended-regexp '^[[:space:]]*LogLevel' /etc/apache2/ /etc/apache2/apache2.conf:143:LogLevel warn ssl:info rewrite:trace3
- Edit the file that sets LogLevel.
$ sudoedit /etc/apache2/apache2.conf
- Increase error-log verbosity by updating LogLevel.
LogLevel info
Common levels: emerg, alert, crit, error, warn, notice, info, debug. Module scoping uses module:level syntax, such as ssl:info or rewrite:trace3.
debug and trace levels can flood logs and increase disk I/O on busy servers.
- Add module-specific log levels for targeted troubleshooting.
LogLevel warn ssl:info rewrite:trace3
Use module tokens that match loaded modules. List loaded modules with
apache2ctl -M
.
- Enable any modules referenced in the LogLevel scope (for example mod_rewrite).
$ sudo a2enmod rewrite Enabling module rewrite. To activate the new configuration, you need to run: systemctl restart apache2
- Check the Apache configuration for syntax errors.
$ sudo apache2ctl configtest
- Reload Apache to apply the new logging settings.
$ sudo systemctl reload apache2
- Check the apache2 service state.
$ sudo systemctl status apache2 --no-pager -l ● apache2.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/apache2.service; enabled; preset: enabled) Active: active (running) since Sun 2026-01-11 05:32:41 +08; 20ms ago Docs: https://httpd.apache.org/docs/2.4/ Process: 10708 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS) Main PID: 10712 (apache2) Tasks: 55 (limit: 4546) Memory: 6.2M (peak: 6.6M) CPU: 18ms CGroup: /system.slice/apache2.service ├─10712 /usr/sbin/apache2 -k start ├─10714 /usr/sbin/apache2 -k start └─10715 /usr/sbin/apache2 -k start Jan 11 05:32:41 host systemd[1]: Starting apache2.service - The Apache HTTP Server... Jan 11 05:32:41 host apachectl[10711]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message Jan 11 05:32:41 host systemd[1]: Started apache2.service - The Apache HTTP Server. - Follow the error log for higher-detail messages.
$ sudo timeout 1 tail --follow=name --lines=50 /var/log/apache2/error.log [Sun Jan 11 05:32:41.200478 2026] [ssl:info] [pid 10711:tid 269336145113120] AH01883: Init: Initialized OpenSSL library [Sun Jan 11 05:32:41.201139 2026] [ssl:info] [pid 10711:tid 269336145113120] AH01887: Init: Initializing (virtual) servers for SSL [Sun Jan 11 05:32:41.201142 2026] [ssl:info] [pid 10711:tid 269336145113120] AH01914: Configuring server host.example.net:443 for SSL protocol [Sun Jan 11 05:32:41.202192 2026] [ssl:info] [pid 10711:tid 269336145113120] AH02568: Certificate and private key host.example.net:443:0 configured from /etc/apache2/ssl/apache.crt and /etc/apache2/ssl/apache.key ##### snipped #####
- Find existing LogFormat definitions.
$ sudo grep --line-number --extended-regexp '^[[:space:]]*LogFormat[[:space:]]' /etc/apache2/apache2.conf 212:LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined 213:LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined 214:LogFormat "%h %l %u %t \"%r\" %>s %O" common 215:LogFormat "%{Referer}i -> %U" referer 216:LogFormat "%{User-agent}i" agent 226:LogFormat "%v:%p %a %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\" \"%{Host}i\"" verbose_timing - Find active CustomLog directives.
$ sudo grep --recursive --line-number --extended-regexp '^[[:space:]]*CustomLog[[:space:]]' /etc/apache2/ /etc/apache2/sites-available/000-default.conf:21: CustomLog ${APACHE_LOG_DIR}/access.log combined /etc/apache2/sites-available/000-default.conf:29: CustomLog ${APACHE_LOG_DIR}/access_verbose.log verbose_timing /etc/apache2/sites-available/default-ssl.conf:13: CustomLog ${APACHE_LOG_DIR}/access.log combined /etc/apache2/conf-available/other-vhosts-access-log.conf:2:CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log vhost_combined - Define a verbose LogFormat nickname in /etc/apache2/apache2.conf.
LogFormat "%v:%p %a %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\" \"%{Host}i\"" verbose_timingNickname is the trailing token (for example combined, vhost_combined, verbose_timing).
Related: LogFormat string referenceStandard combined format:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedMinimalist format:
LogFormat "%h %l %u %t \"%r\" %>s %b" minimal
Verbose format with extra headers and timing:
LogFormat "%v:%p %a %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\" \"%{Host}i\" \"%{Accept}i\" \"%{Accept-Language}i\"" verbose_headersQuery string included explicitly:
LogFormat "%h %l %u %t \"%m %U%q %H\" %>s %b" query_included
Verbose formats can capture sensitive header values or tokens embedded in URLs. Avoid logging secrets (authentication headers, session identifiers, signed URLs).
- Add a dedicated CustomLog line that uses the new nickname.
CustomLog ${APACHE_LOG_DIR}/access_verbose.log verbose_timingKeep the existing CustomLog line for standard logging. Add the verbose line temporarily for troubleshooting.
Debian-family log rotation often matches /var/log/apache2/*.log, which covers access_verbose.log.
- Check the configuration for syntax errors after the log format change.
$ sudo apache2ctl configtest
- Reload Apache to apply the access log changes.
$ sudo systemctl reload apache2
- Generate a request that produces a fresh access-log entry.
$ curl --head http://127.0.0.1/ HTTP/1.1 200 OK Date: Sat, 10 Jan 2026 21:32:42 GMT Server: Apache/2.4.58 (Ubuntu) Last-Modified: Sat, 10 Jan 2026 21:15:28 GMT ETag: "29af-6480f24215cc8" Accept-Ranges: bytes Content-Length: 10671 Vary: Accept-Encoding Content-Type: text/html
- Confirm the verbose access log contains the expected fields.
$ sudo tail --lines=1 /var/log/apache2/access_verbose.log 127.0.1.1:80 127.0.0.1 - - [11/Jan/2026:05:32:42 +0800] "HEAD / HTTP/1.1" 200 - 134 "-" "curl/8.5.0" "127.0.0.1"
Reduce verbosity after troubleshooting by restoring the site default LogLevel and removing temporary verbose CustomLog lines.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
