Configuring the Apache Error and Access Logs

Apache is an open-source and cross-platform HTTP server. It has a lot of powerful features that can be extended by a wide variety of modules. When managing Apache web servers, one of the most frequent tasks you will perform is checking the log files.
Knowing how to configure and read the logs is very useful when troubleshooting server or application issues as they provide detailed debugging information.
Apache writes records of its events in two types of logs: access logs and error logs. Access logs include information about client requests, and error logs include information about server and application issues.
This article describes how to configure and read the Apache access and error logs.
Configuring the Access Log
Apache web server generates a new event in the access log for all processed requests. Each event record contains a timestamp and includes various information about the client and the requested resource. Access logs show the visitor IP address, the requested resource, the response status, and much more.
The CustomLog
directive defines the location of the log file and the format of the logged messages.
The most basic syntax of the CustomLog directive is as follows:
CustomLog log_file format [condition];The log_file can be either relative to the ServerRoot or a full path to the log file. The log messages can also be piped to another program using the pipe symbol |.
The second argument, format specifies the format of the log messages. It can be either an explicit format definition or a nickname defined by the LogFormat directive.
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog logs/access.log combinedCustomLog logs/access.log "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\""To avoid repeating the same code multiple times, prefer defining the LogFormat directive and using it as a nickname in the CustomLog directive.
For a complete list of all format strings and modifiers, check the “mod_log_config” module documentation.
The third argument [condition] is optional and allows you to write log messages only when a specific condition is met. Usually, this is done using environment variables. The condition can be negated with the ! symbol.
For example, if you want to exclude requests to CSS files from being written to the log file, you would use the following:
SetEnvIf Request_URI \.css$ css-file
CustomLog logs/access.log custom env=!css-fileTo change the logging format, you can either define a new LogFormat directive or override the default format. Typically it is better to define a new format.
While the access log provides very useful information it takes disk space and may affect the server performance. If your server is low on resources and you have a busy website, you might want to disable the access log.
To do that, simply comment out or remove the CustomLog directive from the main server configuration and virtual server sections.
If you want to turn off the access log only for one virtual host, set the first argument of the CustomLog directive to /dev/null:
CustomLog /dev/null combinedConfiguring the Error Log
Apache writes messages about the application and general server errors in the error log file. If you are experiencing errors in your web application, the error log is the first place to start for troubleshooting issues.
The ErrorLog directive defines the location of the error log. It takes the following form:
ErrorLog log_fileIf the path to the log_file is not absolute, then it is set as relative to the ServerRoot. The error messages can also be piped to another program using the pipe symbol |.
The LogLevel parameter sets the level of logging. Below are levels listed by their severity (from low to high):
trace1-trace8- Trace messages.debug- Debugging messages.info- Informational messages.notice- Notices.warn- Warnings.error- Errors while processing a request.crit- Critical issues. Requires a prompt action.alert- Alerts. Action must be taken immediately.emerg- Emergency situation. The system is in an unusable state.
Each log level includes the higher levels. For example, if you set the log level to warn, Apache also writes the error, crit, alert, and emerg messages.
When the LogLevel parameter is not specified, it defaults to warn. It is recommended to set the level to at least crit.
The ErrorLogFormat directive specifies the format of the error log. On most Linux distributions, the Apache server is using the default format, which is sufficient for most cases.
Virtual Hosts and Global Logging
The logging behavior and the location of the files can be set either globally or on a per-virtual-host basis.
When the CustomLog or ErrorLog directives are set in the main server context, the server writes all log messages to the same access and error log files. Otherwise, if the directives are placed inside a <VirtualHost> block, only the log messages for that virtual host are written to the specified file.
The log directive set in the <VirtualHost> block overrides the one set in the server context.
Virtual hosts without CustomLog or ErrorLog directives will have their log messages written to the global server logs.
For better readability, it is recommended to set separate access and error log files for each virtual host. Here is an example:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin webmaster@example.com
DocumentRoot /var/www/example.com/public
LogLevel warn
ErrorLog /var/www/example.com/logs/error.log
CustomLog /var/www/example.com/logs/access.log combined
</VirtualHost>Whenever you modify the configuration file, you have to restart the Apache service for the changes to take effect.
Location of the Log Files
The default log file location depends on the Linux distribution:
| Distribution | Access log | Error log |
|---|---|---|
| Ubuntu, Debian | /var/log/apache2/access.log | /var/log/apache2/error.log |
| AlmaLinux, Rocky Linux, Fedora | /var/log/httpd/access_log | /var/log/httpd/error_log |
| Apache compiled from source | /usr/local/apache2/logs/access_log | /usr/local/apache2/logs/error_log |
On systemd-based systems, you can also read Apache log output with journalctl. On Ubuntu and Debian, the service is usually named apache2:
journalctl -u apache2 --no-pagerOn AlmaLinux, Rocky Linux, Fedora, and other RHEL-based systems, the service is usually named httpd:
journalctl -u httpd --no-pagerUse -f to follow the output in real time:
journalctl -u apache2 -fReading and Understanding the Apache Log Files
The log files can be opened and parsed using standard commands like cat
, less
, grep
, cut
, awk
, and so on.
Here is an example record from the access log file that uses the Debian combined log format:
192.168.33.1 - - [08/Jan/2020:21:39:03 +0000] "GET / HTTP/1.1" 200 6169 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"Let’s break down what each field of the record means:
%h-192.168.33.1- The Hostname or the IP address of the client making the request.%l--- Remote logname. When the user name is not set, this field shows-.%u--- If the request is authenticated, the remote user name is shown.%t-[08/Jan/2020:21:39:03 +0000]- Local server time.\"%r\"-"GET / HTTP/1.1"- First line of request. The request type, path, and protocol.%>s-200- The final server response code. If the>symbol is not used and the request has been internally redirected, it will show the status of the original request.%O-6169- The size of the server response in bytes.\"%{Referer}i\"-"-"- The URL of the referral.\"%{User-Agent}i\"-Mozilla/5.0 ...- The user agent of the client (web browser).
Use the tail
command to watch the log file in real time:
tail -f /var/log/apache2/access.logTo filter the access log by HTTP status code, use grep
:
grep " 404 " /var/log/apache2/access.logTo filter by a specific client IP address:
grep "192.168.1.1" /var/log/apache2/access.logReading the Error Log
Here is an example record from the error log:
[Thu Jan 09 10:42:15.123456 2020] [authz_core:error] [pid 1234] [client 192.168.33.1:44832] AH01630: client denied by server configuration: /var/www/html/privateHere is what each field means:
[Thu Jan 09 10:42:15.123456 2020]- Timestamp of the event.[authz_core:error]- The Apache module that generated the message and the log level.[pid 1234]- The process ID of the Apache worker.[client 192.168.33.1:44832]- The IP address and port of the client.AH01630: client denied by server configuration: ...- The error message and affected path.
To watch the error log in real time:
tail -f /var/log/apache2/error.logLog Rotation
Apache log files grow continuously. On most Linux distributions, logrotate handles log rotation automatically. The default Apache logrotate configuration rotates logs weekly and keeps four weeks of history. You can find it at /etc/logrotate.d/apache2 on Debian-based systems or /etc/logrotate.d/httpd on RHEL-based systems.
Quick Reference
| Task | Command or directive |
|---|---|
| View access log | tail -f /var/log/apache2/access.log |
| View error log | tail -f /var/log/apache2/error.log |
| View logs via journalctl | journalctl -u apache2 -f or journalctl -u httpd -f |
| Filter by status code | grep " 404 " access.log |
| Filter by IP address | grep "1.2.3.4" access.log |
| Set access log location | CustomLog /path/to/access.log combined |
| Set error log location | ErrorLog /path/to/error.log |
| Set log level | LogLevel warn |
| Disable access log | CustomLog /dev/null combined |
FAQ
Where are Apache log files located?
On Ubuntu and Debian, logs are in /var/log/apache2/. On AlmaLinux, Rocky Linux, and Fedora, they are in /var/log/httpd/. The exact path can be overridden with the CustomLog and ErrorLog directives in the Apache configuration.
How do I view the Apache error log?
Run tail -f /var/log/apache2/error.log (Ubuntu/Debian) or tail -f /var/log/httpd/error_log (RHEL-based). On systemd systems, use journalctl -u apache2 -f or journalctl -u httpd -f, depending on the distro.
How do I search the Apache access log for a specific IP or status code?
Use grep: grep "1.2.3.4" access.log for an IP, or grep " 404 " access.log for all 404 responses.
How do I disable the Apache access log?
Set CustomLog /dev/null combined in the relevant server or virtual host configuration block, then reload Apache.
Conclusion
Log files provide useful information about server issues and how visitors interact with your website. Apache has a flexible logging system that lets you customize formats, split logs per virtual host, and filter output, making it straightforward to diagnose problems and monitor traffic.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page