서버관리_20 로그 출력을 감시해서 로그에 특정 문자열이 있으면 경고하기

 
  • 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어

명령어: tail, read
키워드: 로그 파일, 감시, 실시간
사용처: 시스템 점검 작업을 하면서 실시간으로 감시 대상 로그 파일을 보기 좋게 가공해서 출력하고 싶을 때

실행 예제

$ ./log-tailgrep.sh
!주의! 파일을 찾지 못했습니다 : [03ac2fsd.dat] File Not Found
!주의! 파일을 찾지 못했습니다 : [pxac2fsd.dat] File Not Found
!경고! 애플리케이션 이상 : [6I7cht1npA] Application Error

실시간으로 로그를 추적해서 주의 메시지를 추가해서 출력

스크립트

#!/bin/sh

# 감시 대상 로그 파일명 설정
logfile="/var/log/myapp/application.log" # ------ 1

# tail 명령어로 로그 감시 :
#  * -F 실시간 감시
#  * -n 0 추가분만 감시
tail -F -n 0 "$logfile" |\ # -------------------- 2
while read line
do
  # 로그에서 일치하는 문자열이 있으면 경고 출력
  case "$line" in # case문 ---------------------- 3
    *"File Not Found"*)
      echo "!주의! 파일을 찾지 못했습니다 : $line"
      ;;
    *"Application Error"*)
      echo "!경고! 애플리케이션 이상 : $line"
      ;;
  esac
done

   

해설

이 스크립트는 계속 추가되는 로그 파일에 문자열 검색을 해서 특정 문자열이 포함된 로그가 출력되면 그 내용을 실시간으로 표시합니다. 어떤 시스템 점검 작업 중에 다른 터미널창에서 표시되는 로그를 확인하는 툴로 사용한다고 가정합니다.

  • 스크립트 이용 예

여기서 점검 대상 애플리케이션은 application.log 로그 파일에 대량의 로그를 기록한다고 합시다. 이때 에러 메시지가 다음과 같다고 가정합니다.

  • application.log 출력
    [03ac2fsd.dat] File Not Found
    [pxac2fsd.dat] File Not Found
    

눈에 잘 띄지 않으므로 에러가 출력되면 바로 알 수 있도록 에러 메시지 앞부분에 강조 표시를 추가한다고 가정합시다.

  • 강조 표시 추가
    !주의! 파일을 찾지 못했습니다 : [03ac2fsd.dat] File Not Found
    !주의! 파일을 찾지 못했습니다 : [pxac2fsd.dat] File Not Found
    

1에서 감시 대상 로그 파일을 지정합니다. 각자 환경에 맞게 수정해서 사용하기 바랍니다.

2에서 로그 출력을 감시하고 while문에 파이프로 연결합니다. 여기서 이용하는 tail 명령어는 파일 마지막 부분을 표시하는 명령어로 주요 옵션은 다음과 같습니다.

  • tail 명령어 주요 옵션

    옵션 의미
    -f 파일 끝에 도달해도 종료하지 않고 추가되는 내용을 기다림
    -F -f 옵션 기능 및 파일명 변경이나 로테이션도 감시
    -n <숫자> 파일 끝의 <숫자> 줄만큼 표시
    -c <숫자> 파일 끝의 <숫자> 바이트만큼 표시

2에서 tail 명령어는 -F 옵션을 이용합니다. 이렇게 하면 계속 출력되는 로그 파일을 실시간으로 추적할 수 있습니다. 일반적으로 이런 용도로는 소문자 -f 옵션을 이용하는 경우가 많은데 이런 예에서는 로그 로테이션에도 대응하도록 -F 옵션을 이용하는 편이 좋습니다.

로그 로테이션이란 애플리케이션 로그 파일이 너무 덩치가 커지지 않도록 어떤 단위로 로그 파일은 분할해서 바꾸는 기능입니다. 로테이션할 때 파일명 끝에 숫자값을 붙이는 형식이 일반적입니다.


이때 application.log가 다음날이 되면 application.log.1로 파일명이 변경되고 신규 파일 application.log가 작성됩니다. 즉 매일, 애플리케이션 로그 출력이 새로운 파일로 전환됩니다.

여기서 tail 명령어 -f 옵션을 이용하면 변경 전 파일을 계속 읽기 때문에 새로운 application.log에 추가되는 걸 검출할 수 없습니다. -F 옵션을 이용하면(OS에 따라 조금씩 구현은 다르지만) tail 명령어는 정기적으로 해당 파일을 다시 열기 때문에 로그 로테이션에 대응할 수 있습니다.

그럼 2에서는 -n 0으로 마지막 0줄을 지정합니다. 이것은 스크립트 실행 시점에 이미 존재하는 로그 파일 내용은 읽지 않고 실행한 다음 추가되는 로그만 대상으로 하기 위한 처리입니다. -n 0이 없으면 tail 명령어 기본 동작은 끝 10줄을 읽습니다. 그 10줄은 과거에 출력된 로그이므로 이런 실시간 감시 목적에는 적절하지 않습니다.

2tail 명령어 출력은 | (파이프)로 while문에 연결합니다. 여기서 끝에 \로 줄바꿈하는데 한 줄이 너무 길어지면 보기 힘들어지므로 보기 좋게 하기 위함입니다. while문에서는 read 명령어로 셸 변수 line에 추가된 로그 파일을 한 줄씩 읽습니다.

3은 case문에서 추가된 로그를 검색합니다. 셸 변숫값에서 특정 문자열을 검색하는 방법이 몇 가지 있지만 여기에서는 사용하기 가장 쉬운 case문을 이용합니다. 우선 “File Not Found”라는 문자열을 포함하면 “!주의! 파일을 찾지 못했습니다” 라는 문구를 출력합니다.

3case문 일치는 임의의 문자열을 뜻하는 와일드 카드 *(애스터리스크)를 사용합니다. “*File Not Fount“라고 *를 큰 따옴표 기호 안에서 사용하면 메타 문자가 아니라 에스터리스크를 의미하게 되어서 일치하지 않게 됩니다. 따라서 * 기호는 큰따옴표 밖에서 사용해서 *“Filne Not Found”라고 작성합니다. 일치하는 문자열을 찾으면 echo 명령어로 “!주의! 파일을 찾지 못했습니다”를 출력하고 그 뒤에 이어서 $line으로 로그 내용을 표시합니다.

3의 case문과 마찬가지로 “Application Error”라는 문자열도 검색해서 “!경고!”를 표시합니다. 그 외에도 패턴을 추가하려면 여기서 case문을 추가하면 됩니다.

이렇게 하면 지정한 로그 파일을 실시간으로 감시해서 점검 작업 등에 유용하게 활용할 수 있습니다. 그 외에도 어떤 읽기 힘든 로그를 보기 좋도록 실시간으로 텍스트 조작을 해서 표시하거나 숫자가 출력되는 프로그램의 로그를 실시간으로 계산해서 보여주는 사용법도 있습니다.

   

주의사항

  • 중요한 작업 시에는 이런 스크립트가 에러를 놓칠 수도 있으므로 메인 작업창 하나, 예제와 같은 스크립트로 가공한 로그 확인 창 하나, 실제 로그를 tail -F로 계속 표시하는 창 하나 이렇게 3개를 열어두고 작업하는 것이 좋습니다.

  • 창 3개를 열어서 사용

less 명령어 이용

계속 추가되는 로그 파일을 감시하려면 tail 명렁어 외에도 less 명령어도 가능합니다.

less 명령어는 파일을 인수로 실행해서 지정한 텍스트 파일 내용을 관람하기 위한 페이저라고 부르는 명령어입니다. 파일 내용 표시 중에 space 키를 눌러서 다음 쪽, b로 앞쪽으로 이동 가능합니다.

그리고 f를 누르면 less 명령어는 파일 끝을 계속 읽는 모드로 전환합니다.

  • less 명령어에서 F키를 누름
    [03ac2fsd.dat] File Not Found
    [pxac2fsd.dat] File Not Found
    Waiting for data... (interrupt to abort)
    

    Waiting for data… 라고 표시된 모드가 되면 less 명령어는 tail 명령어 -f 옵션과 마찬가지로 파일에 추가된 내용을 읽습니다. less 명령어의 F 모드에서 빠져나오려면 Ctrl + C 키를 누릅니다. less 명령어 종료는 q이므로 F 모드에서 그대로 종료하려면 Ctrl + Cq 순서대로 누릅니다.