SpringBoot應用基於docker和EFK的日誌處理

1.概述git

在分佈式集羣環境下,單個節點的日誌內容每每都是存放在本身的節點上,這種獨立分散的日誌存儲方式會有不少問題。咱們須要一個統一的日誌處理中心,對日誌進行收集和集中存儲,並進行查看和分析。The Twelve-Factor App中有關於日誌處理的建議。github

相應的處理技術如今也很成熟,一般會採用Elastic Search + Logstash + Kibana的技術棧(ELK)。在這篇文章中咱們會採用一種更便於部署的方式,採用Elastic Search +Fluentd + Kibana的技術棧(EFK),而且經過docker進行部署。spring

對應的有一個示例項目在github上,地址:fluentd-bootdocker

2.安裝dockerubuntu

2.1.設置yum鏡像centos

國外的鏡像安裝速度很慢,採用清華大學 TUNA 鏡像源。瀏覽器

用root用戶新建 /etc/yum.repos.d/docker.repo 文件,內容以下:ruby

[dockerrepo]
name=Docker Repository
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker/yum/repo/centos7
enabled=1
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker/yum/gpg

2.2.安裝bash

執行命令:架構

sudo yum makecache
sudo yum install docker-engine

2.3.啓動docker服務

執行命令:

systemctl start docker.service

2.4.測試docker服務

執行命令:

docker run hello-world

屏幕上若是輸出如下相似信息,說明docker安裝正常。

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete 
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

2.5.安裝docker-compose

執行命令:

sudo curl -L https://github.com/docker/compose/releases/download/1.8.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

3.啓動容器

經過如下命令來下載示例項目,並進入項目目錄:

git clone https://github.com/qihaiyan/fluentd-boot.git;
cd fluentd-boot

在項目目錄中執行如下命令來啓動docker容器:

docker-compose up -d

容器的配置是在項目的docker-compose.yml文件中,配置內容很是簡單:

es:
  image: elasticsearch
  volumes:
    - ./es:/usr/share/elasticsearch/data
  ports:
    - 9200:9200
    - 9300:9300

kibana:
  image: kibana
  ports:
    - 5601:5601
  links:
    - es:elasticsearch

fluentd:
  build: fluent-es/
  ports:
    - 24224:24224
  links:
- es:es

配置文件中啓用了3個容器,分別是elasticsearch、kibana、fluentd。其中elasticsearch、kibana直接從倉庫中下載,fluentd是本身創建的容器。注意

- ./es:/usr/share/elasticsearch/data

這一行內容,會將elasticsearch的數據持久化保存在docker-compose.yml所在目錄的es目錄中。能夠將./es修改成其它任何路徑,可是對應的目錄要有讀寫權限。

fluentd容器的構建文件是項目的fluent-es目錄裏的Dockerfile,內容以下:

FROM fluent/fluentd:latest

WORKDIR /home/fluent
ENV PATH /home/fluent/.gem/ruby/2.2.0/bin:$PATH
RUN gem install fluent-plugin-elasticsearch

USER root
COPY fluent.conf /fluentd/etc

EXPOSE 24284

USER fluent
VOLUME /fluentd/log
CMD fluentd -c /fluentd/etc/$FLUENTD_CONF -p /fluentd/plugins $FLUENTD_OPT

從配置內容中能夠看出,咱們自建的fluentd容器是在官方的鏡像基礎上建的,主要的改動有2點:

  1. 安裝fluent-plugin-elasticsearch這個plugin;
  2. 將配置文件fluent.conf拷貝到容器中;

這兩個步驟的做用是讓fluentd可以將日誌內容發送到elasticsearch。

4.配置SpringBoot應用,將日誌發送到fluentd

在項目的build.gradle文件中包含這2行內容:

compile 'org.fluentd:fluent-logger:0.3.2'
compile 'com.sndyuk:logback-more-appenders:1.1.1'

項目會用logback-more-appenders將logback的日誌轉到fluentd。

logback的配置文件爲logback.xml:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <property name="FLUENTD_HOST" value="${FLUENTD_HOST:-${DOCKER_HOST:-localhost}}"/>
    <property name="FLUENTD_PORT" value="${FLUENTD_PORT:-24224}"/>
    <appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
        <tag>dab</tag>
        <label>normal</label>
        <remoteHost>${FLUENTD_HOST}</remoteHost>
        <port>${FLUENTD_PORT}</port>
        <maxQueueSize>20</maxQueueSize>
    </appender>

    <logger name="fluentd" level="debug" additivity="false">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
        <appender-ref ref="FLUENT" />
    </logger>
</configuration>

配置文件中經過FLUENTD_HOST和FLUENTD_PORT兩個環境變量來指定fluentd的地址和端口。若是環境變量中沒有這兩項配置,會默認發送到本機地址。

5.執行程序,查看效果 進入fluent-es目錄,執行 ./gradlew bootRun

這步會啓動SpringBoot的應用,該應用會隨機的產生日誌信息,並將日誌發送到Elastic Search。

在瀏覽器中打開 http://localhost:5601 能夠看到Kibana dashboard的頁面。

經過在環境變量中配置FLUENTD_HOST 和 FLUENTD_PORT,能夠指定docker容器的地址和端口,若是沒有指定,日誌會默認發送到localhost,在此種狀況下,SpringBoot應用和docker容器應該是運行在同一臺機器上。

6.總結

在現代化的系統架構中,愈來愈強調雲計算、微服務、集羣部署,日誌的集中處理是須要重點考慮的環節。爲了便於演示,只是部署了單節點,能夠經過kubernetes或是docker自帶的docker swarm來實現集羣部署。

原文地址:http://springcamp.cn/spring-boot/spring-boot-efk-log/

相關文章
相關標籤/搜索