docker log 압축과 제거

2019. 8. 9. 00:20OS & Server/Docker

728x90

 

dockerrun / file / compose / swarm 

어떠한 경우로 사용하던지 해당 container log가 무수히 적재됩니다.

 

example:

docker logs overmap -f

하지만 이 데이터가 너무 많이 쌓이면 보기가 힘들어집니다.

그럴 때는 Linux/Unix에서 사용되는 tail 명령어를 이용하는데

docker에서도 옵션 중에 tail을 줄 수 있습니다.

 

 

docker logs overmap -f --tail

여기 까진 좋은데 docker log가 너무 많이 쌓이게 될 경우 너무 많은 용량을 차지하게 됩니다.

이럴 때는 linuxtruncate라는 명령을 이용하여 로그를 비워줄 수 있습니다.

 

 

truncate -s 0 /var/lib/docker/containers/8363088ca41a80025d840ae7d191710bbe3cc3aa9f4804720f1864eb84569566/8363088ca41a80025d840ae7d191710bbe3cc3aa9f4804720f1864eb84569566-json.log

 

하지만 이 긴 컨테이너의 경로를 매번 기억하기도 작성하기도 귀찮아서,

cron으로 적재하면 정말 좋겠지만 치명적인 결함이 하나 생깁니다.

 

로그의 용도중 가장 핵심은 Error (info, warn, error, critical)등 필요에 의해

모니터링이 필요한 로그는 이때 볼 수 없게 되죠.

 

 

그래서 저는 로그는 비우되 일단 압축해서 보존하고 있다가 필요할 때 빼서 쓰려고 간단하게

bash shell script로 작성을 해봤습니다.

 

 

 

작성이 어려우신 분을 위해 파일을 첨부합니다.

docker-logger.sh
0.00MB

wget https://k.kakaocdn.net/dn/bBJbUB/btqxkVz9alZ/qL0V7oGY1WjvqCkoip23Zk/tfile.sh

 

 

 

Code

#!/bin/bash
# Global variable
FILES=()
LOGDIR=$HOME/backup/docker-logs
NOW=$(date +%Y-%m-%d)

if [ $EUID -ne 0 ]; then
        echo -e "\e[1m\e[93mPlease run as must be a root!\033[0m"
        exit
fi


# check Log Directory
if [ ! -d ${LOGDIR} ]; then
        mkdir -p ${LOGDIR}
fi

NAMES=( `docker ps --format '{{.Names}}'` )
for name in ${NAMES[@]}
do
        folder=${LOGDIR}/${name}
        if [ ! -d ${folder} ]; then
                mkdir -p ${folder}
                echo "Created Directory : "${folder}
        else
                echo ${name}
                find ${LOGDIR} -type f -name "*.log" -mtime +7 -delete
        fi
        tmp=`docker inspect --format='{{.LogPath}}' ${name}`
        FILES+=("$tmp")
done

for index in ${!FILES[@]}
do
        nice -n 19 bzip2 -ck ${FILES[$index]} > ${LOGDIR}/${NAMES[$index]}/${NOW}.bz2
        truncate -s 0 ${FILES[$index]}
done

gzip이 아닌 압축 효율이 더 좋은 bzip2를 사용하였습니다.

 

첫 번째 분기의 조건문은 permission을 체크하는 구간입니다.

* 도커의 로그파일에 접근하기 위해서는 sudo 혹은 root유저만 이용할 수 있습니다.

 

 

두 번째 분기의 조건문은 LOGDIR의 변숫값에 의한 경로를 검사하고 없을 경우 생성합니다.

 

 

세 번째 분기의 반복문은

docker에서 각 컨테이너의 컨테이너명을 배열에 저장하며, 해당 컨테이너명으로 LOGDIR 밑에 폴더를 생성합니다.

그 후 각 컨테이너의 로그 경로를 배열에 저장합니다.

 

 

네 번째 분기의 반복문은

프로세스 우선순위를 제어하여 CPU 점유율이 과부하되는 것을 방지하기 위해 nice 명령을 사용하여

배열에 저장된 컨테이너의 로그파일 경로를 읽어 들인 뒤, bzip2 압축합니다. 

 

 

bzip2에서 -kkeep으로 원본 파일을 bz2로 변경하지 않는다는 의미입니다.

bzip2에서 -cstdout으로 표준 출력방식을 사용하여 해당 경로에 저장하지 않기 위해 사용합니다.

 

 

압축된 파일은 > ${LOGDIR}/${NAMES [$index]}/${NOW}. bz2에 의해

세 번째 분기에서 생성된 각 컨테이너의 컨테이너명 폴더로 저장됩니다.

 

 

 

Result example:

# 저장된 로그 파일 위치
/home/yankee/backups/docker-logs/overmap/2019-08-08.bz2

 

 

이제 이것을 vim /etc/crontab 에 작성해주면 매일매일 작업을 하니 일주일에 한 번씩 

압축 로그 받으러 가면 될 것 같네요.

 

0 *     * * *   root    /home/yankee/scheduler/docker-logger.sh
# 매일 자정에 root 권한으로 /home/yankee/scheduler 위치에 docker-logger.sh 를 실행

 

728x90