기타

점차 쌓이는 로그들 어떻게 처리해야할까 ?

MIN우 2024. 4. 29. 16:32
728x90

목차

· docker , docker volume을 이용해서 로그를 기록해보자 log.info 와 was-log !

· 점차 쌓여가는 로그들 나의 EC2의 용량은 누가 지킬 것 인가 알아보자!

 

 

최근에 실제 운영되는 프로젝트를 하면서 로그들을 관리해야할 상황이 왔다. docker logback에 의해 생성되는 로그들을

EC2내부에 기록을 해야했고, 해당 기록을 한 과정들을 담아보려고합니다.

 

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 이 곳에 추가할 properties를 넣는다. -->
    <property name="LOGS_ABSOLUTE_PATH" value="/var/log"/> <!-- docker run 시 볼륨 매핑해주기 -->

    <!-- appender(어디에 출력할 지)에서 콘솔에 출력되는 형식을 지정한다. -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{36} - %msg%n</Pattern>
        </layout>
    </appender>

    <springProfile name="dev"><!-- profile prod 에서만 동작해서 파일에 기록하도록 -->
        <!-- Info 레벨의 이름을 가진 로그를 저장할 방식을 지정한다. -->
        <appender name="INFO_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">

            <file>${LOGS_ABSOLUTE_PATH}/info.log</file> <!-- 파일을 저장할 경로를 정한다, 도커 사용 시 볼륨매핑 해주어야함 -->
            <!-- filters 종류 키워드로 확인 -->
            <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 지정한 레벨과 같은 로그이벤트 필터링 수행 -->
                <level>INFO</level>
                <onMatch>ACCEPT</onMatch> <!-- 해당 레벨만 기록한다. -->
                <onMismatch>DENY</onMismatch> <!-- 지정 레벨과 맞지 않으면 onMisMatch 에 지정에 따라 수행, DENY -> print 하지않음 -->
            </filter> <!-- 레벨별 필터링이 필요없을 경우 filter class 관련된 부분을 삭제하면 됨-->
            <encoder>
                <pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35} - %msg%n</pattern> <!-- 해당 패턴 네이밍으로 현재 로그가 기록됨 -->
            </encoder>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${LOGS_ABSOLUTE_PATH}/was-logs/info/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> <!-- 해당 패턴 네이밍으로 이전 파일이 기록됨 -->
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>100MB</maxFileSize> <!-- 한 파일의 최대 용량 -->
                </timeBasedFileNamingAndTriggeringPolicy>
                <maxHistory>60</maxHistory> <!-- 한 파일의 최대 저장 기한 -->
                <totalSizeCap>1GB</totalSizeCap> <!-- 전체 로그파일 크기 제한, 1기가 넘으면 오래된거 삭제 -->
            </rollingPolicy>
        </appender>
    </springProfile>

    <springProfile name="dev">
        <appender name="WARN_OR_MORE_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">

            <file>${LOGS_ABSOLUTE_PATH}/warn-or-more.log</file>
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <!-- 지정레벨 이상의 로그만 print 하는 필터 -->
                <level>WARN</level>
            </filter>
            <encoder>
                <pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35} - %msg%n</pattern>
            </encoder>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${LOGS_ABSOLUTE_PATH}/was-logs/warn-or-more/warn-or-more.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>100MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
                <maxHistory>60</maxHistory> <!-- 한 파일의 최대 저장 기한 -->
                <totalSizeCap>1GB</totalSizeCap> <!-- 전체 로그파일 크기 제한, 1기가 넘으면 오래된거 삭제 -->
            </rollingPolicy>
        </appender>
    </springProfile>

    <!-- 루트로거 구성, 루트로그의 기본 수준을 INFO로 지정, info 이상만 print -->
    <root level="INFO">
        <springProfile name="!dev">
            <!-- 각 appender는 루트 로거에 추가 -->
            <appender-ref ref="STDOUT"/>
        </springProfile>
        <springProfile name="dev">
            <!-- 각 appender는 루트 로거에 추가 -->
            <appender-ref ref="STDOUT"/>
            <appender-ref ref="WARN_OR_MORE_LOG"/>
            <appender-ref ref="INFO_LOG"/>
        </springProfile>
    </root>
</configuration>

여기서 중요한것은 

<property name="LOGS_ABSOLUTE_PATH" value="/var/log"/> <!-- docker run 시 볼륨 매핑해주기 -->

이 부분입니다. 불륨을 어디에 할 것인가 이부분을 불륨마운트를 시켜 호스트에서도 해당 로그들을 관찰할 수 있도록 할 것입니다.

또한 info레벨 이상에서의 로그들을 확인할 것 입니다.

 

저는 이렇게 진행하여 해당 로그들을 호스트에서 해놨습니다.

 

 

이렇게하게되면 점차 로그들은 쌓이게되고 오늘이 아닌 다른 로그들은 was-log라는 디렉토리안에 쌓이게되고 점차 쌓이게되면

EC2의 용량은 가득 차 오류가 날 것 입니다. 

 

점차 쌓여가는 로그들 나의 EC2의 용량은 누가 지킬 것 인가 

결론을 말하자면 , crontab과 aws s3로 처리하면된다.

 

usage:  crontab [-u user] file
        crontab [ -u user ] [ -i ] { -e | -l | -r }
                (default operation is replace, per 1003.2)
        -e      (edit user's crontab)
        -l      (list user's crontab)
        -r      (delete user's crontab)
        -i      (prompt before deleting user's crontab)

 

 

 export VISUAL=vi; crontab -e 해당 명령어로 crontab를 vi편집기로 수정한다.

 

매일 아침 6시 마다 해당 쉘 스크립트를 실행해준다.

 

upload_logs_daily.sh

#!/bin/bash

# 압축할 디렉토리와 압축 파일 이름 설정
source_dir="/home/ubuntu/pullo/log/was-logs"
compressed_file="logs-$(date +%Y%m%d).tar.gz"
# was-logs 디렉토리의 파일들을 압축
tar -zcvf "$compressed_file" "$source_dir"
echo "압축성공"
# 압축된 파일을 S3로 복사
aws s3 cp "./$compressed_file" "s3://pullo-s3-bucket/$compressed_file"
echo "aws s3 업로드 성공"
# 압축 파일 삭제
rm "./$compressed_file"
echo "압출 파일 삭제 성공"

# was-log파일 삭제
rm -rf "$source_dir"

 

이 작업은 was-logs라는 파일을 압축하여 s3 버킷에 저장하고 was logs파일을 삭제하는 방식으로 진행된다.

하지만 이 작업을 하기위해서는 aws configure 설정을 해줘야한다.

 

https://kimjingo.tistory.com/209

 

[AWS] AWS CLI 자격 증명하기(aws configure 명령어)

AWS CLI에서 다양한 리소스를 다루기 위해서는 자격 증명이 필요합니다. AWS 계정 혹은 액세스 키를 통하여 자격 증명을 할 수 있는데, 액세스 키를 이용하여 자격 증명을 하는 방법에 대하여 다루

kimjingo.tistory.com

aws configure은 다음처럼 퍼플릭키 ,시크릿키 , 리전, output 에 대한 파일을 명시해주면됩니다.

 

그러면 다음 쉘 스크립트는 6시마다 작동되어 logs들을 깔끔하게 처리해주고 s3버킷에 로그들은 매일 저장이 될 것입니다.

728x90