使用 perl 解析日志

使用 perl 解析日志

我希望使用我设计的 perl 命令来解析日志。到目前为止,我想要完成的就是提取特定的时间戳格式并检索主机。日志看起来像这样

2016-05-07T09:07:04.933343+00:00 heroku[router]: status=301 bytes=680 service=2698ms connect=1ms dyno=web.2 fwd="10.29.10.29" at=info host="jamaican.com" request_id=32fc8d88-99f8-4cc2-89f9-284d059eebf8 method=GET path="/blog"

我的命令可以解析我想要的日期格式,但我似乎无法弄清楚如何在输出中添加主机。任何建议都会很棒!

cat test.log  |
perl -lne 'print $1 if  /^([0-9]+[-]+[0-9]+[0-9]+[-]+[0-9]+[0-9]+[T]+[0-9]+[0-9]+[:]+[0-9]+[0-9]+[:]+[0-9]+[0-9])/'

答案1

尝试这个:

perl -nle'($time, $host) = /^(\S+)\s(?:\S+\s+){8}\S+="(\S+?)"/; print "$time $host"'

输出:

2016-05-07T09:07:04.933343+00:00 jamaican.com
  • \S表示非空间
  • \s是空间
  • (?:)是未捕获的逻辑分组
  • {8}是跳过的“单词”
  • \S+="(\S+?)"意思是:跳过直到并捕获两个引号=之间的内容"
  • ($time, $host) = /.../将两个捕获的组分配给$time$host

答案2

您需要使用第二个捕获组捕获主机名。

例如使用您的示例输入:

$ cat test.log 
2016-05-07T09:07:04.933343+00:00 heroku[router]: status=301 bytes=680 service=2698ms connect=1ms dyno=web.2 fwd="10.29.10.29" at=info host="jamaican.com" request_id=32fc8d88-99f8-4cc2-89f9-284d059eebf8 method=GET path="/blog"

这个 perl 单行代码提取时间戳和主机名字段。我也对正则表达式进行了一些改进,用于\d数字,每个数字都有一个匹配计数。

$ perl -lne 'print "$1 $2" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}) ([^ ]+) /)' test.log
2016-05-07T09:07:04.933343+00:00 heroku[router]:

另一种选择:

$ perl -lne 'print "$1 $2 $3" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}) ([^[]+)\[([^]]+)\]/)' test.log
2016-05-07T09:07:04.933343+00:00 heroku router

我假设您想要本地计算机的主机名(我什至没有注意到host="jamaican.com"日志条目的部分)。这可能不是您想要的,因此如果您想要 后面双引号内的主机名host=,那么:

$ perl -lne 'print "$1 $2" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}).*host="([^"]+)"/)' test.log
2016-05-07T09:07:04.933343+00:00 jamaican.com 

或者(更简单):

$ perl -lne 'print "$1 $2" if (m/(^\S+).*host="([^"]+)"/)' test.log
2016-05-07T09:07:04.933343+00:00 jamaican.com

或者提取时间戳,使用 解析它Date::Parse并使用 重新格式化它Date::Format

$ perl -MDate::Parse -MDate::Format -lne \
  'if (m/(^\S+).*host="([^"]+)"/) {
     print join(" ", time2str("%Y-%m-%d %R %z",str2time($1)), $2)
   }' test.log
2016-05-07 19:07 +1000 jamaican.com

注意:时间戳已转换为本地时区(对我来说,即 +1000 或澳大利亚东部标准时间)。 time2str()默认情况下使用本地时区,但您可以给它第三个参数 ( time2str(TEMPLATE, TIME [, ZONE])) 以使其输出任何其他区域的时间。

$ perl -MDate::Parse -MDate::Format -lne   'if (m/(^\S+).*host="([^"]+)"/) {
     print join(" ", time2str("%Y-%m-%d %R %z",str2time($1),"+0"), $2)
   }' test.log
2016-05-07 09:07 +0000 jamaican.com

相关内容