← Back to Apache Course | Chapter 6: Logging | Lesson 1 of 4

Access Log

The access log records every single request Apache handles -- who asked for what, when, and what response they got back. It's the first place to look when you want to know how a site is actually being used.

Where It Lives

On Ubuntu/Debian, the default access log is /var/log/apache2/access.log; on RHEL-family systems it's /var/log/httpd/access_log. Each VirtualHost can (and usually should) define its own with a CustomLog directive, so traffic for different sites doesn't all mix into one file.

The CustomLog Directive

CustomLog /var/log/apache2/example.com-access.log combined writes every request for that VirtualHost to the given file, formatted according to the named log format -- combined is Apache's standard, information-rich built-in format (covered fully in the Custom Log Formats lesson).

Reading a Log Line

A typical combined-format line looks like: 203.0.113.5 - - [10/Mar/2024:14:22:01 +0000] "GET /index.html HTTP/1.1" 200 5423 "https://example.com/" "Mozilla/5.0 ..." -- in order, that's the client IP, the request's timestamp, the request line itself, the HTTP status code, the response size in bytes, the referring page, and the browser's user agent string.

Common Uses

The access log is the raw material behind traffic analytics, debugging "is anyone actually hitting this URL" questions, spotting suspicious request patterns, and tools like fail2ban, which scan it for repeated failed attempts and temporarily block the offending IP at the firewall level.

Note: tail -f /var/log/apache2/access.log shows new requests as they arrive in real time -- handy for watching exactly what happens while you test something on the live site.

Example: Per-site access log in a VirtualHost

apacheconf
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example.com/public

    CustomLog /var/log/apache2/example.com-access.log combined
</VirtualHost>

# Example combined-format log line:
# 203.0.113.5 - - [10/Mar/2024:14:22:01 +0000] "GET /index.html HTTP/1.1" 200 5423 "https://example.com/" "Mozilla/5.0"
{# Flagged by hand after confirming a runner can't handle this example (a shell command / go.mod file stored as a TopicExample, a language feature the configured runner version doesn't support, or output that blows a runner's sandbox limit) -- see TopicExample.norun. Never render the run button for these, regardless of language, since it would just fail at execute_code (or worse, hang the Judge0 queue on a submission that can never finish cleanly). #}

⚠️ This example can't run in the browser editor. Try it in your own local environment instead.

{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Leaving every VirtualHost writing to the same shared access log, making it hard to tell which site a given request actually belongs to.
  2. Assuming the access log alone tells you about errors -- a request that failed inside the application can still show as 200 OK in the access log if Apache itself never saw a problem.
  3. Not rotating the access log (covered in the Log Rotation lesson), letting it grow indefinitely on a busy site until it fills the disk.
🔒

Chapter Quiz — Complete all 4 topics to unlock

0/4 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.