Como obter todas as linhas de log entre dois intervalos de datas no Linux

2

Como obter todas as linhas de log entre dois intervalos de datas no Linux? Eu tentei certos comandos como

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

mas só me dá as linhas com as datas exatas nelas.

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 

Esse me fornece dados corretos, mas date(Wed 21 Mar 14:52:00) deve ser uma correspondência exata, caso contrário, também não haverá saída para o horário mais próximo. Por exemplo, se Wed 21 Mar 14:52:01 for a hora de início, também não haverá saída.

Exemplo do arquivo de log

:

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
    
por Irfan 03.05.2018 / 17:31

3 respostas

2

Se o seu sistema estiver usando o systemd, o journalctl terá opções de intervalos de data e hora para gerar os logs.

De man journalctl :

-S, --since=, -U, --until= Start showing entries on or newer than the specified date, or on or older than the specified date, respectively. Date specifications should be of the format "2012-10-30 18:17:16". If the time part is omitted, "00:00:00" is assumed. If only the seconds component is omitted, ":00" is assumed. If the date component is omitted, the current day is assumed. Alternatively the strings "yesterday", "today", "tomorrow" are understood, which refer to 00:00:00 of the day before the current day, the current day, or the day after the current day, respectively. "now" refers to the current time. Finally, relative times may be specified, prefixed with "-" or "+", referring to times before or after the current time, respectively. For complete time and date specification, see systemd.time(7). Note that --output=short-full prints timestamps that follow precisely this format.

Combine isso com a opção --user e alguns grep para filtrar as mensagens do sistema para reduzir a desordem. Se o seu sistema não usa o systemd, ou as mensagens do seu programa não são capturadas pelo journald, então você pode precisar de algo diferente.

    
por 03.05.2018 / 19:42
1

Assumindo um ambiente de "tempo" simplista (sem conversões de fuso horário, sem alterações de horário de verão), você pode informar o awk em intervalos de datas em segundos desde a época, e fazer com que o awk converta cada data em segundos. epoch e imprima apenas linhas nesse intervalo:

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.......

Não é particularmente eficiente, pois chama date para cada linha; poderia ser melhorado para pesquisas em cache, se isso se tornar uma preocupação.

    
por 03.05.2018 / 21:20
0

Uma outra abordagem que estou usando com frequência para arquivos de log de aplicativos Java é encontrar o número da linha da primeira ocorrência dos registros de data e hora

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)

em seguida, forneça as informações entre, ou seja,

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

ou via

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

Isso rastreará rastreamentos de pilha, conteúdo da API REST, estruturas JSON etc.

Para determinados aplicativos, como da estrutura do Hadoop, tenho scripts específicos para trabalhar com seus arquivos de log. O de Jeff mencionou abordagem com date que estou usando para calcular o tempo entre dois eventos.

Para mais informações (e referência):

por 03.05.2018 / 21:41