알아두면 좋은 IT 지식/Technical Support

리눅스에서 자바 스택트레이스 로그파일 여러줄 검색 및 특정패턴 제외 방법

uutopia 2021. 7. 2. 13:44

오류로그를 분석하다가 다음과 같은 상황에 부딪혔다.

  1. 오류가 너무 많이 쌓여서 로그파일의 용량이 매우 큼
  2. 일반적인 stack trace 로그파일로 오류가 발생한 지점에 '<<__Exception__>>...<<!__Exception__>>' 라인이 입력되고, 오류에 대한 간단한 설명은 그 윗줄에 표시되므로 오류를 찾기위해서는 '__Exception' 패턴을 검색하지만 오류 내용을 구분하기 위해서는 그 윗줄을 같이 참고해야 함
  3. 로그들을 대충 훑어보니 99%는 크게 중요하지않은 반복오류인 것 같은데 그 외에 의미있는 오류가 섞여있는지 확인이 필요
  4. 일일히 오류들을 눈으로 확인하기에는 양이 너무 많아서 빠른 검색을 위한 코드작성이 필요
  5. 다양한 환경에서도 사용할 수 있도록 기본적이고 범용적인 코드만 사용

 

 

사용할 명령어, 옵션, 정규표현식은 아래와 같다.

  • 명령어
    • grep
    • more
  • 옵션
    • grep -B? : ?숫자만큼의 윗라인까지 출력
    • grep -v : 해당라인 제외
    • grep -c : 일치하는 라인 수 출력
  • 정규표현식
    • * : 0이상의 모든문자
    • ^ : 라인의 시작
    • $ : 라인의 끝

 

 

아래와 같이 활용했다.

grep -B1 '__Exception' *.log | grep -v '^--&' | grep -v '__Exception' | grep -v 'IO error' | grep -v 'failure to connect' | more

코드 설명

grep -B1 '__Exception' *.log : 현재 디렉터리의 .log로 끝나는 모든 파일 중 '__Exception'패턴을 검색하여 그 라인위에 1줄까지 같이 출력한다.

| grep -v '^--&' : 위의 출력결과에서 자동으로 입력되는 구분값인 '^--$' 패턴을 제외한다. (그냥 '--'로 입력할 경우 혹시 오류내용중에 '--'문자가 있을 수 있으므로 라인의 시작과 끝이 --인 것을 검색하여 구분한다.)

| grep -v '__Exception' : 위의 출력결과에서 '__Exception'검색패턴이 입력된 패턴라인을 제외한다.

| grep -v 'IO error' : 위의 출력결과에서 반복되고 중요하지 않다고 판단한 오류(ex. IO error)를 제외한다.

| grep -v 'failure to connect' : 위의 출력결과에서 반복되고 중요하지 않다고 판단한 오류(ex. failure to connect)를 제외한다.

| more : 결과라인이 많을 수 있으므로 more를 걸어서 오류가 발생한 로그파일명과 내용을 확인한다.

결과가 너무 많을 경우 맨 뒤 | grep에 -c옵션을 통해서 발생라인 수를 확인할 수 있다.

 

 

 

실행 결과

로그 디렉터리의 .log파일들 중에서 지속적으로 발생하는 'IO error', 'failure to connect' 오류를 제외한 오류를 2개 찾는데 성공했다.

 

 

 

P.S

  • vi에서는 검색(/)에서 다음과 같은 정규표현식(/[^IO error]\_.<<__Exception) 을 통해서 아주 간단하게 위와 비슷한 결과를 도출할 수 있었습니다. 하지만 용량이 큰 .log파일을 vi로 열 경우 서버에 부하가 발생하므로, 주로 more나 less를 사용하는데 more나 less에서는 위 정규표현식이 통하질 않아서 여러가지 간단한 방법을 찾다가 실패하고 결국 조금 복잡한 grep을 다중으로 사용하는 방법을 찾게 되었습니다.
  • 여기서 핵심은 여러줄을 검색하고 그중에서 특정라인을 제외하는 것인데 생각보다 쉽지 않았습니다. 개행(줄바꿈)에 대한 표현이 프로그램이나 명령어, 옵션에 따라서 다르고 결과가 원하는방식으로 나오지 않았고, 패턴과 의미있는 문구가 다른줄에 있을 때 이를 구분하는방법을 찾는데도 오래 걸렸습니다. 결국 조금 지저분하지만 grep을 다중으로 활용해서 출력결과에서 또다시 출력결과를 얻어내는 방법을 사용할 수 밖에 없었습니다.
  • 의미있는 오류, 중요하지 않은 오류를 골라내는 것은 많은 경험과 노하우가 필요하고 상황에 따라 다르기 때문에 공식이나 쉬운 방법은 없는 것 같습니다. 좋은 팁이 있다면 공유좀 부탁드립니다.