Detailed Apache logging turns vague 4xx and 5xx responses, TLS handshake failures, reverse-proxy timeouts, and rewrite loops into request-level evidence. Raising the log detail lets you see what Apache decided, which module made the decision, and which client request triggered it.

Apache splits diagnostics between the error log and one or more access logs. The LogLevel directive controls how much goes into the error log and supports module-scoped overrides such as ssl:info or rewrite:trace3, while LogFormat and CustomLog control which request fields are written to access logs and where those records are stored.

Verbose logging should be treated as a temporary troubleshooting mode on busy systems because it increases disk writes and can capture sensitive data in URLs, headers, or cookies. The commands below assume a Debian or Ubuntu layout under /etc/apache2/ with the apache2 systemd unit; RHEL-family systems typically use /etc/httpd/ and the httpd service name instead.

Steps to configure verbose Apache logging:

  1. List the configuration files that the running Apache instance loads.
    $ 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/default-ssl.conf

    Some hosts also print the AH00558 server-name warning before the include list. That warning does not prevent the command from showing the active configuration tree.

  2. Find the active LogLevel directive in the main server config.
    $ sudo grep --recursive --line-number --extended-regexp '^[[:space:]]*LogLevel' /etc/apache2/
    /etc/apache2/apache2.conf:143:LogLevel warn
  3. Find the current LogFormat and CustomLog definitions before adding a verbose variant.
    $ sudo grep --recursive --line-number --extended-regexp '^[[:space:]]*(LogFormat|CustomLog)[[:space:]]' /etc/apache2/
    /etc/apache2/apache2.conf:212:LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
    /etc/apache2/apache2.conf:213:LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
    ##### snipped #####
    /etc/apache2/sites-available/000-default.conf:21:    CustomLog ${APACHE_LOG_DIR}/access.log combined
  4. List the loaded modules before choosing module-specific log levels.
    $ sudo apache2ctl -M | grep -E 'rewrite|ssl|logio'
     logio_module (static)
     rewrite_module (shared)
     ssl_module (shared)

    Only add module:level tokens for modules that are actually loaded. If the module you want to trace is missing, enable it first.

  5. Open the main Apache configuration file.
    $ sudoedit /etc/apache2/apache2.conf
  6. Set a conservative default LogLevel and raise detail only for the module you are troubleshooting.
    LogLevel warn ssl:info rewrite:trace3

    warn keeps routine noise low, info restores lower-priority messages such as core:info for missing-file diagnostics, and trace1 through trace8 are the most verbose per-module levels.

    trace levels can generate large volumes of output on busy servers and should be left enabled only for the shortest possible troubleshooting window.

  7. Add a dedicated verbose access-log format in /etc/apache2/apache2.conf.
    LogFormat "%v:%p %a %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\" \"%{Host}i\"" verbose_timing

    This format adds the canonical vhost and port (%v:%p), the client IP (%a), response bytes (%b), request time in microseconds (%D), and selected request headers without replacing your existing standard format.

    Verbose formats can expose internal hostnames, query strings, or sensitive headers if you add too many fields, so avoid logging secrets such as authentication tokens or session cookies.

  8. Add a second CustomLog line inside the affected VirtualHost so the default access log stays in place.
    <VirtualHost *:80>
        ServerName logs.example.net
    
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        CustomLog ${APACHE_LOG_DIR}/access_verbose.log verbose_timing
    </VirtualHost>

    Writing to a separate access_verbose.log file keeps the normal access log stable for parsers and dashboards while you collect the extra detail.

  9. Validate the updated Apache configuration before reloading the service.
    $ sudo apache2ctl configtest
    Syntax OK

    Some hosts print the AH00558 server-name warning before Syntax OK. Fixing that warning is optional for logging changes.

  10. Reload the running Apache service to apply the new logging settings.
    $ sudo systemctl reload apache2

    Use sudo systemctl reload httpd on most RHEL-family systems.

  11. Follow the error log in a second terminal.
    $ sudo timeout 1 tail --follow=name --lines=20 /var/log/apache2/error.log
    [Thu Apr 09 04:19:08.752189 2026] [ssl:info] [pid 3462:tid 281473257799712] AH01883: Init: Initialized OpenSSL library
    [Thu Apr 09 04:19:08.752436 2026] [ssl:info] [pid 3462:tid 281473257799712] AH01887: Init: Initializing (virtual) servers for SSL
    [Thu Apr 09 04:19:08.752448 2026] [ssl:info] [pid 3462:tid 281473257799712] AH01914: Configuring server logs.example.net:443 for SSL protocol
    ##### snipped #####

    The exact messages depend on the module you raised. For missing-file 404 diagnostics in Apache 2.4, a temporary LogLevel warn core:info is often enough.

  12. Send a request through the vhost that should appear in the verbose access log.
    $ curl --head --header "Host: logs.example.net" http://127.0.0.1/
    HTTP/1.1 200 OK
    Date: Thu, 09 Apr 2026 04:19:10 GMT
    Server: Apache/2.4.58 (Ubuntu)
    Last-Modified: Thu, 09 Apr 2026 04:19:05 GMT
    ETag: "29af-64eff5129f6b0"
    Accept-Ranges: bytes
    Content-Length: 10671
    Vary: Accept-Encoding

    If 127.0.0.1 does not hit the same virtual host locally, use the site hostname directly or add a Host header that matches the vhost you changed.

  13. Confirm that the verbose access log is collecting the extra fields you added.
    $ sudo tail --lines=1 /var/log/apache2/access_verbose.log
    logs.example.net:80 127.0.0.1 - - [09/Apr/2026:04:19:10 +0000] "HEAD / HTTP/1.1" 200 - 1133 "-" "curl/8.5.0" "logs.example.net"

    The leading logs.example.net:80 field comes from %v:%p, the dash after 200 comes from %b because a HEAD request sends no response body, and 1133 is the request time from %D in microseconds.

  14. Restore the normal logging level after you capture the evidence you need.
    LogLevel warn

    Remove the temporary CustomLog ${APACHE_LOG_DIR}/access_verbose.log verbose_timing line as well if you only needed the extra log during a debugging session.