编写一个 Bash shell 脚本来读取 mongodb 日志文件并将其内容写入另一个文本文件

Posted

技术标签:

【中文标题】编写一个 Bash shell 脚本来读取 mongodb 日志文件并将其内容写入另一个文本文件【英文标题】:Write a Bash shell script to read mongodb log file and write it's content to another text file 【发布时间】:2021-04-24 03:07:12 【问题描述】:

我正在尝试读取位于 /var/log/mongodb 的 MongoDB 日志文件,其内容如下:


2019-11-04T05:04:00.390-0800 I COMMAND [conn38649] command loldb.$cmd command: update update: "SUBSCRIPTION", ordered: true, writeConcern: w: 1 , $db: " loldb" numYields:0 reslen:295 locks: Global: acquireCount: r: 460, w: 460 , Database: acquireCount: w: 460 , Collection: acquireCount: w: 459 , oplog: acquireCount: w: 1 协议:op_query 568ms

2019-11-04T05:04:00.396-0800 I COMMAND [conn38657] command loldb.SUBSCRIPTION command: find find: "SUBSCRIPTION", filter: customerID: 75824180, policeDepartmentID: 1 , projection: , $readPreference: mode: "secondaryPreferred" , $db: "loldb" planSummary: COLLSCAN keysExamined:0 docsExamined:69998 cursorExhausted:1 numYields:550 nreturned:1 reslen:430 locks: Global: acquireCount: r: 1102 ,数据库: acquireCount: r: 551 ,集合: acquireCount: r: 551 协议:op_query 424ms

2019-11-04T05:04:00.402-0800 I COMMAND [conn38735] command loldb.SUBSCRIPTION command: find find: "SUBSCRIPTION", filter: customerID: 75824164 , projection: , $readPreference: mode: "secondaryPreferred" , $db: "loldb" planSummary: COLLSCAN keysExamined:0 docsExamined:58142 cursorExhausted:1 numYields:456 nreturned:1 reslen:417 locks: Global: acquireCount: r: 914 ,数据库: acquireCount: r: 457 ,集合: acquireCount: r: 457 协议:op_query 374ms


每个块引用是一个单行条目

文件的内容每秒更新一次我需要读取文件,如果查询时间protocol:op_query 385ms 超过 300 毫秒,我需要将整个日志/行保存到另一个文本文件 slow_queries.text

我正在读取的文件是.log文件,但内容似乎是JSON格式(如果我错了,请纠正我)前面有时间戳和命令类型,有没有有效的方法来读取这种格式的数据?我只是逐字逐句阅读。

另外,我该怎么做才能自动读取对.log 文件所做的更改,而无需每次都运行脚本?

【问题讨论】:

【参考方案1】:

我刚刚在我的本地机器上试过这个,可能需要为你的用例做一些工作。但是我添加了一些 cmets,所以也许这会对您有所帮助:

编辑:我添加了时间戳检查,您必须根据需要对其进行配置

#!/bin/bash

# continously read from the file and pipe it into the while loop
tail -F "test.log" | \
while read LINE
do
    # get timestamp from LINE and get time in seconds
    timeinseconds="$(grep -P "^\S*" | date -d - +%s)"
    # get current timestamp before 5 minutes
    timebeforefivemin="$(date -d '-5 minutes' +%s)"
    # only log if timestamp of line is smaller to time before 5 min
    if [[ $(expr $timeinseconds - $timebeforefivemin) -lt 0 ]];
        then
        # get the time of the query from the line
        querytime="$(echo "$LINE" | grep -oP '\d+ms' | grep -oP '\d+')"
        #if the grep was successful and the query time is greater than 300
        if [ $? = 0 ] && [ "$querytime" -gt 300 ]
        then
            # echo the line into the slow_queries file -> change it to the path you want
            echo "$LINE" >> slow_queries.txt
        fi
    fi
done

【讨论】:

谢谢你,这有效,有什么方法可以搜索特定的时间戳,或者只有 5 分钟的日志 是要在这个脚本中搜索/var/log/mongodb下的日志文件,还是只想在这个脚本之外搜索slow_queries.txt? 在读取 /var/log/mongodb 文件中的日志时使用相同的脚本有没有办法按时间戳过滤这些日志? 您必须编辑timebeforefivemin 以分配给date -d 'THE_TIMESTAMP_TO_FILTER_BY' 之类的东西,if 条件必须是if [[ $timebeforefivemin -eq $timeinseconds ]] 之类的东西。请注意,您必须提供准确的时间戳。但是请查看相应的手册页以获取日期并自己查看条件,以了解如何实现您想要的功能:) 谢谢你,我会调查所有这些:)

以上是关于编写一个 Bash shell 脚本来读取 mongodb 日志文件并将其内容写入另一个文本文件的主要内容,如果未能解决你的问题,请参考以下文章

Shell脚本

linux shell脚本有编译器吗?每次都是运行后提示很多错误啊,能在编写的时候提示错误吗?

系统管理中 bash shell 脚本常用方法总结

实验楼-高级Bash脚本编程指南

shell

linux的shell编程中#!/bin/sh和bash是啥意思?