springboot + fluentd + mongoDB 연동

25gStroy·2022년 8월 10일
0

Springboot

목록 보기
28/41

fluntd?

흔히 아는 ELK에 로그스테시와 같이 로그를 저장소에 적제하거나 필터링하고 어딘가로 전송해주는 큐 역할을 하는 툴입니다.
해당 글에선 docker를 사용해서 할 예정입니다.

fluntd Dockerfile

FROM fluent/fluentd:v1.11-debian-1

USER root

RUN buildDeps="sudo make gcc g++ libc-dev" \
 && apt-get update \
 && apt-get install -y --no-install-recommends ${buildDeps} \
 && sudo apt-get install -y libmariadb-dev \
 && sudo gem install fluent-plugin-mongo \
 && sudo gem install -V fluentd-ui \
 && sudo gem sources --clear-all \
 && SUDO_FORCE_REMOVE=yes \
    apt-get purge -y --auto-remove \
                  -o APT::AutoRemove::RecommendsImportant=false \
                  $buildDeps \
 && rm -rf /var/lib/apt/lists/* \
 && rm -rf /tmp/* /var/tmp/* /usr/lib/ruby/gems/*/cache/*.gem

USER fluent

fluent-plugin-mongo 여기서 해당 fluentd에는 몽고디비와 연결할수 있는 플러그인이 필요하기때문에 목록에 추가 해 줬고 sudo gem install -V fluentd-ui를 추가해서 fluentd를 ui 로 관리하기 위해서는 해당 ui툴을 다운받아줘야해서 위와같이 설정 해 줬습니다.

ui 초기 계정 정보

id: admin
password: changeme

fluentd docker run 명령어

docker run -d --network {네트워크id} -u root -p 24224:24224 -p 9292:9292 -v ~/Desktop/fluentd.conf:/fluentd/etc/fluent.conf --name fluentd_mongo 49809b8cae22

fluentd는 24224포트를사용하고 fluentd 의 ui 는 9292포트를 사용하기때문에 위와같이 포트를 두개 열어줘야합니다.

fluent.conf

볼륨으로 연결한fluent.conf는 fluentd를 핸들링하기위한 설정 파일입니다.

  • fluentd 설정
<source>  //input
  @type forward // 해당 포트를 리스닝하고 포트로 오는 데이터를 받아주겠다
  port 24224
</source>



<match **> // output
  @type mongo

  user userid
  password pwd
  database dbname
  collection springboot_log
  host mongodb-container
  port 27017
  # capped
  # capped_size 1000m

  <inject>
    time_key time
  </inject>

  <buffer>
    @type file
    path /fluentd/log/buffer/manage_domain_log
    flush_interval 10s
  </buffer>

  <secondary>
    @type secondary_file
    directory /fluentd/log/secondary/manage_domain_log
    basename my.fail.logs
  </secondary>
</match>

mongodb docker run 명령어

docker run  --network {fluentd와 동일한 네트워크 id}  --name mongodb-container -v ~/data:/data/db -d -p 27017:27017 mongo

Spring boot project logback 설정

fluentd 와 연동하기 위해서는 logback 설정을 해주고 fluentd와 연동하기위한 의존성을 추가해 줘야 합니다.

  • gardle
implementation group: 'org.fluentd', name: 'fluent-logger', version: '0.3.4'
implementation group: 'com.sndyuk', name: 'logback-more-appenders', version: '1.5.6'

해당 라이브러리 사용법 예시

    private static FluentLogger LOG = FluentLogger.getLogger("app");

    @GetMapping("/log")
    public ResponseEntity<?> log() {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("from", "userA");
        data.put("to", "userB");
        LOG.log("follow", data);
        LOG.close();
        return new ResponseEntity<>(HttpStatus.CREATED);
    }
  • logback.xml 설정
    <appender name="FLUENT_TEXT" class="ch.qos.logback.more.appenders.DataFluentAppender">
        <!-- Check tag and label fluentd info: https://docs.fluentd.org/configuration/config-file-->
        <tag>applog</tag>
        <label>error_log</label>
        <remoteHost>${FLUENTD_HOST}</remoteHost>
        <port>${FLUENTD_PORT}</port>
    </appender>

위 appender을 추가해줘야 fluentd 와 통신할 수 있습니다. 설정은 다음과 같이 해주면되고 tag와 label로 fluentd 설정에 보시면 metch의 태그와 매칭돼서 해당 output을 타게됩니다.
해당글에서는 <match **> 로 와일드카드로 설정해놔서 어떻게 해놔도 상관 없습니다.

주의 사항!

저도 삽질하면서 깨달은 사실은 logback.xml 설정과 위에서 컨트롤러에서 사용하는 FluentLogger 객체의 커넥션은 별개라는 점입니다.
저도 테스트하는데 console에 뜨는 로그는 잘 날라가는데 애플리케이션 코드로 보내는 로그는 fluentd와 커넥션이 전혀 안이루어 져서 두개를 같은 커넥션이라 생각해서 한참 해매다가 알게된 점입니다.

개인적인 TIP

    <appender name="FLUENT_TEXT" class="ch.qos.logback.more.appenders.DataFluentAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 에러로그를 설정하고 로그의 레벨이 맞으면 onMatch, 아니라면 onMismatch  -->
            <level>error</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- Check tag and label fluentd info: https://docs.fluentd.org/configuration/config-file-->
        <tag>applog</tag>
        <label>error_log</label>
        <remoteHost>${FLUENTD_HOST}</remoteHost>
        <port>${FLUENTD_PORT}</port>
    </appender>

위 설정과같이 error 로그만 fluentd 에 보내도록 해 놓고 애플리케이션 코드 흐름상에서 애러 로그를 발생시키고 싶을땐 Slf4j 를 활용해서 일부러 콘솔에 에러로그를 띄우도록해서 fluentd로 전송하는 방법을 선택했습니다. 혼자 태스트할때는 애플리케이션 코드로는 커넥션이 되지 않아서 이렇게 해결했습니다.

사용 결과

/log 를 호출해서 해당 코드블럭을 실행하면

다음과같이 로그가 적제되는 것을 볼 수 있습니다.

profile
애기 개발자

0개의 댓글