shell 如何使用bash脚本从日志文件中查找未使用的API?

iq0todco  于 2023-01-17  发布在  Shell
关注(0)|答案(3)|浏览(131)

目标是找出过去7天内未使用过的API,有一个文件存储所有API列表,还有一个文件夹包含每日日志数据。

API.txt(存储所有api列表):

/api/user/status
/api/property/status
/api/video/banner/list
/api/user/info
/api/user/giftList
/api/user/ticket
...

日志数据(存储7天):

每个日志文件将如下所示

2023-01-16 01:20:28.646 +00:00: ID: 1865555 IP:1.2.3.4 POST: /api/user/status Response:1
2023-01-16 01:20:28.646 +00:00: ID: 1444444 IP:1.2.3.4 POST: /api/user/info Response:1
2023-01-16 01:20:28.646 +00:00: ID: 1865555 IP:1.2.3.4 POST: /api/property/status Response:1
2023-01-16 01:20:28.646 +00:00: ID: 1333333 IP:1.2.3.4 GET: /api/video/comments Response:2
2023-01-16 01:20:28.646 +00:00: ID: 1865555 IP:1.2.3.4 GET: /api/user/rate Response:1
...

方法:

从API数据的第一行(/api/user/status)开始,取log文件夹中的文件逐一比较(七个文件),如果发现中间使用了API,则换到下一个API(/api/property/status)检查,如果API的七个文件都没有使用,则回显API即可。

我的努力

问题1:if [[ ! $line == *$i* ]];不起作用,它可以充当if [[ $line == *$i* ]];,但我想得到不等于的结果
问题2:这只是比较两个文件,但是我如何检查循环内的其余六个文件呢?

file1="api.txt"

file2="2023-01-10_00-00-00.log" 

if [ ! -f "$file1" ] || [ ! -f "$file2" ]; then
    echo "Error: One of the files does not exist."
    exit 1
fi

declare -a lines1

while IFS= read -r line; do
    lines1+=("$line")
done < "$file1"

while IFS= read -r line; do
    for i in "${lines1[@]}"; do 
        if [[ ! $line == *$i* ]];
        then
            echo "$i"
            break
        fi
    done
done < "$file2"
monwx1rj

monwx1rj1#

Grep(awk,sed)可以处理多个文件。我建议在API中循环并在日志中使用grep 7天。

api_names=( $(cat api.txt) )
log_files=( $(find path_to_logs -type f -daystart -mtime +7) )

for api in "${api_names[@]}"; { grep -q " $api " "${log_files[@]}" || echo $api not used; }
lbsnaicq

lbsnaicq2#

首先,我将从日志中创建一个实际使用的所有API的列表,例如

grep -hoE ' (GET|POST): /api/[^ ]+' $logdir/*.log | cut -d ' ' -f 2 | sort -u >used_api.txt

然后,我将在api.txt中搜索新生成的used_api.txt不存在的所有行

grep -vxF -f used_api.txt api.txt >unused_api.txt
ttisahbt

ttisahbt3#

cat *.log | awk 'NR==FNR{u[$8];next} !($0 in u)' - api.txt
  • 将日志作为第一个输入文件(-)流入awk
  • 将数组索引设置为字段8的值
  • (可选择在储存前进行其他测试)
  • 读取日志后,循环api.txt中的各行
  • 如果value不是数组索引,则打印它

如果日志可能包含许多不感兴趣的字段8的值,则可以重新排序,并且只存储相关值。例如:

awk '
    NR==FNR { api[$0]; next }
    $8 in api { used[$8] }
    END { for (a in api) if (!(a in used)) print a }
' api.txt *.log

或者您可以初始化API集并从中删除:

awk '
    NR==FNR { unused[$0]; next }
    { delete unused[$8] }
    END { for (api in unused) print api }
' api.txt *.log

相关问题