Server & Network/Linux

[Logging] logrotate, cron & crontab을 활용한 로그 파일 관리

AustinProd 2022. 11. 6. 19:18

이번 포스트에서는 Ubuntu 서버 내에서 스케쥴링 패키지인 Cron, Crontab을 활용한 로깅 방법을 공유한다. 서버 내부에 쌓이는 로그 파일을 정해진 시간에 분리 및 압축(.gz)하여 효과적으로 관리할 수 있다.

 

logrotate & Cron과 Crontab을 사용한 2가지 방법을 기록해두었다.

 

1. logrotate와 cron 활용

logrotate는 apache-utils 패키지에 있는 로그 관리 툴이다. logrotate에서는 로그 파일을 어떻게 관리할지를 지정한다. 생성 주기, 파일 권한, 저장 경로, 저장 형태 등의 속성을 주입할 수 있다. 그리고 cron은 서버 내 자동 스케쥴러 패키지로 서버 시간에 맞춰 지정한 작업이 수행하는 툴이다.

 

logrotate는 온전히 로깅에 대한 설정만 관리한다. 그렇기에 원하는 설정값을 부여했다면, cron 프로세스를 활성화 시켜 해당 작업을 스케줄에 맞춰 실행될 수 있게끔 활성화시켜줘야 한다. 아래 코드 블록에 자세한 내용을 적어두었다.

 

 

# logrotate 설치 (apache2-utils 다운)
sudo apt-get install apache2-utils

# logrotate 확인 (경로가 표기된다면 OK)
which logrotate

# 패키지 경로 이동
cd /etc/logrotate.d

# 로그 파일 스케쥴 설정 파일 생성 (vi log_sample)
/home/경로/logs/daemon.out {
	daily
	dateext
	rotate 180
	missingok
	compress
	notifempty
	create 644 user user
	copytruncate
	su user user
}

# cron 재실행
sudo systemctl restart cron.service
 

2. crontab 활용

위에서 소개한 방법은 logrotate과 cron을 함께 활용한 방법이었고, 지금의 방법은 온전히 cron 자체 기능으로 로그 파일을 관리하는 방법이다. crontab은 cron 스케쥴러에서 실행할 일정을 table 형식으로 등록하는 방법이다. 

 

보통 직접 작성한 쉘 스크립트를 호출하는 방법을 사용하기 때문에 자율성이 높고, 보다 복잡한 작업을 수행할 때 사용하면 좋다. 

 

crontab 등록 - 1

crontab을 처음 실행하면, 편집기 선택 옵션이 주어진다. 각자 선호하는 편집기를 선택하자.

 

# crontab 등록 (= 스케쥴 목록 편집)
crontab -e

# 초기 실행 시, 편집기(editor) 선택
# vi를 선호한다면, 2번
no crontab for ubuntu - using an empty one

Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed

Choose 1-4 [1]: 2
crontab: installing new crontab

 

crontab 등록 - 2

crontab 목록을 처음 열면 안에 주석을 제외하고 아무런 내용이 없다. 여기서 우리는 지정된 형식에 맞춰 스케줄을 등록할 수 있다.

 

문법은 크게 2개로 나누어 생각하면된다. 어느 주기로, 어떤 명령어를 수행할지를 입력한다. 아래 코드블록에서 나는 매일 밤 1시, 특정 경로(/home/app/logs)의 쉘 스크립트 파일(shell_log_to_gz.sh)을 경로 변수(/home/app/logs/SampleDir)와 함께 실행하는 명령어를 입력했다.

 

이 쉘 스크립트 파일은 로그 파일(.log)을 압축(.gz)하는 명령어를 담고 있다. 내부 상세 명령어는 맨 하단 코드 블록에 첨부해두었다.

 

입력이 완료됬다면, 편집기를 닫으면 된다. Ubuntu 기준, 서버 실행과 동시에 자동으로 실행되는 프로세스이기에 따로 실행을 시켜줄 필요 없다.

 

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
0 1 * * * /home/app/logs/shell_log_to_gz.sh /home/app/logs/SampleDir

 

crontab 목록 확인 및 제거

# crontab 확인 (= 스케쥴 목록 보기)
crontab -l

# crontab에 등록된 모든 항목 제거 (단일 항목을 제거하고 싶다면, 편집기로 해당 항목을 지워주면 된다.)
crontab -r

 

crontab에서 읽을 스크립트 생성 예시 - 1

# 파일 생성(shell_log_to_gz.sh 파일)
vi shell_log_to_gz.sh

# 권한 부여
chmod 755 shell_log_to_gz.sh

# 스크립트 명령어
#!/bin/bash
INPUT_PATH=$1
if [ -z "$INPUT_PATH" ];then
    echo "failed : you should input path"
    exit 1
fi

echo "========================="
echo "input path : " $INPUT_PATH

if [ ! -d "$INPUT_PATH" ]; then
    echo "failed : $INPUT_PATH is not directory"
    exit 1
fi

echo "convert log to gz start"
echo "========================="

TO_DAY=$(date +"%Y%m%d")

echo "today is "${TO_DAY}
echo "========================="

for log in $INPUT_PATH*/*.log
    do
        log_name=${log:(${#INPUT_PATH}+1):-4}

        if [ $log_name -lt ${TO_DAY} ]; then

            gzip ${INPUT_PATH}/${log_name}.log &\
            echo "${log_name}.log converted"
            echo "========================="
        else

    echo "${log} is failed to convert"
fi

done

 

crontab에서 읽을 스크립트 생성 예시 - 2

# 파일 생성(shell_log_to_gz.sh 파일)
vi shell_log_to_gz_depth.sh

# 권한 부여
chmod 755 shell_log_to_gz_depth.sh


# 스크립트 생성
#!/bin/bash
INPUT_PATH=$1
if [ -z "$INPUT_PATH" ];then
    echo "failed : you sholud input path"
    exit 1
fi

    echo "========================="
    echo "input path : " $INPUT_PATH

if [ ! -d "$INPUT_PATH" ]; then
    echo "failed : $INPUT_PATH is not directory"
    exit 1
fi

    echo "convert log to gz start"
    echo "========================="

    TO_DAY=$(date +"%Y%m%d")

    echo "today is "${TO_DAY}
    echo "========================="

for log in $INPUT_PATH*/*.log
    do
        echo "========================="
        log_name=${log: -12:8}
        if [ $log_name -lt ${TO_DAY} ]; then
            gzip ${log} &\
            echo "${log} converted"
            echo "========================="
        else
    echo "${log} is failed to convert"
fi

done