如何在 Linux 中获取两个日期范围之间的所有日志行

如何在 Linux 中获取两个日期范围之间的所有日志行

如何获得所有日志行Linux 中两个日期范围之间?我尝试了某些命令,例如

1)awk '$0>=from&&$0<=to' from=\"Wed 21 Mar 14:52:08\" to=\"Wed21 Mar 
14:53:08\" /home/db2inst1/logs/tracestart.log 

但它只给我那些包含确切日期的行。

2) sed -n '/Wed 21 Mar 14:52:00/,/Wed 21 Mar 14:53:08/p'  
/home/db2inst1/logs/tracestart.log  /home/db2inst1/logs/traceend.log 

这个给了我正确的数据,但date(Wed 21 Mar 14:52:00)应该是完全匹配的,否则也没有最近时间的输出。例如,如果Wed 21 Mar 14:52:01是开始时间,则也没有输出。

日志文件样本::

2018-04-04 11:40:46 INFO  RestAssuredService:184 - some thing.......
2018-04-04 11:40:48 INFO  RestAssuredService:199 - some thing.......
2018-04-04 11:40:48 INFO  RestAssuredService:177 -
*********invokeService is 
2018-04-04 11:40:48 INFO  ProductInfoTest:57 - Response Map::::: 
{RESPONSE_TYPE=application/json, EXPECTED_RESPONSE={
"products": [
    {
        "id": 23001,
        "type": "SHIRT",
        "description": "Mens Wear Dresses",
        "price": 850,
        "brand": "PETER_ENGLAND"
    },
    {
        "id": 23002,
        "type": "KURTI",
        "description": "Womens Wear Dresses",
        "price": 899,
        "brand": "ALLEND_SOLEY"
    }
] }, 
ACTUAL_RESPONSE=com.jayway.restassured.internal.RestAssuredResponseImpl@7d48651a}
2018-04-04 11:40:48 INFO  ProductValidator:47 - EXPECTED_RESPONSE:::: {
"products": [
    {
        "id": 23001,
        "type": "SHIRT",
        "description": "Mens Wear Dresses",
        "price": 850,
        "brand": "PETER_ENGLAND"
    },
    {
        "id": 23002,
        "type": "KURTI",
        "description": "Womens Wear Dresses",
        "price": 899,
        "brand": "ALLEND_SOLEY"
    }
] }
2018-04-04 11:40:48 ERROR ProductInfoTest:65 - Exception occured::: null
2018-04-04 11:40:48 INFO  ProductInfoStepDefinations:27 - addProductDetailsApiTest Starting::::
2018-04-04 11:40:48 INFO  ProductInfoTest:53 - getAllProductsInfo starting
2018-04-04 11:40:48 INFO  RestAssuredService:170 -
*********invokeService is starting*********
2018-04-04 11:40:48 INFO  RestAssuredService:247 - Final uri:::::: rest/market/item/info
2018-04-04 11:40:48 INFO  RestAssuredService:258 - HeaderParametersMap :::::: {Accept=application/json, Content-Type=application/json

答案1

如果您的系统使用 systemd,则journalctl可以选择从日志输出的时间和日期范围。

man journalctl

-S、--since=、-U、--until= 分别开始显示指定日期或更新日期或指定日期或早于指定日期的条目。日期规范应采用“2012-10-30 18:17:16”格式。如果省略时间部分,则假定为“00:00:00”。如果仅省略秒部分,则假定为“:00”。如果省略日期部分,则假定为当天。或者,字符串“昨天”、“今天”、“明天”被理解为分别指当天前一天、当天或当天后一天的00:00:00。 “现在”指的是当前时间。最后,可以指定相对时间,以“-”或“+”为前缀,分别指当前时间之前或之后的时间。有关完整的时间和日期规范,请参阅 systemd.time(7)。请注意,--output=short-full 打印完全遵循此格式的时间戳。

将其与--user选项和一些选项结合起来grep可以过滤掉系统消息以减少混乱。如果您的系统不使用systemd,或者您的程序的消息没有被journald捕获,那么您可能需要其他东西。

答案2

假设一个简单的“时间”环境(没有时区转换,没有夏令时更改),您可以告诉 awk 您的日期范围以自纪元以​​来的秒数为单位,然后让 awk 将每个日期转换为自纪元以来的秒数并打印仅该范围内的行:

awk -v from=$(date -d "2018-04-04 11:40:45" +%s) \
    -v   to=$(date -d "2018-04-04 11:40:47" +%s) \
 '{ "date -d \""$1 " "$2"\" +%s" | getline s; 
    if (from <= s && s <= to) print;
  }' < input
2018-04-04 11:40:46 INFO  RestAssuredService:184 - some thing.......

它不是特别有效,因为它date需要每条线;如果这成为一个问题,可以增强它以缓存查找。

答案3

我经常对 Java 应用程序的日志文件使用的另一种方法是查找时间戳第一次出现的行号

FROM_DATE="Wed 21 Mar 14:52:08"
TO_DATE=""Wed 21 Mar 14:53:08"

FROM_LINE=$(grep -n -m 1 ${FROM_DATE} ${FILE} | cut -d ":" -f 1)
TO_LINE=$(grep -n -m 1 ${TO_DATE} ${FILE} | cut -d ":" -f 1)

然后给出之间的信息,即

tail -n "${FROM_LINE}" ${FILE} | head -n $(expr $TO_LINE - $FROM_LINE)

或通过

sed -n -e "${FROM_LINE},${TO_LINE} p" -e "${TO_LINE} q" ${FILE}

这将捕获堆栈跟踪、REST API 内容、JSON 结构等。

对于 Hadoop 框架等某些应用程序,我有特定的脚本来处理它们的日志文件。杰夫提到的方法date我用来计算两个事件之间的时间。

了解更多信息(和参考):

相关内容