dea*_*mer 72 grep logging parsing awk apache-2.2
我可以使用日志分析器,但通常我需要解析最近的网络日志以查看当前发生的情况。
我有时会做一些事情,比如找出请求某个文件的前 10 个 ip
cat foo.log | grep request_to_file_foo | awk '{print $1}' | sort -n | uniq -c | sort -rn | head
Run Code Online (Sandbox Code Playgroud)
你的工具箱里有什么?
Mar*_*ark 60
您可以单独使用 awk 对 apache 日志文件执行任何操作。Apache 日志文件基本上以空格分隔,您可以假装引号不存在,并通过列号访问您感兴趣的任何信息。唯一的问题是如果您有组合日志格式并且对用户代理感兴趣,此时您必须使用引号 (") 作为分隔符并运行单独的 awk 命令。以下将向您显示每个请求按点击次数排序的索引页的用户:
awk -F'[ "]+' '$7 == "/" { ipcount[$1]++ }
END { for (i in ipcount) {
printf "%15s - %d\n", i, ipcount[i] } }' logfile.log
Run Code Online (Sandbox Code Playgroud)
$7 是请求的 URL。您可以在开始时添加任何您想要的条件。将 '$7 == "/" 替换为您想要的任何信息。
如果替换 (ipcount[$1]++) 中的 $1,则可以按其他条件对结果进行分组。使用 $7 将显示访问了哪些页面以及访问频率。当然,您会希望在开始时更改条件。以下将显示用户从特定 IP 访问了哪些页面:
awk -F'[ "]+' '$1 == "1.2.3.4" { pagecount[$7]++ }
END { for (i in pagecount) {
printf "%15s - %d\n", i, pagecount[i] } }' logfile.log
Run Code Online (Sandbox Code Playgroud)
您还可以通过 sort 管道输出以按顺序获取结果,或者作为 shell 命令的一部分,或者也可以在 awk 脚本本身中:
awk -F'[ "]+' '$7 == "/" { ipcount[$1]++ }
END { for (i in ipcount) {
printf "%15s - %d\n", i, ipcount[i] | sort } }' logfile.log
Run Code Online (Sandbox Code Playgroud)
如果您决定扩展 awk 脚本以打印出其他信息,后者将非常有用。这完全取决于您想了解什么。这些应该作为您感兴趣的任何内容的起点。
Dan*_*dey 25
出于我无法想象的原因,我从未见过其他人做过的一件事是将 Apache 日志文件格式更改为更易于解析的版本,其中包含对您而言真正重要的信息。
例如,我们从不使用 HTTP 基本身份验证,因此我们不需要记录这些字段。我对每个请求的服务时间很感兴趣,所以我们将其添加进去。对于一个项目,我们还想知道(在我们的负载均衡器上)是否有任何服务器处理请求的速度比其他服务器慢,所以我们记录名称我们代理回的服务器。
这是一台服务器的 apache 配置的摘录:
# We don't want to log bots, they're our friends
BrowserMatch Pingdom.com robot
# Custom log format, for testing
#
# date proto ipaddr status time req referer user-agent
LogFormat "%{%F %T}t %p %a %>s %D %r %{Referer}i %{User-agent}i" standard
CustomLog /var/log/apache2/access.log standard env=!robot
Run Code Online (Sandbox Code Playgroud)
从中您无法真正看出的是,每个字段之间是一个文字制表符 (\t)。这意味着如果我想在 Python 中进行一些分析,例如显示非 200 状态,我可以这样做:
for line in file("access.log"):
line = line.split("\t")
if line[3] != "200":
print line
Run Code Online (Sandbox Code Playgroud)
或者,如果我想做“谁在盗链图片?” 这将是
if line[6] in ("","-") and "/images" in line[5]:
Run Code Online (Sandbox Code Playgroud)
对于访问日志中的 IP 计数,前面的示例:
grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" logfile | sort -n | uniq -c | sort -n
Run Code Online (Sandbox Code Playgroud)
变成这样:
cut -f 3 log | uniq -c | sort -n
Run Code Online (Sandbox Code Playgroud)
更容易阅读和理解,而且计算成本要低得多(没有正则表达式),这在 9 GB 的日志上,对花费的时间产生了巨大的影响。当这变得非常整洁时,如果您想为用户代理做同样的事情。如果您的日志以空格分隔,则必须手动进行一些正则表达式匹配或字符串搜索。使用这种格式,很简单:
cut -f 8 log | uniq -c | sort -n
Run Code Online (Sandbox Code Playgroud)
和上面的完全一样。事实上,任何你想做的总结本质上都是一样的。
我到底为什么要把系统的 CPU 花在 awk 和 grep 上,而 cut 会以更快的速度完成我想要的数量级?
小智 17
忘记 awk 和 grep。查看asql。当您可以使用类似 sql 的语法查询日志文件时,为什么还要编写不可读的脚本。例如。
asql v0.6 - type 'help' for help.
asql> load /home/skx/hg/engaging/logs/access.log
Loading: /home/skx/hg/engaging/logs/access.log
sasql> select COUNT(id) FROM logs
46
asql> alias hits SELECT COUNT(id) FROM logs
ALIAS hits SELECT COUNT(id) FROM logs
asql> alias ips SELECT DISTINCT(source) FROM logs;
ALIAS ips SELECT DISTINCT(source) FROM logs;
asql> hits
46
asql> alias
ALIAS hits SELECT COUNT(id) FROM logs
ALIAS ips SELECT DISTINCT(source) FROM logs;
Run Code Online (Sandbox Code Playgroud)
小智 8
这是一个脚本,用于从最近的 N 个日志条目中查找顶级 url、顶级引用者和顶级用户代理
#!/bin/bash
# Usage
# ls-httpd type count
# Eg:
# ls-httpd url 1000
# will find top URLs in the last 1000 access log entries
# ls-httpd ip 1000
# will find top IPs in the last 1000 access log entries
# ls-httpd agent 1000
# will find top user agents in the last 1000 access log entries
type=$1
length=$2
if [ "$3" == "" ]; then
log_file="/var/log/httpd/example.com-access_log"
else
log_file="$3"
fi
if [ "$type" = "ip" ]; then
tail -n $length $log_file | grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | sort -n | uniq -c | sort -n
elif [ "$type" = "agent" ]; then
tail -n $length $log_file | awk -F\" '{print $6}'| sort -n | uniq -c | sort -n
elif [ "$type" = "url" ]; then
tail -n $length $log_file | awk -F\" '{print $2}'| sort -n | uniq -c | sort -n
fi
Run Code Online (Sandbox Code Playgroud)
对于访问日志中的 IP 计数:
cat log | grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | sort -n | uniq -c | sort -n
Run Code Online (Sandbox Code Playgroud)
这有点难看,但它有效。我还将以下内容与 netstat 一起使用(查看活动连接):
netstat -an | awk '{print $5}' | grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | egrep -v "(`for i in \`ip addr | grep inet |grep eth0 | cut -d/ -f1 | awk '{print $2}'\`;do echo -n "$i|"| sed 's/\./\\\./g;';done`127\.|0\.0\.0)" | sort -n | uniq -c | sort -n
Run Code Online (Sandbox Code Playgroud)
它们是我最喜欢的一些“单衬” :)
| 归档时间: |
|
| 查看次数: |
143627 次 |
| 最近记录: |