ELK入門02—Logstash+Log4j2+ES

1. 安裝Logstash

先到官方下載地址選擇對應版本的Logstash安裝包,由於我們Elasticsearch是2.4.6版本,這裏我們Logstash選擇2.4.1版本。
下載完成後,直接解壓
tar zxvf logstash-2.4.1.tar.gz
進入目錄,創建一個配置文件夾,在其中新建一個配置文件

cd logstash-2.4.1
mkdir config
vim config/log4j2-tcp.conf

輸入以下內容

input {
    tcp {
        mode => "server"
        host => "127.0.0.1"
        port => 4567
    }
}
filter {
    json {
        source => "message"
    }
}
output {
    stdout {
        codec => rubydebug
    }
}
Logstash處理數據的流程就像它的配置文件一樣簡單:input -> filter -> output
input配置數據來源,然後經過filter對數據進行過濾,最後輸出到output配置的目的地
tcp、json、stdout是插件的名稱,可以根據需要選擇插件,甚至開發自己的插件,相當的靈活
執行命令 ./bin/logstash-plugin list 可以查看Logstash的插件列表
執行命令 ./bin/logstash-plugin install plugin-name 可以安裝插件

配置好了,就可以直接運行了
./bin/logstash agent -f ./config/log4j2-tcp.conf

-f參數指定配置文件

當你看到輸出 Pipeline main has been shutdown,表示logstash啓動成功

2. log4j2

新建一個Log4j2的工程(請自行準備,簡單的demo即可),配置文件log4j2.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Properties>
        <Property name="LOG_PATTERN">{"logger": "%logger", "level": "%level", "msg": "%message"}%n</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>
        <Socket name="logstash-tcp" host="127.0.0.1" port="4567" protocol="TCP">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Socket>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="logstash-tcp" />
        </Root>
    </Loggers>
</Configuration>
如果你的使用的是log4j,那麼可以直接使用logstash的log4j插件,這裏就不展示了。

由於我們使用的是log4j2,而logstash-input-log4j2插件不支持logstash2.0.0以上的版本,所以這裏採用TCP的方式傳輸日誌
爲了展示logstash的filter的功能,這裏特意把log4j2的pattern設置成json格式的

運行log4j2的工程,然後到logstash運行的控制檯,正常的話就可以看到輸出

{                                                                                                                                              
    "message" => "{\"logger\": \"ELK\", \"level\": \"INFO\", \"msg\": \"log4j2 to logstash, uuid c944e68c-0247-43c7-ba53-6154eeec7357\"}\r",
    "@version" => "1",
    "@timestamp" => "2018-08-22T06:32:00.963Z",
    "host" => "127.0.0.1",
    "port" => 19766,
    "logger" => "ELK",
    "level" => "INFO",
    "msg" => "log4j2 to logstash, uuid c944e68c-0247-43c7-ba53-6154eeec7357"
}                                                                                                                                              

可以看到Logstash自動添加了幾個字段:@version、@timestamp、host、port
logger、level、msg就是filter配置的json插件解析message得到的

3. Logstash-gelf

上面是用的socket方式將日誌傳輸給logstash,如果你恰好遇到了,會發現一個問題,如果把logstash停掉然後再啓動,日誌就無法繼續傳輸了,也就是說socket無法自動重連,這在生產環境中,當然是個隱患。所以我們用gelf的方式
首先修改log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Properties>
        <Property name="LOG_PATTERN">{"logger": "%logger", "level": "%level", "msg": "%message"}%n</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>
        <Gelf name="logstash-gelf" host="udp:127.0.0.1" port="4567" version="1.1" ignoreExceptions="true">
            <Field name="timestamp" pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}" />
            <Field name="logger" pattern="%logger" />
            <Field name="level" pattern="%level" />
            <Field name="simpleClassName" pattern="%C{1}" />
            <Field name="className" pattern="%C" />
            <Field name="server" pattern="%host" />
        </Gelf>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="logstash-gelf" />
        </Root>
    </Loggers>
</Configuration>

接下來在logstash/config目錄下新建一個配置文件
vim ./config/log4j2-gelf.conf
輸入以下內容:

input {
    gelf {
        host => "127.0.0.1"
        port => 4567
    }
}
filter {
}
output {
    stdout {
        codec => rubydebug
    }
}
注意input的插件換成了gelf
如果你使用的是高版本的Logstash,執行 ./bin/logstash-plugin list --verbose | grep input-gelf 後,發現你的logstash-input-gelf版本大於等於3.1.0,那麼你可以通過增加 use_tcp => true 配置項開啓TCP支持,同時記得要把log4j2.xml中 host="udp:127.0.0.1" 改成 host="tcp:127.0.0.1"

啓動logstash ./bin/logstash agent -f ./config/log4j2-gelf.conf
然後重新運行log4j2的工程,正常情況下你會看到如下輸出:

{
    "host" => "hostname",
    "level" => "INFO",
    "facility" => "logstash-gelf",
    "@version" => "1",
    "@timestamp" => "2018-08-22T08:38:13.053Z",
    "source_host" => "127.0.0.1",
    "message" => "log4j2 to logstash, uuid c5b53dcc-7653-4f3e-bd6a-3164ec8f2dad",
    "server" => "server name",
    "logger" => "ELK",
    "className" => "com.demo.elk.log4j.Log",
    "simpleClassName" => "Log",
    "timestamp" => "2018-08-22 16:38:13.053"
}

可以發現,使用gelf,可以靈活的配置日誌的字段。同時如果你關閉後再打開Logstash,會發現已經可以自動重新連接了。

4. 輸出到ES

上面我們只是把日誌簡單的輸出到stdout,現在我們要做的是通過logstash把數據保存到Elasticsearch中
其實到了這一步就很簡單了,只需要更改logstash的配置文件中output部分,將輸出的目的地指向Elasticsearch即可
這裏我們在 log4j2-gelf.conf 的基礎上新建一個 log4j2-es.conf 配置文件,內容如下:

input {
    gelf {
        host => "127.0.0.1"
        port => 4567
    }
}
filter {
  mutate {
    lowercase => [ "logger", "level" ]
  }
}
output {
    stdout {
        codec => rubydebug
    }
    elasticsearch {
        hosts => ["127.0.0.1:9200"]
        index => "%{logger}"
        document_type => "%{level}"
    }
}

主要是output部分增加了elasticsearch插件的配置
hosts: elasticsearch的地址,數組類型,說明支持輸出到多個elasticsearch節點
index: 指定es中index的名稱
document_type: 指定index的type名稱

  1. %{logger} 和 %{level} 是引用了上面gelf插件得到的字段,同時因爲這兩個字段原本的值是大寫的,而index和document_type必須是小寫,所以增加了filter來把這兩個字段的值轉成小寫,所以filter裏的內容不是必須的
  2. 由於Elasticsearch以後將不再支持一個index下面多個type,所以document_type這個配置即將過時(官方文檔有介紹)

開啓elasticsearch,然後執行 ./bin/logstash agent -f ./config/log4j2-es.conf 啓動logstash,運行log4j2項目
會看到logstash控制檯依然正常輸出日誌內容,同時訪問 http://127.0.0.1:9200/_plugin/head/ 在索引欄目中應該可以看到寫入的日誌數據

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章