如何从access.log中提取不同的域



我想分别提取每个域的请求数。Access.log";apache"-节点名要获得以下结果:

# domain10.com  20-11-2020
560  22:00
550  22:01
620  22:02
# test.domain20.com
number request       time
550              22:01
620               22:02

我使用grep提取每小时分钟的所有请求

grep "[domain.com]" /root/eslam33/test/access.log.7 |
cut -d[ -f2 | cut -d] -f1 | awk -F: '{print $2":"$3}' |
sort -nk1 -nk2 | uniq -c | awk '{ if ($1 > 10) print $0}' 

输出:来自access.log:

105.181.206.150 - - [30/Nov/2020:06:37:03 +0200] "POST /store/web/app.php/api/v3/WEB/products/filter?_locale=en_US HTTP/1.1" 200 19002 "https://from-egypt.com/en_US/collection?taxons=Fashion&sort=date&order=asc&page=1"

但我想运行一个命令或脚本,分别向每个域发出请求。我该怎么做?

如果您想提取第二个和第三个斜杠之间最后一个引用字段中的文本,请尝试

sed 's%.*"https*://([^/]*)/[^"]*"$%1%' apache.log

如果你想把访问的分钟和小时作为前缀,这也是可行的:

sed 's%[^[]*[[^:]*:([0-9]*:[0-9]*)].*"https*://([^/]*)/[^"]*"$%1 2%' apache.log

您的sort管道应该可以正常工作;然后添加一些后处理,根据您的喜好对其进行格式化。

sed 's%[^[]*[[^:]*:([0-9]*:[0-9]*)].*"https*://([^/]*)/[^"]*"$%1 2%' apache.log |
sort -n | uniq -c |
awk 'NR == 1 || $2 != prev { print "# " $2; prev = $1; next }
$1 > 10 { print $1, $3 }'

您可以使用awk和标准的apache日志文件:

awk '{ 
split($4,map1,"[:/]");
split($11,map2,"/"); # split to get the domain name
if (map2[3] == "")
{
next
}
map[map2[3]" "substr(map1[1],2)" "map1[2]" "map1[3]" "map1[4]":"map1[5]]+=1 
} 
END { 
for (i in map) 
{ 
print i" - "map[i]
} 
}' access_log

一个衬垫:

awk '{ split($4,map1,"[:/]");split($11,map2,"/");if (map2[3])=="") { next } map[map2[3]" "substr(map1[1],2)" "map1[2]" "map1[3]" "map1[4]":"map1[5]]+=1 } END { for (i in map) { print i" - "map[i]} }' access_log

使用:和/将第4个空格分隔的字段拆分为名为map的数组。然后使用天、月、年、小时和分钟(map1的不同索引(为另一个数组映射创建索引。通过拆分第9个字段添加域名。每当遇到同一天、月、年、分钟和小时的请求时,此数组都会递增。最后,将打印数组中的数据。

为了在特定域上搜索,只需在字段9上添加模式匹配即可:

awk '$11 ~ /from-egypt.com/ { 
split($4,map1,"[:/]");
split($11,map2,"/");
if (map2[3])=="") 
{ 
next 
}
map[substr(map1[1],2)" "map1[2]" "map1[3]" "map1[4]":"map1[5]]+=1 
} 
END { 
for (i in map) 
{ 
print i" - "map[i]
} 
}' access_log

最新更新