# monitor.parse-access-log Parses one line of a web server access log in the NCSA Common Log Format or the Combined Log Format, the defaults of Apache httpd and nginx (nginx's `combined` is the same layout): ``` Common %h %l %u %t "%r" %>s %b Combined %h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i" 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)" ``` Feed it `monitor.status-code-summary` for error rates, or `monitor.rollup` for requests per minute. ## Decisions - **Junk is null, not an error.** Real logs hold truncated lines, lines from another format and binary noise; a log reader should skip them and count them, not stop. So anything not in either format returns null: a bad month, 30 February, a status outside 100 to 599, stray text after the byte count. - **"-" is null** in every field that uses it (ident, user, bytes, referer, user agent). Apache's `%b` writes "-" rather than 0 when no body was sent (a 304, say): treat a null `bytes` as 0 if you are summing. - **The request line.** `"-"` (the client sent nothing before timing out) and anything that is not `METHOD path HTTP/x` (a TLS handshake sent to a plain HTTP port logs as `"\x16\x03\x01..."`) keep the line, with method, path and protocol null: the status (typically 400 or 408) is still worth counting. `METHOD path` with no protocol is an HTTP/0.9 request: protocol null. - **Escapes are kept as logged.** Apache writes `"` as `\"`, `\` as `\\` and non-printable bytes as `\xhh` inside quoted fields. The parser honours `\"` when finding the end of a field but returns the text as it appears in the log, so no information is lost and nothing is decoded twice. - **Extra fields after the user agent are ignored**, since many sites append response time or a request id to Combined. After a Common line's byte count nothing may follow except the two quoted Combined fields. - **Time** `[10/Oct/2000:13:55:36 -0700]` is checked field by field (English month abbreviations, real calendar dates, leap years, a numeric offset) and converted with `time.iso-to-unix`, so `at` is exact Unix seconds (UTC). A leap second (`:60`) is not a Unix time and makes the line null. - A trailing `\n` or `\r\n` is stripped, so lines straight from a file work. ## Sources - Apache HTTP Server 2.4, mod_log_config: "Common Log Format" and "Combined Log Format", the `%b` "-" for no bytes, the `%t` format and the escaping of `%r`, `%i` and `%u`, https://httpd.apache.org/docs/2.4/mod/mod_log_config.html - Apache HTTP Server 2.4, Log Files (the example lines and field-by-field explanation), https://httpd.apache.org/docs/2.4/logs.html#accesslog