在nginx访问日志bash脚本中包含User-Agent信息

时间:2013-07-27 19:28:03

标签: bash logging nginx awk

我有一个工作的bash脚本告诉我nginx访问日志,将原始日志格式化为彩色信息。

不幸的是,我不太确定如何处理我已经创建的内容,并添加显示请求的User-Agent。我希望能够一目了然地看一下User-Agent的用途。是Googlebot吗?是Windows上的Firefox 22吗?

这是我的bash脚本:

#!/bin/bash

LOG_DEFAULT_PATH="/var/log/nginx/access.log"
LOG_PATH="$1"

if [ "$LOG_PATH" = "" ] && test -f "$LOG_DEFAULT_PATH"; then

  echo -e "\033[35mAuto-detected Log File: \033[32m$LOG_DEFAULT_PATH\033[0m"
  LOG_PATH="$LOG_DEFAULT_PATH"

fi

if [ "$LOG_PATH" = "" ]; then

  echo -e "\033[32mUsage: $0 /path/to/nginx/access_log\033[0m"

else

  (tail -n 500 -F $LOG_PATH | awk '{printf "%s%s %s %s%s%s %s %s %s%s%s %s%s\n", "\033[40;1;35m", $5, $6, "\033[0;32m", $1, "\033[37m", $10, substr($7, 2), "\033[31m", $8, "\033[36m", $2, "\033[0m"}')

fi

脚本的主体位于以tail命令开头的行中。我正在使用awk将请求的不同部分打印到终端中,并为每个部分着色。在这里,我假设还将显示用户代理信息。

这是日志格式:

  log_format  vhost_combined  '$http_host $remote_addr - $remote_user [$time_local]  '
                              '"$request" $status $body_bytes_sent "$http_referer" '
                              '"$http_user_agent"';

当然,对于更好的脚本编写的任何建议也将非常感谢!

2 个答案:

答案 0 :(得分:0)

正如我在评论中所说,注意字段内的空白区域,因为awk使用空格作为默认分隔符,您可能无法获得所需的正确字段。您可以使用-F选项更改默认分隔符,也可以使用awk中的正则表达式来执行此操作。 awk中正则表达式的一个例子:

awk '{if(match($0,/GET ([^ ]*)/,a)){print a[1];}}' access_log

你可以推荐的正则表达式如下:

^(\d+\.\d+\.\d+\.\d+) ([^ ]+) ([^ ]+) \[([^\]]*)\] \"([A-Z]+) ([^\"]+)\" (\d+) (\d+) \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" ([\d\.]+)( (\d+) (\d+))?

结果: enter image description here

如果无法清楚地看到图片,请右键单击它并在另一个标签中重新打开以查看原始尺寸。

答案 1 :(得分:0)

前段时间我解决了自己的问题,但忘了在这里更新。

以下是我提出的脚本:

#!/bin/sh

LOG_DEFAULT_PATH="/var/log/nginx/access.log"
LOG_PATH="$1"

if [ "$LOG_PATH" = "" ] && [ -f "$LOG_DEFAULT_PATH" ]; then

  echo -e "\033[35mAuto-detected Log File: \033[32m$LOG_DEFAULT_PATH\033[0m"
  LOG_PATH="$LOG_DEFAULT_PATH"

fi

if [ "$LOG_PATH" = "" ]; then

  echo -e "\033[32mUsage: $0 /path/to/nginx/access_log\033[0m"

else

  sudo tail -n 500 ./nginx-access.log | perl -n -e'/^(\S+) (\S+) (\S+) (\S+) \[([^:]+):(\d+:\d+:\d+) ([^\]]+)\] \"(\S+) (.*?) (\S+)\" (\S+) (\S+) "([^"]*)" "([^"]*)"$/ && print "\033[40;1;35m[$5 $6]\033[0;32m $1 \033[37m$11 $8 \033[31m$9 \033[36m$2 \033[30;1m$14\033[0m\n"'

fi

基本上,scsript的主要部分或主体是底部的perl命令。它使用正则表达式分离出日志格式,然后使用print显示一些变量。

用户代理最后以粗体灰色文本显示,使用正则表达式中的$14

如果需要,可以给予进一步解释。