Log Aggregation/FluentD

Spring Logback -> FluentD -> ES 연동 - 2. Spring Logback 설정

Camouflage129 2021. 1. 7. 12:13

꽤나 고생한 부분인데, FluentdAppender가 따로있어, 이를 적용하여 사용하였습니다.

일반적인 LogbackSocket을 사용할 경우 아래와 같은 에러가 발생하여,

FluentdAppender를 사용하여 처리하였습니다.

 

먼저 Pom.xml입니다.

 

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>

<dependency>
	<groupId>com.sndyuk</groupId>
	<artifactId>logback-more-appenders</artifactId>
	<version>1.8.3</version>
</dependency>

<!-- [Optional] If you use The Fluentd appender, You need to add the dependency(fluent-logger). -->
<dependency>
	<groupId>org.fluentd</groupId>
	<artifactId>fluent-logger</artifactId>
	<version>0.3.4</version>
</dependency>

<!-- [Optional] If you use The Fluency appender, You need to add the dependency(fluency). -->
<dependency>
	<groupId>org.komamitsu</groupId>
	<artifactId>fluency-core</artifactId>
	<version>2.4.1</version>
	<optional>true</optional>
</dependency>
<dependency>
	<groupId>org.komamitsu</groupId>
	<artifactId>fluency-fluentd</artifactId>
	<version>2.4.1</version>
	<optional>true</optional>
</dependency>

 

다음은 Logback.xml입니다.

저희는 zipkin-slueth까지 설정하여 TraceId를 부여하고 있기 때문에 아래와같은 패턴이 입력됩니다.

만약 이러한 세팅을 사용하지 않는다면, 가장 하단 참고 링크를 참조하시면 됩니다.

 

tag.label으로 로그를 FluentD Match에서 매핑하여 사용한다고 보시면 됩니다.

 

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>
                 %d{yyyy-MM-dd HH:mm:ss, ${projectTimeZone}} [%X{X-B3-TraceId:-}, %X{X-B3-SpanId:-}] [%X{requestURL}] [%thread] %-5level %logger{36} - %msg %n
            </Pattern>
        </layout>
    </appender>

    <springProfile name="dev, stg, prd">
        <appender name="fluentd" class="ch.qos.logback.more.appenders.DataFluentAppender">
            <tag>applog</tag>
            <label>logback</label>
            <remoteHost>${FULENTD_SERVER_IP}</remoteHost>
            <port>24224</port>
            
            <additionalField>
                <key>foo</key>
                <value>bar</value>
            </additionalField>
            <additionalField>
                <key>foo2</key>
                <value>bar2</value>
            </additionalField>

            <!-- [Optional] Configurations to customize Fluent-logger-java's behavior -->
            <bufferCapacity>16777216</bufferCapacity> <!-- in bytes -->
            <timeout>10000</timeout> <!-- in milliseconds -->

            <!--  [Optional] If true, Map Marker is expanded instead of nesting in the marker name -->
            <flattenMapMarker>false</flattenMapMarker>
            <!--  [Optional] default "marker" -->
            <markerPrefix></markerPrefix>

            <!-- [Optional] Message encoder if you want to customize message -->
            <layout class="ch.qos.logback.classic.PatternLayout">
                <Pattern>
                    %d{yyyy-MM-dd HH:mm:ss, ${projectTimeZone}} [%X{X-B3-TraceId:-}, %X{X-B3-SpanId:-}] [%X{requestURL}] [%thread] %-5level %logger{36} - %msg %n
                </Pattern>
            </layout>

            <!-- [Optional] Message field key name. Default: "message" -->
            <messageFieldKeyName>msg</messageFieldKeyName>
        </appender>

        <appender name="async" class="ch.qos.logback.classic.AsyncAppender">
            <!-- Logback의 AsyncAppender 옵션 -->
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>DEBUG</level>
            </filter>
            <param name="includeCallerData" value="false"/>
            <param name="queueSize" value="2048"/>
            <param name="neverBlock" value="true"/>
            <param name="maxFlushTime" value="5000"/>
            <appender-ref ref="fluentd" />
        </appender>
    </springProfile>
    
    <logger name="com.xyz" level="DEBUG" additivity="false">
        <appender-ref ref="stdout" />
        <springProfile name="dev, stg, prod">
            <appender-ref ref="fluentd" />
        </springProfile>
    </logger>

    <root level="INFO">
        <appender-ref ref="stdout" />
        <springProfile name="dev, stg, prod">
            <appender-ref ref="fluentd" />
        </springProfile>
    </root>

</configuration>

 

Spring Boot 서버에서 구성이 끝났습니다.

 

이제 Route53 -> NLB -> FluentD 서버로 진행하시면 됩니다.

 

FluentD에서는 아래와 같이 .applog로 로그내역이 들어오는 것을 볼 수 있고,

 

ES에서는 아래와 같이 Index가 생성되는 것을 보실 수 있습니다.

 

 

이제 이 서버들을 오토스케일링으로 세팅하여 사용 할 경우, 아래와 같이 명령어로 수행해주시면 됩니다.

fluentd -c /home/ec2-user/.fluentd-ui/fluentd-ui.conf -d /home/ec2-user/.fluentd-ui/fluentd-ui.pid

 

 

참고

 

docs.fluentd.org/deployment/command-line-option

 

FluentdAppender Git

https://github.com/sndyuk/logback-more-appenders

https://github.com/sndyuk/logback-more-appenders/blob/master/src/test/resources/logback-appenders-fluentd.xml

https://github.com/sndyuk/logback-more-appenders/blob/master/pom.xml

https://github.com/lightingLYG/fluentd-logback-appender/blob/master/src/main/resources/logback-appenders.xml

 

FluentAppender Ex

https://medium.com/@federicogaule/collecting-access-logs-into-elasticsearch-1a6f05288f8a

 

AsyncAppender

https://stylishc.tistory.com/133

https://docs.toast.com/ko/Analytics/Log%20&%20Crash%20Search/ko/logback-sdk-guide/