ELK的踩坑之旅
前言
起源
許多年前,一個剛結婚的名叫 Shay Banon 的失業開發者,跟著他的妻子去了倫敦,他的妻子在那裡學習廚師。 在尋找一個賺錢的工作的時候,為了給他的妻子做一個食譜搜索引擎,他開始使用 Lucene 的一個早期版本。
直接使用 Lucene 是很難的,因此 Shay 開始做一個抽象層,Java 開發者使用它可以很簡單的給他們的程式添加搜索功能。 他發布了他的第一個開源項目 Compass。
後來 Shay 獲得了一份工作,主要是高性能,分散式環境下的記憶體數據網格。這個對於高性能,實時,分散式搜索引擎的需求尤為突出, 他決定重寫 Compass,把它變為一個獨立的服務並取名 Elasticsearch。
第一個公開版本在2010年2月發布,從此以後,Elasticsearch 已經成為了 Github 上最活躍的項目之一,他擁有超過300名 contributors(目前736名 contributors )。 一家公司已經開始圍繞 Elasticsearch 提供商業服務,並開發新的特性,但是,Elasticsearch 將永遠開源並對所有人可用。
據說,Shay 的妻子還在等著她的食譜搜索引擎…
設計思路如下
有3台機器
2台做elasticsearch的主副節點
1台做kibana和elasticsearch_head 由於機器匱乏我還在這台機器上部署了logstash和nginx服務
先說目的:將nginx的日誌通過logstash收集後發送到ela,然後kibana進行展示
環境如下
elasticsearch master 10.5.2.175:9200
elasticsearch salve 10.5.2.176:9200
logstash 172.17.211.153 啟動命令: nohup /usr/local/logstash/bin/logstash -f /usr/local/logstash/config/agent.conf -w 10 -l /usr/local/logstash/logs/logstash-plain.log &
nginx
es-head: 172.16.211.143:9100
kibana: 172.16.211.143:5601
架構如下:
加redis/kafa的原因:
在生產環境中,我們的日誌可能會有瞬時高峰,而這個時候如果直接存入es,可能會導致es承受不住,從而影響日誌的收集和查詢。 一般情況下,我們會將日誌存直接放到kafka或者redis這種讀寫性能非常高的應用中,作為一個快取,然後通過下游組件(例如logstash)進行消費、過濾後存入ES,然後通過可視化介面查看。
ELK的工作流程
- logstash客戶端收集到日誌後將日誌存入到redis之類的快取中
- Logstash_server將數據從redis中提取出來並根據/usr/local/logstash/patterns下的文件(文件名隨意取)這裡叫grok-patterns裡面根據不同的日誌,比如apache、nginx服務規定的不同格式來進行切割,切割完畢後將日誌存入到elastaicsearch中,格式裡面的key vlaue值就是els中的欄位和值
- elastaicsearch對logstash_server發送過來的值進行集群保存,提供被調用介面以及快速的搜索服務(這裡還可以安裝分詞插件,當做搜索引擎)
- kibana對es根據條件進行搜索並對搜索到的數據進行展示,使我們看起來更加直觀。
一、elasticsearch
Elasticsearch 是一個開源的搜索引擎,建立在一個全文搜索引擎庫 Apache Lucene™ 基礎之上。 Lucene 可以說是當下最先進、高性能、全功能的搜索引擎庫—無論是開源還是私有。
中文文檔//www.elastic.co/guide/cn/elasticsearch/guide/current/intro.html#intro
elasticsearch的安裝
需要有jdk環境
vim /etc/elasticsearch/jvm.options
2g
2g
1.vim /etc/elasticsearch/elasticsearch.yml
http.port: 9200
discovery.zen.ping.unicast.hosts: ["10.5.2.175","10.5.2.176"]
network.host: 10.5.2.175
2.vim /etc/systemd/system.conf
DefaultLimitNOFILE=65536
DefaultLimitNPROC=32000
DefaultLimitMEMLOCK=infinity
3.vim /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536
* soft nproc 32000
* hard nproc 32000
* hard memlock unlimited
* soft memlock unlimited
4.vim /etc/sysconfig/elasticsearch
JAVA_HOME=/usr/java/jdk1.8.0_151
5.vim /usr/lib/systemd/system/elasticsearch.service
[Service]
LimitMEMLOCK=infinity
elasticsearch的問題
啟動elasticsearch失敗,報找不到JAVA環境,可明明系統是有的 解決方法如下:
vim /etc/sysconfig/elasticsearch
JAVA_HOME=/usr/java/jdk1.8.0_151
elasticsearch的概念
index 索引 相當於資料庫里的「資料庫」 他是我們存儲和索引關聯數據的地方
type 類數據 將一類的數據放到一起 相當於資料庫中的「表」
id 相當於資料庫表中的一行
-
Elastic 本質上是一個分散式資料庫,允許多台伺服器協同工作,每台伺服器可以運行多個 Elastic 實例。單個 Elastic 實例稱為一個節點(node)。一組節點構成一個集群(cluster)。
-
Elastic 會索引所有欄位,經過處理後寫入一個反向索引(Inverted Index)。查找數據的時候,直接查找該索引。
倒排索引(反向索引)
原始文檔
創建倒排索引列表
倒排索引創建索引的流程:
1) 首先把所有的原始數據進行編號,形成文檔列表
2) 把文檔數據進行分詞,得到很多的詞條,以詞條為索引。保存包含這些詞條的文檔的編號資訊。
搜索的過程:
當用戶輸入任意的詞條時,首先對用戶輸入的數據進行分詞,得到用戶要搜索的所有詞條,然後拿著這些詞條去倒排索引列表中進行匹配。找到這些詞條就能找到包含這些詞條的所有文檔的編號。
然後根據這些編號去文檔列表中找到文檔
-
所以,Elastic 數據管理的頂層單位就叫做 Index(索引)。它是單個資料庫的同義詞。每個 Index (即資料庫)的名字必須是小寫。
下面的命令可以查看當前節點的所有 Index。
$ curl -X GET '//localhost:9200/_cat/indices?v
index 索引 相當於資料庫里的「資料庫」 他是我們存儲和索引關聯數據的地方
type 類數據 將一類的數據放到一起 相當於資料庫中的「表」
id 相當於資料庫表中的一行
pertty 在網頁中格式化輸出響應內容
elasticsearch的操作方法
官方教程在這裡,我覺得這個更加實用官方教程 //www.cnblogs.com/chuyuan/p/11380744.html
增
# 增加
//10.5.103.176:9200/database1/table1
{
"name": "doudou",
"age": 4.5,
"weight": 20,
}
# 查詢
# 以上方法是正確的
但是再增加一個table2的是否發生如下報錯
//10.5.103.176:9200/database1/table2
{
"name": "dianche1",
"weight": 1000
}
原因是elastic search在6.x版本調整了, 一個index只能存儲一種type。
查
GET /atguigu/_mapping
1. 檢索文檔
Mysql : select * from user where id = 1
ES : GET /atguigu/doc/1
響應結果
{
"_index" : "megacorp",
"_type" : "employee",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : {
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
}
2.簡單檢索
Mysql : select * from user
ES : GET /megacorp/employee/_search
3.全文檢索
ES : GET /megacorp/employee/_search?q=haha
查詢出所有文檔欄位值為haha的文檔
4.搜索(模糊查詢)
ES : GET /megacorp/employee/_search?q=hello
查詢出所有文檔欄位值分詞後包含hello的文檔
5.聚合
PUT atguigu/_mapping/doc
{
"properties": {
"interests": {
"type": "text",
"fielddata": true
}
}
}
elasticsearch-head的安裝
ealsticsearch只是後端提供各種api,那麼怎麼直觀的使用它呢?elasticsearch-head將是一款專門針對於elasticsearch的客戶端工具,是es的集群管理工具、數據可視化、增刪改查工具。相關詳細的教程在這裡
1 //www.sojson.com/blog/85.html
2 //www.cnblogs.com/xuwenjin/p/8792919.html
3 //blog.csdn.net/huwei2003/article/details/40581143
一、下載head插件
//github.com/mobz/elasticsearch-head
二、解壓到任意目錄
注意:為避免找不到,一定要和elasticsearch的安裝目錄區分開
三、安裝Node.js
因為head是一個Node.js項目。所以,如果沒有安裝nodejs需要先安裝Node.js
32位安裝包下載地址: //nodejs.org/dist/v4.4.3/node-v4.4.3-x86.tar.gz
64位安裝包下載地址: //nodejs.org/dist/v4.4.3/node-v4.4.3-x64.tar.gz
檢測PATH環境變數是否配置了Node.js,打開命令行輸入命令"which npm",輸出如下結果:
/usr/bin/npm
wget //nodejs.org/dist/latest-v8.x/node-v8.16.0.tar.gz
tar xf node-v8.16.0.tar.gz
cd node-v8.16.0
./configure --prefix=/usr/local/node-v8.16
make -j 8 && make install
添加環境變數
vim /etc/profile
################nodejs###############
export NODE_HOME=/usr/local/node-v8.16
export PATH=$PATH:$NODE_HOME/bin
source /etc/profile
node -v
v8.16.0
npm -v
6.4.1
四、安裝npm
yum install npm -y
五、es-head安裝:
解壓源碼包:elasticsearch-head.tar.gz
啟動:cd /usr/local/src/elasticsearch-head
npm run start &
訪問地址是//{你的ip地址}:9200/_plugin/head/
在瀏覽器中輸入:這台機器的ip+埠
//10.5.2.220:9100/
問題解決:
在elasticsearch中沒有當天的索引
頭一天使用過的bj日誌第二天無法收集到,原因是昨天logstash已經收集過一遍,就被打過了標籤,今天再使用的話,如果這個日誌是不再增加的就不會被收集,因為日誌中沒有新的內容進來,解決方法如下:
在logstash的config文件下的agent.conf加入以下配置
start_position =>"beginning"#檢查時間戳
二、kibana
語言設置
vim config/kibana.yml
i18n.locale: "en" 或者zh-CN中文
systemctl restart kibana重啟即可
安裝配置
重新載入systemctl配置,這個是針對centos7以上使用systemctl kibana restart命令的
systemctl daemon-reload
這裡由於是二進位的安裝方法,所以要設置一個systemctl start kibana.service
的啟動方法
1. vim /usr/lib/systemd/system/kibana.service
添加以下內容
[Unit]
Description=Kibana
After=network.target
[Service]
ExecStart=/usr/local/kibana/bin/kibana
Type=simple
PIDFile=/usr/local/kibana/kibana.pid
Restart=always
#User=es 這裡我直接使用root用戶進行啟動
#Group=es
[Install]
WantedBy=default.target
2. 重新載入一下配置文件
systemctl daemon-reload
3. 啟動
systemctl start kibana.service
4. 訪問測試
//10.5.2.220:5601
查詢語法
參考地址1 參考地址2 參考地址3//blog.csdn.net/u013958257/article/details/88567581
kibana查詢語法基於Lucene
Lucene是apache軟體基金會4 jakarta項目組的一個子項目,是一個開放源程式碼的全文檢索引擎工具包,但它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,提供了完整的查詢引擎和索引引擎,部分文本分析引擎(英文與德文兩種西方語言)。Lucene的目的是為軟體開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能,或者是以此為基礎建立起完整的全文檢索引擎。Lucene是一套用於全文檢索和搜尋的開源程式庫,由Apache軟體基金會支援和提供。Lucene提供了一個簡單卻強大的應用程式介面,能夠做全文索引和搜尋。在Java開發環境里Lucene是一個成熟的免費開源工具。就其本身而言,Lucene是當前以及最近幾年最受歡迎的免費Java資訊檢索程式庫。人們經常提到資訊檢索程式庫,雖然與搜索引擎有關,但不應該將資訊檢索程式庫與搜索引擎相混淆。
Lucene最初是由Doug Cutting開發的,在SourceForge的網站上提供下載。在2001年9月作為高品質的開源Java產品加入到Apache軟體基金會的 Jakarta家族中
kibana在ELK陣營中用來查詢展示數據
elasticsearch構建在Lucene之上,過濾器語法和Lucene相同
1. 根據某個欄位查詢
精確匹配: agent:"Mozilla/5.0"
如果不帶雙引號,只要包含指定值就可以搜索到 agent:Mozilla/5.0
如果是數值類型沒有以上區別
2. 數組範圍查詢
[7758794 TO 7758794] 表示等於,原意思是一個區間範圍
指定區間: response:[100 TO 200]
大於等於指定數值的: response:[201 TO *]
小於等於指定數值的: response:[* TO 200]
3. 從指定時間到現在/或者查詢指定時間前數據
2015-05-20T09:20:41.943Z之後的數據: @timestamp:{2015-05-20T09:20:41.943Z TO *}
2015-05-20T09:20:41.943Z之前的數據: @timestamp:{* TO 2015-05-20T09:20:41.943Z }
指定時間範圍: @timestamp:{2015-05-20T09:20:41.943Z TO 015-05-22T09:20:41.943Z}
備註:09:20:41事實上是17:20:41,存在8個小時差
4. 正則匹配
包含指定值: request:/uploads*/
不包含指定值: !request:/uploads*/
5. 邏輯查詢
AND(與關係資料庫一樣) request:/uploads*/ AND response:404
OR(與關係資料庫一樣) request:/uploads*/ OR response:200
組合查詢: (uid OR token) AND version
6. 存在/不存在
存在host欄位但不存在url欄位: _exists_:host AND _missing_:url
特殊轉義字元
+ – && || ! () {} [] ^」 ~ * ? : \
kibana創建索引模式(手動)
//blog.csdn.net/weixin_34727238/article/details/81540692
當在els中有了當天的索引,就可以到kibana中取創建索引模式了,只是這裡提供了一手動創建的方式,無法自動進行,需要本地定義腳本的方式進行自動索引的創建。
等所有索引都創建完畢後,在下面就能看到了
然後在下面這個裡面就能看到我們的索引裡面的數據情況了,前提是你的logstash成功將切割後的日誌發送到了els中
否則就是以下這種的
kibana創建索引模式(自動)
由於logstash客戶端運行的問題,只要有當天日誌產生,就會將該日誌發送給elasticsearch,然後會在elasticsearch裡面產生一個新的索引
方法如下:
在kibana節點上寫一個腳本,然後設置定時任務執行kibana中索引與elasticsearch的關聯
vim /usr/local/scripts/kibana_create_index.sh
#!/bin/bash
today=`date +%Y-%m-%d`
index_name="bj169-hc360-${today}.log"
curl -X POST -H "kbn-xsrf:reporting" -H "Content-Type: application/json" -d '{"attributes":{"title":"'$log_name'"}}' '//172.16.211.143:5601/api/saved_objects/index-pattern'
這裡遇到一個問題,json中調用變數的問題,一直調用不到,後來各種查詢原來是格式不對
json數據里變數要用''括起來
<font color=gray size=72>color=gray</font>
json數據里變數要用”括起來//www.cnblogs.com/landhu/p/7048255.html
ELK 索引生命周期管理
問題解決
Kibana server is not ready yet出現的原因
第一點:KB、ES版本不一致(網上大部分都是這麼說的)
解決方法:把KB和ES版本調整為統一版本
第二點:kibana.yml中配置有問題(通過查看日誌,發現了Error: No Living connections的問題)
解決方法:將配置文件kibana.yml中的elasticsearch.url改為正確的鏈接,默認為: //elasticsearch:9200
改為//自己的IP地址:9200
第三點:瀏覽器沒有緩過來
解決方法:刷新幾次瀏覽器。
終極解決方法:在elasticsearch中刪除kibana的相關索引,只是再打開kibana看不到其他了之前創建的圖形什麼的了
kibana可以做哪些分析
分析的必要性:頂級
- 用戶分布
- PV、UV
- 狀態碼
- 訪問時間
更多圖形看這裡//www.cnblogs.com/hanyifeng/p/5860731.html
比較牛逼一點的教程看這裡//www.bilibili.com/video/BV1TE411A77i?p=6
三、logstash
logstash和filebeat的對比
Filebeat是收集日誌的另外一種方式,二者區別在於以下
Filebeat用於日誌收集和傳輸,相比Logstash更加輕量級和易部署,對系統資源開銷更小,日誌流架構的話,Filebeat適合部署在收集的最前端,Logstash相比Filebeat功能更強,可以在Filebeat收集之後,由Logstash進一步做日誌的解析,至於kafka也可以考慮添加,然後收集的數據都存放在elasticsearch中。
- logstash和filebeat都是可以作為日誌採集的工具,目前日誌採集的工具有很多種,如fluentd, flume, logstash,betas等等。甚至最後我決定用filebeat作為日誌採集端工具的時候,還有人問我為什麼不用flume,logstash等採集工具。
- logstash出現時間要比filebeat早許多,隨著時間發展,logstash不僅僅是一個日誌採集工具,它也是可以作為一個日誌搜集工具,有豐富的input|filter|output插件可以使用。常用的ELK日誌採集方案中,大部分的做法就是將所有節點的日誌內容上送到kafka消息隊列,然後使用logstash集群讀取消息隊列內容,根據配置文件進行過濾。上送到elasticsearch。logstash詳細資訊可前往//www.elastic.co/
- logstash是使用Java編寫,插件是使用jruby編寫,對機器的資源要求會比較高,網上有一篇關於其性能測試的報告。之前自己也做過和filebeat的測試對比。在採集日誌方面,對CPU,記憶體上都要比前者高很多。LogStash::Inputs::Syslog 性能測試與優化
- filebeat也是elastic.公司開發的,其官方的說法是為了替代logstash-forward。採用go語言開發。程式碼開源。elastic/beats filebeat是beats的一個文件採集工具,目前其官方基於libbeats平台開發的還有Packetbeat, Metricbeat, Winlogbeat。filebeat性能非常好,部署簡單。是一個非常理想的文件採集工具。我自己採集工具也是基於beats源碼進行的二次開發。
//blog.csdn.net/m0_38120325/article/details/79072921
自動創建elasticsearch的索引
在logstash客戶端的配置文件中會有這麼一個配置文件
就是會將日誌發送到當天日期的索引匯總,沒有的話自動創建索引,我們只需要做的就是每日刪除舊的索引。
電子書教程推薦://doc.yonyoucloud.com/doc/logstash-best-practice-cn/get_start/introduction.html
啟動方法 基於最基礎的 nohup 方式
nohup /usr/local/logstash/bin/logstash -f /usr/local/logstash/conf/agent.conf &> /dev/null
也可以用daemontools來進行管理
安裝
yum -y install supervisord --enablerepo=epel
在 /etc/supervisord.conf 配置文件里添加內容,定義你要啟動的程式:
[program:elkpro_1]
environment=LS_HEAP_SIZE=5000m
directory=/opt/logstash
command=/opt/logstash/bin/logstash -f /etc/logstash/pro1.conf --pluginpath /opt/logstash/plugins/ -w 10 -l /var/log/logstash/pro1.log
[program:elkpro_2]
environment=LS_HEAP_SIZE=5000m
directory=/opt/logstash
command=/opt/logstash/bin/logstash -f /etc/logstash/pro2.conf --pluginpath /opt/logstash/plugins/ -w 10 -l /var/log/logstash/pro2.log
然後啟動 service supervisord start 即可。
logstash 會以 supervisord 子進程的身份運行,你還可以使用 supervisorctl 命令,單獨控制一系列 logstash 子進程中某一個進程的啟停操作:
supervisorctl stop elkpro_2
- 一個普通logstash_agent文件解析(logstash agent配置)
比如同一個nginx服務有3個點,怎麼測試其中每一個點都將日誌成功的發送出去了呢?
思路1:
在elasticsearch中查一條數據,然後再去各個點上找這條數據出現的次數,如果每個點都有該數據,多查幾條數據,盡量在每一個點都查到,如下
這裡查106.121.152.208這個IP,發現以下三個點都出現了該條數據
通過以下方法,在elk中找到了3條數據,說明至少這個3個點的日誌都已經上傳成功了
grok語法
官方給定的語法
//github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns
//github.com/elastic/logstash/tree/v1.4.2/patterns
如果你使用的正則語言可以將nginx日誌進行匹配,就可以成功對日誌進行切割,效果看下圖:
網站是這個://grokdebug.herokuapp.com/
1. 線上配置的資訊格式192.168.70.94 跟權威指南中的一樣
SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}:
以下這個是Logstash默認自帶了Apache標準日誌的grok正則表達式:
COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest
})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)
COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent}
2. 我的nginx日誌切割格式
NGINX_ACCESS %{IPORHOST:remote_addr} - %{USERNAME:remote_user} \[%{HTTPDATE:tiem_local}\] \"%{DATA:request}\" %{INT:status} %{NUMBER:bytes_sent} \"%{DATA:http_referer}\" \"%{DATA:http_user_agent}\"
MAINNGINXLOG %{COMBINEDAPACHELOG} %{QS:x_forwarded_for}
COMBINEDAPACHELOG 合併的apache日誌 logstash客戶端用的是這種方式
COMMONAPACHELOG 普通的apache日誌
當grok匹配失敗的時候,插件會為這個事件打個tag,默認是_grokparsefailure。LogStash允許你把這些處理失敗的事件路由到其他地方做後續的處理
input { # ... }
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} \[%{IPV4:ip};%{WORD:environment}\] %{LOGLEVEL:log_level} %{GREEDYDATA:message}" }
}
}
output {
if "_grokparsefailure" in [tags] {
# write events that didn't match to a file
file { "path" => "/tmp/grok_failures.txt" }
} else {
elasticsearch { }
}
}
看下面紅色的地方,表示grok匹配失敗,才會將tags的標籤定義成_grokparsefailure這個默認的
解決說是要設置錨點 目前不懂什麼意思 先放到這裡
//www.jianshu.com/p/86133dd66ca4
另外一種說法,暫時不會用,先放著
1.
if "_grokparsefailure" in [tags] { drop { } }
2.match語句跟第一個一樣的 沒啥要點,看著官網例子搞就行了
3.盡量用grok吧 ,grep功能以後要去掉的。
當時想的另外一種解決方法就是改nginx的日誌格式成json形式的,但是我不想用這種方法。
log_format json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"request":"$request",'
'"status":"$status",'
'"request_method": "$request_method",'
'"size":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"url":"$uri",'
'"http_forward":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"agent":"$http_user_agent"}';
access_log /var/log/nginx/access.log json ;
問題解決
Nginx日誌沒有被成功切割的終極原因
以下是兩種日誌方式:
log_format main '$remote_addr - $remote_user [$time_iso8601] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$host" "$request_time"';
log_format format2 '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$host" "$request_time"';
在logstash中進行切割的時候調用的時間變數是不同的,靈感來自如下:
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:time}" }
}
date{
match => ["time", "yyyy-MM-dd HH:mm:ss", "ISO8601"]
target => "@timestamp"
}
mutate{
remove_field => ["time"]
}
定義:
HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT}
TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?
#NGINX_ACCESS %{IPORHOST:remote_addr} - %{USERNAME:remote_user} \[%{HTTPDATE:time_iso8601}\] \"%{DATA:request}\" %{INT:status} %{NUMBER:bytes_sent} \"%{DATA:http_referer}\" \"%
{DATA:http_user_agent}\"
{DATA:http_user_agent}\"
NGINX_ACCESS %{IPORHOST:remote_addr} - %{USERNAME:remote_user} \[%{TIMESTAMP_ISO8601:time_iso8601}\] \"%{DATA:request}\" %{INT:status} %{NUMBER:bytes_sent} \"%{DATA:http_refere
r}\" \"%{DATA:http_user_agent}\"
SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}:
COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest
})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)
COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent}
Nginx中時間格式1:$time_local 對應logstash中\[%{HTTPDATE:timestamp}\]
Nginx中時間格式2:$time_iso8601 對應logstash中\[%{TIMESTAMP_ISO8601:timestamp}\]