이미지 로딩 중...

로그 로테이션과 아카이빙 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 11. 18. · 4 Views

로그 로테이션과 아카이빙 완벽 가이드

서버 로그가 무한정 쌓여서 디스크 공간이 부족해진 경험, 누구나 한 번쯤은 있으시죠? 로그 로테이션과 아카이빙을 제대로 설정하면 디스크 공간도 절약하고, 필요한 로그는 안전하게 보관할 수 있습니다. 실무에서 바로 쓸 수 있는 로그 관리 노하우를 알려드립니다.


목차

  1. 로그_로테이션_개념
  2. 날짜별_로그_압축
  3. 오래된_로그_자동_삭제
  4. 디스크_공간_모니터링
  5. logrotate_통합
  6. 백업_스토리지_연동

1. 로그_로테이션_개념

시작하며

여러분의 서버가 매일 수백 MB의 로그를 생성한다고 상상해보세요. 처음엔 별 문제가 없지만, 몇 달이 지나면 디스크 공간이 꽉 차서 서버가 멈춰버리는 상황이 발생합니다.

심지어 중요한 애플리케이션이 더 이상 로그를 쓸 수 없어서 오류 추적도 불가능해지죠. 이런 문제는 로그를 관리하지 않고 방치했을 때 생기는 대표적인 상황입니다.

로그 파일은 시간이 지날수록 계속 커지기 때문에, 적절히 나누고 정리하지 않으면 시스템 전체에 심각한 영향을 미칩니다. 바로 이럴 때 필요한 것이 로그 로테이션입니다.

로그 로테이션은 마치 노트를 다 쓰면 새 노트를 꺼내 쓰는 것처럼, 로그 파일이 일정 크기나 기간에 도달하면 자동으로 새 파일로 교체해주는 똑똑한 시스템입니다.

개요

간단히 말해서, 로그 로테이션은 하나의 로그 파일이 너무 커지지 않도록 주기적으로 새 파일로 교체하는 과정입니다. 왜 이게 필요할까요?

실무에서는 웹 서버, 데이터베이스, 애플리케이션 등이 24시간 쉬지 않고 로그를 기록합니다. 만약 application.log라는 파일 하나에 모든 로그를 계속 쌓는다면, 그 파일은 몇 GB를 넘어 수십 GB까지 커질 수 있습니다.

이렇게 큰 파일은 열어보기도 어렵고, 검색도 느리며, 백업하기도 힘듭니다. 기존에는 개발자가 직접 스크립트를 만들어서 수동으로 로그 파일을 옮기고 이름을 바꿔야 했다면, 이제는 로그 로테이션 시스템을 설정해두면 자동으로 처리됩니다.

로그 로테이션의 핵심 특징은 크게 세 가지입니다. 첫째, 시간 기반 또는 크기 기반으로 파일을 자동 분할합니다.

둘째, 오래된 로그는 압축해서 저장 공간을 절약합니다. 셋째, 일정 기간이 지난 로그는 자동으로 삭제하여 디스크 공간을 확보합니다.

이러한 특징들 덕분에 여러분은 로그 관리에 신경 쓰지 않고도 안정적인 시스템을 운영할 수 있습니다.

코드 예제

# 로그 로테이션 기본 설정 예제 (/etc/logrotate.d/myapp)

/var/log/myapp/*.log {
    daily                    # 매일 로테이션 수행
    rotate 7                 # 최근 7개 파일만 보관
    compress                 # 오래된 로그는 gzip으로 압축
    delaycompress           # 가장 최근 로그는 압축하지 않음
    missingok               # 로그 파일이 없어도 에러 발생 안 함
    notifempty              # 빈 파일은 로테이션하지 않음
    create 0640 www-data adm  # 새 로그 파일 생성 시 권한 설정
    sharedscripts           # 여러 로그에 대해 스크립트를 한 번만 실행
    postrotate
        systemctl reload nginx > /dev/null  # 로테이션 후 nginx 재시작
    endscript
}

설명

이것이 하는 일: 위 설정 파일은 /var/log/myapp/ 디렉토리의 모든 로그 파일에 대해 매일 자동으로 로테이션을 수행하도록 지시합니다. 첫 번째로, daily와 rotate 7 옵션은 매일 자정에 로그 파일을 새로 만들고, 최근 7일치만 보관하도록 합니다.

즉, application.log는 application.log.1, application.log.2... 이런 식으로 이름이 바뀌면서 보관되고, 8일째 되는 로그는 자동으로 삭제됩니다.

이렇게 하면 항상 일주일치 로그만 유지되어 디스크 공간을 예측 가능하게 관리할 수 있습니다. 두 번째로, compress와 delaycompress가 실행되면서 오래된 로그 파일들은 gzip으로 압축됩니다.

예를 들어 application.log.2는 application.log.2.gz로 압축되어 저장 공간이 90% 이상 줄어듭니다. 다만 가장 최근 로그(application.log.1)는 압축하지 않아서, 급하게 확인할 때 압축 해제 없이 바로 볼 수 있습니다.

세 번째 단계로, postrotate 섹션이 실행됩니다. 로그 파일이 교체된 후에는 nginx 같은 애플리케이션에 reload 신호를 보내서 새 로그 파일에 기록하도록 합니다.

이 과정이 없으면 애플리케이션이 여전히 옛날 로그 파일에 쓰려고 시도해서 로그가 누락될 수 있습니다. 여러분이 이 설정을 사용하면 로그 관리에 손 하나 까딱하지 않아도 됩니다.

디스크 공간은 항상 일정하게 유지되고, 필요한 로그는 언제든 찾아볼 수 있으며, 오래된 로그는 자동으로 정리됩니다. 특히 운영 환경에서는 이런 자동화가 시스템 안정성을 크게 높여줍니다.

실전 팁

💡 로테이션 주기는 로그 생성량에 따라 조절하세요. 트래픽이 많은 서비스는 hourly(시간별)로 설정하는 것이 좋고, 작은 서비스는 weekly(주별)로도 충분합니다.

💡 rotate 숫자를 너무 작게 설정하면 나중에 필요한 로그를 찾을 수 없습니다. 최소 7일, 가능하면 30일 이상 보관하는 것을 추천합니다. 규정이나 법적 요구사항이 있다면 그에 맞춰 설정하세요.

💡 compress 옵션은 반드시 켜두세요. 텍스트 로그는 압축률이 90% 이상이라 디스크 공간을 엄청나게 절약할 수 있습니다. 다만 CPU 사용량이 약간 증가하므로, 매우 바쁜 서버라면 로테이션 시간을 새벽으로 조정하세요.

💡 설정 파일을 수정한 후에는 logrotate -d /etc/logrotate.d/myapp 명령으로 테스트해보세요. -d 옵션은 실제로 실행하지 않고 어떤 작업이 일어날지만 보여줍니다. 실수를 미리 잡을 수 있어서 안전합니다.

💡 postrotate 스크립트에서 애플리케이션을 restart가 아닌 reload로 하세요. restart는 서비스가 잠시 멈추지만, reload는 무중단으로 설정을 다시 읽어서 사용자에게 영향을 주지 않습니다.


2. 날짜별_로그_압축

시작하며

여러분의 서버에 한 달치 로그가 쌓여 있는데, 각 로그 파일이 500MB씩이라면 총 15GB가 넘는 공간을 차지합니다. 이런 로그들을 나중에 분석하려고 보관하고 싶지만, 디스크 공간은 한정되어 있어서 고민이 되는 상황이죠.

실무에서는 법적 요구사항이나 보안 정책 때문에 로그를 일정 기간 보관해야 하는 경우가 많습니다. 하지만 원본 그대로 보관하면 저장 비용이 너무 많이 들고, 백업 시간도 오래 걸립니다.

바로 이럴 때 필요한 것이 날짜별 로그 압축입니다. 오래된 로그를 날짜별로 깔끔하게 정리하고 압축하면, 저장 공간은 10분의 1로 줄이면서도 필요할 때 언제든 압축을 풀어 확인할 수 있습니다.

개요

간단히 말해서, 날짜별 로그 압축은 매일 생성되는 로그 파일을 날짜가 포함된 이름으로 보관하고 자동으로 압축하는 프로세스입니다. 왜 날짜별로 구분해야 할까요?

로그를 분석할 때는 대부분 "지난주 화요일에 무슨 일이 있었지?" 같은 식으로 특정 날짜의 로그를 찾게 됩니다. 날짜가 파일명에 포함되어 있으면 app-2025-11-15.log.gz처럼 한눈에 알아보기 쉽고, 필요한 날짜의 로그만 빠르게 찾을 수 있습니다.

기존에는 로그를 번호로만 구분했다면(app.log.1, app.log.2), 이제는 의미 있는 날짜로 구분합니다. 이렇게 하면 3개월 전 로그를 찾을 때 몇 번 파일인지 계산할 필요 없이 바로 2025-08-15.log.gz를 열어보면 됩니다.

핵심 특징은 세 가지입니다. 첫째, dateext 옵션으로 파일명에 날짜를 자동으로 붙입니다.

둘째, 오래된 로그는 gzip, bzip2, xz 등 다양한 압축 방식으로 저장할 수 있습니다. 셋째, 압축 레벨을 조절해서 압축률과 속도의 균형을 맞출 수 있습니다.

이런 기능들 덕분에 로그를 체계적으로 관리하면서도 저장 비용을 대폭 절감할 수 있습니다.

코드 예제

# 날짜별 로그 압축 설정 예제

/var/log/app/application.log {
    daily                           # 매일 로테이션
    dateext                         # 파일명에 날짜 추가
    dateformat -%Y-%m-%d           # 날짜 형식: -2025-11-18
    rotate 90                       # 90일치 보관
    compress                        # 압축 활성화
    compresscmd /usr/bin/gzip      # gzip 사용
    compressoptions -9             # 최대 압축률 적용
    compressext .gz                # 압축 파일 확장자
    delaycompress                  # 가장 최근 파일은 압축 안 함
    notifempty                     # 빈 파일은 무시
    create 0640 app app            # 새 파일 권한과 소유자
}

설명

이것이 하는 일: 위 설정은 매일 자정에 로그를 로테이션하면서 파일명에 날짜를 붙이고, 하루가 지난 로그는 최대 압축률로 압축해서 보관합니다. 첫 번째로, dateext와 dateformat 옵션이 작동합니다.

application.log가 로테이션될 때, application.log-2025-11-18처럼 오늘 날짜가 자동으로 붙습니다. 다음 날이 되면 application.log-2025-11-19가 만들어지죠.

이렇게 하면 3개월 뒤에도 "아, 11월 18일 로그가 필요해"라고 하면 바로 해당 파일을 찾을 수 있습니다. 두 번째로, compress와 관련된 옵션들이 실행됩니다.

compresscmd는 어떤 압축 프로그램을 쓸지 지정하는데, gzip이 가장 흔하게 쓰입니다. compressoptions -9는 압축률을 최대로 설정하는 옵션으로, 시간은 조금 더 걸리지만 파일 크기를 최소화합니다.

500MB 로그 파일이 30-50MB로 줄어드는 마법을 경험할 수 있습니다. 세 번째로, delaycompress 옵션이 중요한 역할을 합니다.

어제 생성된 로그(application.log-2025-11-17)는 아직 압축하지 않고 원본 상태로 둡니다. 왜냐하면 최근 로그는 문제가 생겼을 때 자주 확인하기 때문에, 압축을 풀었다 다시 압축하는 수고를 덜기 위해서입니다.

그 전날 로그(application.log-2025-11-16)부터는 .gz로 압축됩니다. 여러분이 이 설정을 적용하면 로그 관리가 정말 편해집니다.

장애 분석을 할 때 "2주 전 수요일 로그 좀 보자"라고 하면 application.log-2025-11-05.gz를 바로 찾아서 zcat이나 zgrep으로 압축을 풀지 않고도 내용을 확인할 수 있습니다. 또한 90일치 로그를 보관해도 압축 덕분에 디스크 공간은 5-10GB 정도만 차지합니다.

실전 팁

💡 dateformat은 프로젝트 전체에서 통일하세요. 어떤 로그는 -%Y%m%d, 어떤 로그는 -%Y-%m-%d로 되어 있으면 나중에 스크립트로 처리할 때 헷갈립니다. -%Y-%m-%d 형식을 추천합니다.

💡 compressoptions -9는 최대 압축이지만 CPU를 많이 씁니다. 로그 생성량이 아주 많다면 -6 정도로 낮춰서 압축 시간을 줄이세요. 압축률 차이는 5-10% 정도지만, 속도는 2-3배 빨라집니다.

💡 압축된 로그를 검색할 때는 zgrep, zcat 명령어를 사용하세요. zgrep "ERROR" application.log-2025-11-15.gz처럼 압축을 풀지 않고도 바로 검색할 수 있어서 편리합니다.

💡 rotate 90은 90일치 보관이라는 뜻입니다. 회사의 로그 보관 정책을 확인하세요. 금융권은 1년 이상, 일반 서비스는 30-90일이 일반적입니다. 법적 문제를 피하려면 정책에 맞춰 설정해야 합니다.

💡 bzip2나 xz 압축도 고려해보세요. gzip보다 압축률이 10-20% 더 좋지만, 압축/해제 시간은 2-5배 느립니다. 장기 보관용 로그라면 xz를 쓰고, 자주 확인하는 로그라면 gzip을 쓰는 것이 좋습니다.


3. 오래된_로그_자동_삭제

시작하며

여러분의 서버에 3년치 로그가 쌓여 있다면, 그중에서 실제로 필요한 로그는 얼마나 될까요? 대부분의 경우 최근 1-3개월 로그만 있으면 충분하고, 그 이전 로그는 거의 열어보지 않습니다.

하지만 자동 삭제 설정이 없다면 이 로그들이 계속 쌓여서 수백 GB를 차지하게 됩니다. 더 큰 문제는 디스크가 꽉 찼을 때입니다.

갑자기 서버가 응답하지 않아서 확인해보니 디스크 사용률이 100%에 도달해서 아무 작업도 할 수 없는 상황이 됩니다. 이런 긴급 상황에서 수동으로 로그를 삭제하느라 귀중한 시간을 낭비하게 되죠.

바로 이럴 때 필요한 것이 오래된 로그 자동 삭제입니다. 보관 기간을 정해두고 그 이상 된 로그는 자동으로 삭제되도록 설정하면, 디스크 공간을 항상 일정하게 유지하면서도 필요한 로그는 안전하게 보관할 수 있습니다.

개요

간단히 말해서, 오래된 로그 자동 삭제는 지정한 기간이 지난 로그 파일을 시스템이 자동으로 찾아서 삭제하는 프로세스입니다. 왜 이게 중요할까요?

서버는 24시간 365일 로그를 생성합니다. 한 달에 10GB씩 로그가 쌓인다면 1년이면 120GB, 3년이면 360GB입니다.

클라우드 환경에서는 이런 저장 공간이 매달 비용으로 청구되고, 온프레미스에서는 디스크 용량 부족으로 시스템 장애가 발생할 수 있습니다. 기존에는 관리자가 매달 로그인해서 "이 로그는 6개월 됐네, 삭제하자"라고 수동으로 처리했다면, 이제는 한 번 설정해두면 시스템이 알아서 관리합니다.

핵심 특징은 세 가지입니다. 첫째, maxage 옵션으로 일수 기준으로 자동 삭제합니다.

둘째, rotate 숫자와 조합해서 개수 기준으로도 관리할 수 있습니다. 셋째, 삭제 전에 백업 스토리지로 이동하는 스크립트를 연동할 수도 있습니다.

이런 기능들 덕분에 저장 공간을 효율적으로 사용하면서도 중요한 로그를 잃어버릴 걱정이 없습니다.

코드 예제

# 오래된 로그 자동 삭제 설정

/var/log/app/*.log {
    daily
    rotate 30                    # 최근 30개 파일만 유지
    maxage 90                    # 90일 이상 된 파일은 강제 삭제
    dateext
    compress
    delaycompress
    notifempty
    missingok
    sharedscripts
    prerotate
        # 삭제 전에 오래된 로그를 백업 스토리지로 이동
        find /var/log/app/ -name "*.log.*.gz" -mtime +60 -exec \
            mv {} /backup/old-logs/ \; 2>/dev/null || true
    endscript
}

설명

이것이 하는 일: 위 설정은 매일 로그를 로테이션하면서 30개 파일 또는 90일 이상 된 로그를 자동으로 삭제하고, 그 전에 60일 이상 된 로그는 백업 위치로 이동합니다. 첫 번째로, rotate 30과 maxage 90이 함께 작동합니다.

rotate 30은 "최근 30개 파일만 유지"라는 뜻이고, maxage 90은 "90일 이상 된 파일은 무조건 삭제"라는 뜻입니다. 이 두 옵션 중 하나라도 조건을 만족하면 파일이 삭제됩니다.

예를 들어 로그가 너무 많아서 25일 만에 30개가 찼다면, 25일째 로그도 삭제되고, 로그가 적어서 30개가 50일치라면 50일째 로그는 유지됩니다. 두 번째로, prerotate 스크립트가 실행됩니다.

이 스크립트는 로테이션이 일어나기 직전에 실행되며, find 명령으로 60일 이상 된 압축 로그를 찾아서 /backup/old-logs/ 디렉토리로 이동합니다. -mtime +60은 "60일보다 오래된 파일"을 의미하고, -exec mv로 찾은 파일들을 모두 옮깁니다.

2>/dev/null은 에러 메시지를 숨기고, || true는 파일이 없어도 스크립트가 실패하지 않게 합니다. 세 번째로, 백업된 파일들은 안전하게 보관되고, 나머지 로그들은 maxage에 따라 삭제됩니다.

즉, 0-60일 로그는 원본 위치에 그대로, 60-90일 로그는 백업 위치로 이동, 90일 이상 로그는 완전히 삭제되는 3단계 관리 체계가 만들어집니다. 여러분이 이 설정을 사용하면 디스크 공간 걱정에서 해방됩니다.

운영 서버의 디스크 사용률은 항상 예측 가능한 수준으로 유지되고, 혹시 모를 문제 분석을 위해 중요한 로그는 백업 스토리지에 안전하게 보관됩니다. 클라우드 환경이라면 오래된 로그를 S3 Glacier 같은 저렴한 스토리지로 옮겨서 비용을 더욱 절감할 수도 있습니다.

실전 팁

💡 maxage와 rotate를 함께 사용하세요. maxage만 쓰면 로그가 너무 많을 때 대응이 안 되고, rotate만 쓰면 날짜 기준 관리가 안 됩니다. 둘을 조합하면 완벽한 안전망이 됩니다.

💡 백업 스크립트에서 mv 대신 cp를 쓰는 것도 고려해보세요. mv는 파일을 이동시켜서 원본이 사라지지만, cp는 복사본을 만들어서 혹시 모를 문제에 대비할 수 있습니다. 다만 디스크 공간을 2배로 쓰므로 상황에 맞게 선택하세요.

💡 삭제 전에 확인하는 습관을 들이세요. logrotate -d 명령으로 어떤 파일들이 삭제될지 미리 확인할 수 있습니다. 중요한 로그를 실수로 삭제하는 것을 방지할 수 있습니다.

💡 삭제된 로그는 복구할 수 없습니다. 법적 요구사항이나 회사 정책을 반드시 확인하세요. 금융, 의료, 공공 분야는 1-7년 보관 의무가 있을 수 있습니다.

💡 cron으로 주기적인 정리 작업을 추가하세요. logrotate만으로는 놓칠 수 있는 임시 로그나 비정상 로그를 find /var/log -name ".log." -mtime +180 -delete로 정리하면 더욱 안전합니다.


4. 디스크_공간_모니터링

시작하며

여러분이 아침에 출근해서 서버를 확인했는데 디스크 사용률이 95%라는 경고를 보게 됩니다. 어제까지만 해도 70%였는데 갑자기 무슨 일이 생긴 걸까요?

급하게 로그 파일들을 확인해보니 어제 밤에 에러가 반복되면서 로그가 폭증했고, 자동 삭제 설정이 미처 따라가지 못한 상황입니다. 이런 상황은 실무에서 정말 자주 발생합니다.

로그 로테이션을 아무리 잘 설정해도 예상치 못한 에러나 트래픽 급증으로 로그가 갑자기 늘어날 수 있습니다. 문제는 디스크가 100%에 도달하면 시스템 전체가 먹통이 되어버린다는 점입니다.

바로 이럴 때 필요한 것이 디스크 공간 모니터링입니다. 미리 정해둔 임계값을 넘으면 자동으로 경고를 보내고, 긴급 상황에서는 오래된 로그를 즉시 삭제해서 시스템을 보호하는 안전장치 역할을 합니다.

개요

간단히 말해서, 디스크 공간 모니터링은 로그 디렉토리와 파티션의 사용률을 주기적으로 확인하고, 위험 수준에 도달하면 관리자에게 알리거나 자동으로 대응하는 시스템입니다. 왜 로테이션만으로는 부족할까요?

로테이션은 정해진 스케줄대로 작동하지만, 갑작스러운 상황에는 대응할 수 없습니다. 예를 들어 애플리케이션 버그로 1시간에 10GB 로그가 쌓인다면, 다음 로테이션 시간까지 기다리는 동안 디스크가 꽉 찰 수 있습니다.

모니터링은 이런 비정상 상황을 실시간으로 감지합니다. 기존에는 관리자가 가끔씩 df -h 명령으로 수동 확인했다면, 이제는 모니터링 스크립트가 5분마다 자동으로 체크하고, 문제가 생기면 즉시 슬랙, 이메일, SMS로 알려줍니다.

핵심 특징은 네 가지입니다. 첫째, 임계값 기반 경고로 80%, 90%, 95% 같은 단계별 알림을 설정할 수 있습니다.

둘째, 자동 정리 기능으로 위험 수준에서는 강제로 오래된 로그를 삭제합니다. 셋째, 로그별 사용량 추적으로 어떤 로그가 공간을 많이 차지하는지 파악할 수 있습니다.

넷째, 히스토리 트렌드로 디스크 증가 추세를 예측할 수 있습니다. 이런 기능들 덕분에 디스크 부족으로 인한 장애를 사전에 예방할 수 있습니다.

코드 예제

#!/bin/bash
# 디스크 공간 모니터링 스크립트 (/usr/local/bin/monitor-disk.sh)

LOG_DIR="/var/log/app"
THRESHOLD_WARNING=80      # 경고 임계값 80%
THRESHOLD_CRITICAL=90     # 위험 임계값 90%
THRESHOLD_EMERGENCY=95    # 긴급 임계값 95%

# 현재 디스크 사용률 확인
USAGE=$(df -h $LOG_DIR | tail -1 | awk '{print $5}' | sed 's/%//')

if [ $USAGE -ge $THRESHOLD_EMERGENCY ]; then
    # 긴급: 30일 이상 로그 즉시 삭제
    echo "EMERGENCY: Disk usage $USAGE%. Cleaning old logs..."
    find $LOG_DIR -name "*.log.*.gz" -mtime +30 -delete
    logger -t disk-monitor "Emergency cleanup: deleted logs older than 30 days"
elif [ $USAGE -ge $THRESHOLD_CRITICAL ]; then
    # 위험: 60일 이상 로그 삭제
    echo "CRITICAL: Disk usage $USAGE%. Cleaning logs..."
    find $LOG_DIR -name "*.log.*.gz" -mtime +60 -delete
    logger -t disk-monitor "Critical cleanup: deleted logs older than 60 days"
elif [ $USAGE -ge $THRESHOLD_WARNING ]; then
    # 경고: 알림만 전송
    echo "WARNING: Disk usage $USAGE%"
    logger -t disk-monitor "Warning: disk usage at $USAGE%"
fi

설명

이것이 하는 일: 위 스크립트는 /var/log/app 디렉토리의 디스크 사용률을 확인하고, 80%, 90%, 95% 임계값에 따라 다른 수준의 대응을 자동으로 수행합니다. 첫 번째로, df -h 명령으로 현재 디스크 사용률을 확인합니다.

tail -1은 헤더를 제외한 실제 데이터 라인만 가져오고, awk '{print $5}'는 사용률 컬럼(예: 87%)을 추출하고, sed 's/%//'는 퍼센트 기호를 제거해서 숫자만 남깁니다. 이렇게 하면 USAGE 변수에 87 같은 숫자가 저장되어 조건문에서 비교할 수 있습니다.

두 번째로, if-elif 조건문이 실행됩니다. 가장 위험한 상황부터 체크하는 것이 중요합니다.

사용률이 95% 이상이면 긴급 상황으로 판단하고, find 명령으로 30일 이상 된 압축 로그를 모두 삭제합니다. -delete 옵션은 찾은 파일을 즉시 삭제하는 강력한 옵션입니다.

90% 이상이면 60일 기준으로, 80% 이상이면 경고만 남깁니다. 세 번째로, logger 명령이 시스템 로그에 기록을 남깁니다.

-t disk-monitor는 로그에 태그를 붙여서 나중에 grep으로 쉽게 찾을 수 있게 합니다. 이렇게 하면 "언제 디스크 정리가 자동으로 실행됐는지" 추적할 수 있어서, 나중에 문제 분석이나 용량 계획을 세울 때 유용합니다.

여러분이 이 스크립트를 cron에 등록해서 5분마다 실행하면, 디스크 폭증 상황에서도 시스템이 자동으로 대응합니다. 예를 들어 */5 * * * * /usr/local/bin/monitor-disk.sh로 cron에 등록하면, 디스크가 95%에 도달해도 5분 안에 감지되고 자동으로 정리되어 시스템 중단을 막을 수 있습니다.

또한 알림을 이메일이나 슬랙으로 보내도록 확장하면, 잠을 자고 있을 때도 문제를 바로 알 수 있습니다.

실전 팁

💡 임계값은 3단계 이상으로 설정하세요. 경고(80%), 위험(90%), 긴급(95%)처럼 단계를 나누면 상황에 맞는 대응이 가능합니다. 한 번에 다 삭제하는 것보다 단계적으로 대응하는 게 안전합니다.

💡 삭제 전에 반드시 백업하세요. 스크립트에 삭제 명령 전에 tar -czf /backup/emergency-$(date +%F).tar.gz $LOG_DIR/*.gz 같은 백업 명령을 추가하면, 나중에 필요할 때 복구할 수 있습니다.

💡 알림 기능을 추가하세요. echo 대신 mail -s "Disk Warning" admin@company.com이나 curl로 슬랙 웹훅을 호출하면, 관리자가 즉시 알 수 있습니다. 긴급 상황은 SMS로 보내는 것도 좋습니다.

💡 cron 실행 주기를 용량 증가 속도에 맞추세요. 트래픽이 많은 서버는 */5(5분마다), 작은 서버는 0 */2(2시간마다)로 설정하면 리소스를 절약하면서도 안전합니다.

💡 모니터링 데이터를 수집해서 그래프로 만드세요. Grafana나 CloudWatch 같은 도구와 연동하면 디스크 사용 트렌드를 시각화할 수 있고, "이 속도면 2주 후에 디스크가 찰 것 같다"같은 예측이 가능합니다.


5. logrotate_통합

시작하며

여러분이 지금까지 배운 로그 로테이션, 압축, 삭제, 모니터링을 모두 따로따로 스크립트로 만들어서 관리한다면 어떻게 될까요? 각 스크립트의 설정이 충돌할 수도 있고, 어떤 스크립트가 언제 실행되는지 추적하기도 어렵습니다.

유지보수도 힘들고, 새로운 팀원이 오면 이해시키기도 복잡하죠. 실무에서는 수십 개의 애플리케이션이 각각 여러 개의 로그 파일을 생성합니다.

웹 서버 로그, 애플리케이션 로그, 데이터베이스 로그, 시스템 로그 등 관리해야 할 로그가 너무 많아집니다. 각각을 별도로 관리하는 것은 현실적으로 불가능합니다.

바로 이럴 때 필요한 것이 logrotate 통합입니다. 리눅스에 기본으로 설치된 logrotate는 모든 로그 관리 작업을 하나의 체계로 통합해서, 설정 파일만 작성하면 나머지는 알아서 처리해주는 강력한 도구입니다.

개요

간단히 말해서, logrotate 통합은 시스템의 모든 로그 파일을 하나의 중앙 관리 시스템으로 묶어서, 일관된 정책으로 자동 관리하는 방식입니다. 왜 logrotate를 써야 할까요?

logrotate는 1990년대부터 사용된 검증된 도구로, 거의 모든 리눅스 배포판에 기본 설치되어 있습니다. 직접 스크립트를 만드는 것보다 안정적이고, 예외 처리도 잘 되어 있으며, 커뮤니티에서 수많은 사용 사례와 해결책이 공유됩니다.

새로운 기능이 필요하면 플러그인 형태로 추가할 수도 있습니다. 기존에는 여러 개의 쉘 스크립트와 cron 작업으로 흩어져 있던 로그 관리를, 이제는 /etc/logrotate.d/ 디렉토리 안의 설정 파일들로 모두 관리합니다.

핵심 특징은 다섯 가지입니다. 첫째, 선언적 설정으로 "무엇을 할지"만 정의하면 "어떻게 할지"는 logrotate가 알아서 합니다.

둘째, 전역 설정과 개별 설정을 분리해서 공통 정책과 특수 정책을 함께 관리할 수 있습니다. 셋째, 스크립트 훅(prerotate, postrotate)으로 로테이션 전후에 커스텀 작업을 실행할 수 있습니다.

넷째, 에러 처리가 견고해서 문제가 생겨도 시스템이 멈추지 않습니다. 다섯째, 상태 파일(/var/lib/logrotate/status)로 마지막 로테이션 시간을 추적합니다.

이런 기능들 덕분에 엔터프라이즈급 로그 관리를 간단히 구현할 수 있습니다.

코드 예제

# /etc/logrotate.conf - 전역 설정
# 모든 로그에 공통 적용되는 기본 정책

weekly                  # 기본은 주간 로테이션
rotate 4                # 기본 4주치 보관
create                  # 로테이션 후 새 파일 자동 생성
dateext                 # 날짜 확장자 사용
compress               # 압축 활성화

# 개별 애플리케이션 설정 포함
include /etc/logrotate.d

# /etc/logrotate.d/myapp - 애플리케이션별 설정
/var/log/myapp/*.log {
    daily               # 전역 설정을 덮어씀: 매일 로테이션
    rotate 30
    compress
    delaycompress
    notifempty
    create 0640 myapp myapp
    sharedscripts
    postrotate
        systemctl reload myapp
    endscript
}

설명

이것이 하는 일: logrotate는 전역 설정 파일(/etc/logrotate.conf)에서 기본 정책을 정의하고, /etc/logrotate.d/ 디렉토리의 개별 설정들을 모두 로드해서 각 로그 파일에 맞는 정책을 적용합니다. 첫 번째로, 전역 설정이 읽힙니다.

/etc/logrotate.conf에서 weekly, rotate 4, compress 같은 기본값을 정의합니다. 이 값들은 모든 로그 파일에 적용되는 "기본 정책"입니다.

만약 개별 설정 파일에서 특정 옵션을 지정하지 않으면, 이 전역 값이 사용됩니다. 예를 들어 압축 여부를 설정하지 않은 로그는 자동으로 compress가 적용됩니다.

두 번째로, include /etc/logrotate.d 지시어가 해당 디렉토리의 모든 설정 파일을 읽어옵니다. 이 디렉토리에는 nginx, mysql, myapp 등 각 애플리케이션별 설정이 별도 파일로 저장되어 있습니다.

이렇게 분리하면 애플리케이션을 추가하거나 삭제할 때 해당 설정 파일만 넣거나 빼면 되어서 관리가 쉽습니다. 세 번째로, 개별 설정이 전역 설정을 덮어씁니다.

/etc/logrotate.d/myapp에서 daily를 지정하면, 전역 설정의 weekly가 아닌 daily가 적용됩니다. 이런 우선순위 시스템 덕분에 공통 정책은 전역에서 관리하고, 특수한 요구사항은 개별로 처리할 수 있습니다.

네 번째로, logrotate는 매일 새벽(보통 3-4시경) cron에 의해 자동 실행됩니다. /etc/cron.daily/logrotate 스크립트가 logrotate를 호출하면, 모든 설정 파일을 읽어서 "오늘 로테이션할 파일이 뭔가?"를 확인하고 작업을 수행합니다.

상태 파일(/var/lib/logrotate/status)에는 각 로그의 마지막 로테이션 시간이 기록되어 있어서, 중복 실행을 방지합니다. 여러분이 logrotate를 제대로 설정하면, 새로운 애플리케이션을 추가할 때 /etc/logrotate.d/에 설정 파일 하나만 만들면 끝입니다.

압축, 삭제, 백업, 알림 등 모든 기능이 일관되게 작동하고, 팀 전체가 같은 방식으로 로그를 관리할 수 있어서 협업도 쉬워집니다.

실전 팁

💡 설정 파일은 애플리케이션별로 분리하세요. /etc/logrotate.d/nginx, /etc/logrotate.d/mysql처럼 나누면 나중에 특정 앱만 수정하기 쉽고, 버전 관리도 깔끔합니다.

💡 테스트는 logrotate -d /etc/logrotate.d/myapp로 하세요. -d 옵션은 실제로 실행하지 않고 시뮬레이션만 해서, 어떤 파일이 어떻게 처리될지 미리 보여줍니다. 실수를 미리 잡을 수 있어서 안전합니다.

💡 강제 실행은 logrotate -f로 하세요. 테스트가 끝나고 당장 로테이션을 실행하고 싶을 때 -f 옵션을 쓰면, 마지막 로테이션 시간과 관계없이 즉시 실행됩니다. 설정을 바꾼 직후 확인할 때 유용합니다.

💡 전역 설정은 최소한으로 유지하세요. 너무 많은 것을 전역에 넣으면 나중에 예외를 만들기 어렵습니다. compress, dateext 정도만 전역에 두고, 나머지는 개별 설정에서 명시하는 것이 안전합니다.

💡 상태 파일을 정기적으로 확인하세요. cat /var/lib/logrotate/status로 각 로그의 마지막 로테이션 시간을 보면, "이 로그는 왜 3일째 로테이션이 안 됐지?" 같은 문제를 발견할 수 있습니다.


6. 백업_스토리지_연동

시작하며

여러분이 3개월 전 로그를 찾아야 하는데, 로컬 서버에는 30일치만 있다면 어떻게 할까요? 자동 삭제 설정 때문에 이미 사라진 로그를 복구할 방법이 없어서 중요한 분석을 할 수 없는 상황이 됩니다.

특히 보안 감사나 법적 조사가 필요할 때 "로그가 삭제됐습니다"라고 말할 수는 없습니다. 더 큰 문제는 하드웨어 장애입니다.

서버의 디스크가 갑자기 고장나면 모든 로그가 한순간에 사라집니다. 백업이 없다면 장애 원인 분석도, 복구 시점 파악도 불가능합니다.

바로 이럴 때 필요한 것이 백업 스토리지 연동입니다. 로컬에서는 최근 로그만 유지하고, 오래된 로그는 S3, Google Cloud Storage, NAS 같은 안전한 백업 스토리지로 자동으로 옮겨서 장기 보관하는 전략입니다.

개요

간단히 말해서, 백업 스토리지 연동은 로테이션된 로그 파일을 자동으로 클라우드나 별도 스토리지로 업로드해서 안전하게 장기 보관하는 시스템입니다. 왜 백업이 필수일까요?

실무에서는 로그 보관 의무가 법으로 정해진 경우가 많습니다. 금융권은 5-7년, 의료는 10년 이상 보관해야 합니다.

하지만 운영 서버에 몇 년치 로그를 모두 저장하면 디스크 비용이 엄청나게 증가합니다. 클라우드 스토리지를 사용하면 GB당 월 $0.01 수준으로 저렴하게 장기 보관할 수 있습니다.

기존에는 관리자가 주기적으로 로그를 수동으로 다운로드해서 외장 하드에 저장했다면, 이제는 logrotate의 postrotate 스크립트로 S3 같은 클라우드 스토리지에 자동 업로드됩니다. 핵심 특징은 네 가지입니다.

첫째, 스토리지 계층화로 최근 로그는 고속 디스크에, 오래된 로그는 저렴한 스토리지에 보관합니다. 둘째, 자동 암호화로 민감한 로그를 안전하게 보호합니다.

셋째, 버전 관리로 실수로 덮어쓴 파일도 복구할 수 있습니다. 넷째, 검색 가능한 아카이브로 필요한 로그를 빠르게 찾을 수 있습니다.

이런 기능들 덕분에 규정 준수, 비용 절감, 데이터 보호를 모두 달성할 수 있습니다.

코드 예제

#!/bin/bash
# S3 백업 스크립트 (/usr/local/bin/backup-logs-to-s3.sh)

S3_BUCKET="s3://my-company-logs"
LOG_DIR="/var/log/myapp"
RETENTION_DAYS=7  # 로컬은 7일만 보관

# 7일 이상 된 압축 로그를 S3로 업로드
find $LOG_DIR -name "*.log.*.gz" -mtime +$RETENTION_DAYS | while read logfile; do
    # 파일명에서 날짜 추출
    filename=$(basename $logfile)
    date_part=$(echo $filename | grep -oP '\d{4}-\d{2}-\d{2}')

    # S3 경로 생성: year=2025/month=11/day=18/
    s3_path="$S3_BUCKET/year=${date_part:0:4}/month=${date_part:5:2}/day=${date_part:8:2}/"

    # S3로 업로드 (서버 사이드 암호화 적용)
    aws s3 cp "$logfile" "$s3_path" \
        --storage-class STANDARD_IA \
        --server-side-encryption AES256

    # 업로드 성공하면 로컬 파일 삭제
    if [ $? -eq 0 ]; then
        rm "$logfile"
        echo "Backed up and removed: $logfile"
    fi
done

설명

이것이 하는 일: 위 스크립트는 7일 이상 된 압축 로그 파일을 찾아서 AWS S3에 날짜별 폴더 구조로 업로드하고, 업로드가 성공하면 로컬 파일을 삭제합니다. 첫 번째로, find 명령이 실행됩니다.

$LOG_DIR에서 -name ".log..gz" 패턴에 맞고 -mtime +7(7일보다 오래된) 파일들을 모두 찾습니다. while read logfile로 찾은 파일들을 하나씩 순회하면서 처리합니다.

이렇게 하면 한 번에 수백 개 파일도 자동으로 처리할 수 있습니다. 두 번째로, 파일명에서 날짜를 추출해서 S3 경로를 만듭니다.

grep -oP '\d{4}-\d{2}-\d{2}'는 파일명에서 2025-11-18 형식의 날짜를 찾아냅니다. 그 다음 ${date_part:0:4}는 문자열의 0번째부터 4글자(2025), ${date_part:5:2}는 5번째부터 2글자(11)를 추출해서 year=2025/month=11/day=18/ 같은 폴더 구조를 만듭니다.

이렇게 하면 나중에 "2025년 11월 18일 로그"를 쉽게 찾을 수 있습니다. 세 번째로, aws s3 cp 명령이 실행됩니다.

--storage-class STANDARD_IA는 자주 접근하지 않는 데이터용 스토리지 클래스로, Standard보다 50% 저렴합니다. --server-side-encryption AES256은 S3에 저장될 때 자동으로 암호화해서 보안을 강화합니다.

업로드가 완료되면 $?가 0(성공)이 되고, 이때만 rm으로 로컬 파일을 삭제합니다. 네 번째로, 에러 처리가 작동합니다.

if [ $? -eq 0 ] 조건 덕분에 네트워크 문제나 권한 문제로 업로드가 실패하면 로컬 파일을 삭제하지 않습니다.

이렇게 하면 다음 실행 때 다시 시도할 수 있어서 로그 손실을 방지할 수 있습니다. 여러분이 이 스크립트를 cron으로 매일 실행하면, 로컬 디스크는 항상 7일치만 유지되어 공간을 절약하고, 오래된 로그는 S3에 안전하게 보관됩니다.

6개월 후에 "11월 18일 로그 좀 보자"라고 하면 aws s3 cp s3://my-company-logs/year=2025/month=11/day=18/ ./ --recursive로 해당 날짜 로그를 다운로드해서 분석할 수 있습니다. 또한 S3 Lifecycle 정책을 설정하면 1년 후에는 자동으로 Glacier로 이동시켜서 비용을 더욱 절감할 수도 있습니다.

실전 팁

💡 스토리지 클래스를 용도에 맞게 선택하세요. 최근 90일은 STANDARD_IA, 그 이후는 GLACIER, 7년 이상은 DEEP_ARCHIVE를 쓰면 비용을 최대 95%까지 절감할 수 있습니다. S3 Lifecycle 정책으로 자동 전환 설정이 가능합니다.

💡 업로드 실패를 모니터링하세요. 스크립트에 실패 카운트를 세는 로직을 추가하고, 일정 횟수 이상 실패하면 알림을 보내도록 하세요. 네트워크 문제나 권한 문제를 조기에 발견할 수 있습니다.

💡 압축을 한 번 더 하는 것도 고려하세요. gzip 파일을 tar로 묶어서 업로드하면 작은 파일 여러 개보다 전송 속도가 빠르고, S3 요청 비용도 줄어듭니다. 하루치 로그를 하나의 tar.gz로 만드는 것이 효율적입니다.

💡 메타데이터를 활용하세요. aws s3 cp에 --metadata "app=myapp,env=prod,retention=90days" 같은 태그를 붙이면, 나중에 로그를 분류하거나 자동 삭제 정책을 적용할 때 유용합니다.

💡 다른 클라우드도 비슷합니다. Google Cloud는 gsutil, Azure는 az storage를 사용하면 됩니다. 스크립트 구조는 동일하고 명령어만 바꾸면 되므로, 멀티 클라우드 환경에서도 쉽게 적용할 수 있습니다.


#Bash#logrotate#로그관리#자동화#시스템관리#Bash,Linux,로그분석,자동화

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.