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名稱
- %{logger} 和 %{level} 是引用了上面gelf插件得到的字段,同時因爲這兩個字段原本的值是大寫的,而index和document_type必須是小寫,所以增加了filter來把這兩個字段的值轉成小寫,所以filter裏的內容不是必須的
- 由於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/
在索引欄目中應該可以看到寫入的日誌數據