解析HttpLog格式的正则表达式模式

8

我在寻找一个可以匹配HttpLogFormat中字符串的正则表达式。这个日志是由haproxy生成的。以下是此格式中的示例字符串。

Feb 6 12:14:14 localhost haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} {} "GET /index.html HTTP/1.1"

可在HttpLogFormat获取格式说明。感谢任何帮助。

我正在尝试获取包含在该行中的各个信息。以下是字段:

  1. 进程名称 '[' 进程ID ']:'
  2. 客户端IP ':' 客户端端口
  3. '[' 接受日期 ']'
  4. 前端名称
  5. 后端名称 '/' 服务器名称
  6. Tq '/' Tw '/' Tc '/' Tr '/' Tt*
  7. 状态码
  8. 读取字节数
  9. 捕获的请求cookie
  10. 捕获的响应cookie
  11. 终止状态
  12. actconn '/' feconn '/' beconn '/' srv_conn '/' retries
  13. srv_queue '/' backend_queue
  14. '{' 捕获的请求头* '}'
  15. '{' 捕获的响应头* '}'
  16. '"' http请求 '"'

1
你试图从这一行中解析出什么?匹配它是一回事,从中获取特定信息又是另一回事。 - eldarerathis
但是你想从这行代码中得到什么? - Keng
1
这真的取决于你想匹配什么。所有信息还是只有部分信息? - jordanbtucker
抱歉各位..我花了一些时间才添加了那16行代码。HAproxy以这种格式生成日志。我只想高效地解析数据。在问题中发布的HttpLogFormat链接上有详细的格式说明。 - Thimmayya
5个回答

5

正则表达式:

^(\w+ \d+ \S+) (\S+) (\S+)\[(\d+)\]: (\S+):(\d+) \[(\S+)\] (\S+) (\S+)/(\S+) (\S+) (\S+) (\S+) *(\S+) (\S+) (\S+) (\S+) (\S+) \{([^}]*)\} \{([^}]*)\} "(\S+) ([^"]+) (\S+)" *$

结果:

Group 1:    Feb 6 12:14:14
Group 2:    localhost
Group 3:    haproxy
Group 4:    14389
Group 5:    10.0.1.2
Group 6:    33317
Group 7:    06/Feb/2009:12:14:14.655
Group 8:    http-in
Group 9:    static
Group 10:   srv1
Group 11:   10/0/30/69/109
Group 12:   200
Group 13:   2750
Group 14:   -
Group 15:   -
Group 16:   ----
Group 17:   1/1/1/1/0
Group 18:   0/0
Group 19:   1wt.eu
Group 20:   
Group 21:   GET
Group 22:   /index.html
Group 23:   HTTP/1.1

我使用RegexBuddy来编写复杂的正则表达式。


谢谢,这很有效。只需要进行一些微调来处理一些自定义情况。 - Thimmayya

2

使用需谨慎

假设所有字段都返回某些内容,除了您用星号标记的字段(星号是什么意思?)。还有明显的失败情况,例如任何类型的嵌套括号,但如果记录器打印出合理的消息,那么我想你应该没问题......

当然,即使是我个人也不想维护这个,但这就是它。如果可以的话,您可能需要考虑编写一个常规的解析器。

编辑:将其标记为CW,因为它更像是一种“我想知道这将变成什么”的答案。供快速参考,这是我最终在rubular中构建的内容:

^[^[]+\s+(\w+)\[(\d+)\]:([^:]+):(\d+)\s+\[([^\]]+)\]\s+[^\s]+\s+(\w+)\/(\w+)\s+(\d+)\/(\d+)\/(\d+)\/(\d+)\/(\d*)\s+(\d+)\s+(\d+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s(\d+)\/(\d+)\/(\d+)\/(\d+)\/(\d+)\s+(\d+)\/(\d+)\s+\{([^}]*)\}\s\{([^}]*)\}\s+\"([^"]+)\"$

我的第一种编程语言是Perl,即使我愿意承认,我也感到害怕。


只是因为你发出了那个讨厌的东西,我就给你点赞!我会试一试并更新进展的。 - Thimmayya
感谢您提供的解决方案。它在大多数情况下都可以正常工作。Mike上面提供的解决方案更好,正则表达式更简单、更灵活。我使用了rubular来调整正则表达式,这是一个不错的工具。 - Thimmayya

1

看起来这个字符串匹配非常复杂。我建议使用像Expresso这样的工具。从要匹配的字符串开始,然后用正则表达式符号逐步替换字符串的部分。

要抓取单独的部分,可以使用分组括号。

另一个选择是为每个要抓取的部分创建一个正则表达式。


1

你为什么要精确匹配这行?如果你正在寻找其中的特定字段,最好指定并提取它们。如果你想在haproxy日志上运行统计信息,你应该看看源代码中“contrib”目录中的“halog”工具。使用版本1.4.9的工具,它甚至知道如何按响应时间对URL进行排序。

但无论你想用这些行做什么,正则表达式可能总是最慢和最复杂的解决方案。


0

你还有什么其他建议? - Thimmayya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接