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를 사용하지 않거나 프로그램 메시지가 저널링에 의해 캡처되지 않으면 다른 것이 필요할 수 있습니다.

답변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 프레임워크와 같은 일부 애플리케이션의 경우 로그 파일을 처리하기 위한 특정 스크립트가 있습니다. Jeff가 언급한 방법은 date두 사건 사이의 시간을 계산하는 데 사용됩니다.

더 많은 정보를 알고 싶다면(및 참조):

관련 정보