Configuring the Apache Error and Access Logs

Published on

6 min read

Configuring Apache Logging

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’ll 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 information about the server and application issues.

This article describes how to configure and read the Apache access and error logs.

Configuring the Access Log

Apache webserver 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 visitors’ location, the page they visit, how much time they spend on the page, 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 combined
CustomLog 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 to be written to the log file, you would use the following:

SetEnvIf Request_URI \.css$ css-file
CustomLog logs/access.log custom env=!css-file

To 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 combined

Configuring 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 name location of the error log. It takes the following form:

ErrorLog log_file

If 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 per virtual host basis.

Then 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>
     DocumentRoot /var/www/
     LogLevel warn
     ErrorLog /var/www/
     CustomLog /var/www/ combined

Whenever you modify the configuration file, you have to restart the Apache service for the changes to take effect.

Location of the Log Files

By default on Debian-based distributions such as Ubuntu , access and error logs are located in the /var/log/apache2 directory. On CentOS the log files are placed in /var/log/httpd directory.

Reading 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’ combine log format: - - [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 - - 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 - 396 - The size of 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 access.log 


Log files provide you with useful information about server issues and how visitors interact with your website.

Apache has a very configurable logging system that allows you to customize the access and error logs according to your needs.

If you have any questions or feedback, feel free to leave a comment.