跳转到主要内容
模块 8 · 第 2 课(共 4)课程中的30/32~12 min
模块课程(2/4)

Apache 日志解析器

Apache 日志(组合格式)具有精确的结构:

Code
127.0.0.1 - - [10/Oct/2024:13:55:36 +0000] "GET /index.html HTTP/1.1" 200 1234

具有命名组的模式一次性提取每个字段:

Code
^(?<ip>\d+\.\d+\.\d+\.\d+)\s+\S+\s+\S+\s+\[[^\]]+\]\s+"(?<metodo>\w+)\s+(?<path>\S+)\s+\S+"\s+(?<status>\d+)\s+(?<size>\d+)

它看起来很可怕,但它是简单模式的串联:

  • (?<ip>\d+\.\d+\.\d+\.\d+) -- 源 IPv4。
  • \s+\S+\s+\S+ -- 用户 ID(通常为 -)。
  • \[[^\]]+\] -- 方括号中的日期。
  • "(?<metodo>\w+)\s+(?<path>\S+)\s+\S+" -- 引号中的请求,带有 HTTP 方法、路径和版本。
  • (?<status>\d+)\s+(?<size>\d+) -- 发送的状态代码和字节。

总体策略

  1. 从实行开始并固定分隔符:空格、引号、括号。
  2. 在分隔符之间,标识令牌的类型(IP、单词、数字)。
  3. 仅包含您需要提取的命名组。

解析复杂日志

在日志解析中,字段通常以空格分隔,除非它们包含带引号的字符串或括号(例如用户代理)。使用排除字符类而不是通配符点可以防止错误地合并多个列。

尝试一下

锻炼#regex.m8.l2.e1
尝试:0加载中...

将每个日志行开头的 IPv4 提取为命名组“ip”。

正在加载编辑器...
显示提示

使用 ^ 和 m 标志锚定到行的开头,并将 IP 包装在 (?<ip>...) 中。

3 次尝试后可用的解决方案

复习练习

锻炼#regex.m8.l2.e2
尝试:0加载中...

提取引号之间请求的 HTTP 方法和路径,作为“metodo”和“path”组。

正在加载编辑器...
显示提示

使用 " 打开,然后 (?<metodo>\\w+)\\s+(?<path>\\S+)。

3 次尝试后可用的解决方案

额外的挑战

锻炼#regex.m8.l2.e3
尝试:0加载中...

Extract only the date and time part enclosed in brackets in logs, e.g. `10/Oct/2024:13:55:36 +0000`, as a named group `timestamp`.

正在加载编辑器...
显示提示

Use \[(?<timestamp>[^\]]+)\] to prevent the engine from matching past the closing bracket.

3 次尝试后可用的解决方案