以博客<ELK日志分析系統概述及部署>中實驗結果為依據
補充:如何用正則表達式匹配一個ipv4地址
([0-9] | [1-9][0-9] | 1[0-9][0-9] | 2[04][0-9] | 25[0-5])\.([0-9] | [1-9][0-9] | 1[0-9][0-9] | 2[04][0-9] | 25[0-5])\.([0-9] | [1-9][0-9] | 1[0-9][0-9] | 2[04][0-9] | 25[0-5])\.([0-9] | [1-9][0-9] | 1[0-9][0-9] | 2[04][0-9] | 25[0-5])
1、grok
grok可以將大文本字段分片成若干的小字段,如剛剛的日志文件,一行的信息太多,需要將message這個大文本字段給分片成若干的小字段如訪問ip、請求方法、URL、狀態碼等
grok兩種格式:
內置正則匹配格式:%{內置正則表達式:自定義的字段名稱}
自定義正則匹配格式:(?<自定義的字段名稱>自定義的正則表達式)
常用的正則表達式常量:
USERNAME [a-zA-Z0-9._-]+
USER %{USERNAME}
EMAILLOCALPART [a-zA-Z][a-zA-Z0-9_.+-=:]+
EMAILADDRESS %{EMAILLOCALPART}@%{HOSTNAME}
INT (?:[+-]?(?:[0-9]+))
BASE10NUM (?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+)))
NUMBER (?:%{BASE10NUM})
BASE16NUM (?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+))
BASE16FLOAT \b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\.[0-9A-Fa-f]*)?)|(?:\.[0-9A-Fa-f]+)))\bPOSINT \b(?:[1-9][0-9]*)\b
NONNEGINT \b(?:[0-9]+)\b
WORD \b\w+\b
NOTSPACE \S+
SPACE \s*
DATA .*?
GREEDYDATA .*
QUOTEDSTRING (?>(?<!\\)(?>"(?>\\.|[^\\"]+)+"|""|(?>'(?>\\.|[^\\']+)+')|''|(?>(?>\\.|[^\\]+)+)|))
UUID [A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}
# URN, allowing use of RFC 2141 section 2.3 reserved characters
URN urn:[0-9A-Za-z][0-9A-Za-z-]{0,31}:(?:%[0-9a-fA-F]{2}|[0-9A-Za-z()+,.:=@;$_!*'/?#-])+# Networking
MAC (?:%{CISCOMAC}|%{WINDOWSMAC}|%{COMMONMAC})
CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4})
WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2})
COMMONMAC (?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2})
IPV6 ((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?
IPV4 (?<![0-9])(?:(?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]))(?![0-9])
IP (?:%{IPV6}|%{IPV4})
HOSTNAME \b(?:[0-9A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b)
IPORHOST (?:%{IP}|%{HOSTNAME})
HOSTPORT %{IPORHOST}:%{POSINT}# paths
PATH (?:%{UNIXPATH}|%{WINPATH})
UNIXPATH (/([\w_%!$@:.,+~-]+|\\.)*)+
TTY (?:/dev/(pts|tty([pq])?)(\w+)?/?(?:[0-9]+))
WINPATH (?>[A-Za-z]+:|\\)(?:\
^\\?*]*)+ ?URIPROTO [A-Za-z]([A-Za-z0-9+\-.]+)+ ?URIHOST %{IPORHOST}(?::%{POSINT:port})? ?# uripath comes loosely from RFC1738, but mostly from what Firefox ?# doesn't turn into %XX ?URIPATH (?:/[A-Za-z0-9$.+!*'(){},~:;=@#%&_\-]*)+ ?#URIPARAM \?(?:[A-Za-z0-9]+(?:=(?:[^&]*))?(?:&(?:[A-Za-z0-9]+(?:=(?:[^&]*))?)?)*)? ?URIPARAM \?[A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[
^\\?*]*)+ ?URIPROTO [A-Za-z]([A-Za-z0-9+\-.]+)+ ?URIHOST %{IPORHOST}(?::%{POSINT:port})? ?# uripath comes loosely from RFC1738, but mostly from what Firefox ?# doesn't turn into %XX ?URIPATH (?:/[A-Za-z0-9$.+!*'(){},~:;=@#%&_\-]*)+ ?#URIPARAM \?(?:[A-Za-z0-9]+(?:=(?:[^&]*))?(?:&(?:[A-Za-z0-9]+(?:=(?:[^&]*))?)?)*)? ?URIPARAM \?[A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[
<>]*
URIPATHPARAM %{URIPATH}(?:%{URIPARAM})?
URI %{URIPROTO}://(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATHPARAM})?# Months: January, Feb, 3, 03, 12, December
MONTH \b(?:[Jj]an(?:uary|uar)?|[Ff]eb(?:ruary|ruar)?|[Mm](?:a|?)?r(?:ch|z)?|[Aa]pr(?:il)?|[Mm]a(?:y|i)?|[Jj]un(?:e|i)?|[Jj]ul(?:y)?|[Aa]ug(?:ust)?|[Ss]ep(?:tember)?|[Oo](?:c|k)?t(?:ober)?|[Nn]ov(?:ember)?|[Dd]e(?:c|z)(?:ember)?)\b
MONTHNUM (?:0?[1-9]|1[0-2])
MONTHNUM2 (?:0[1-9]|1[0-2])
MONTHDAY (?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9])# Days: Monday, Tue, Thu, etc...
DAY (?:Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?|Sun(?:day)?)# Years?
YEAR (?>\d\d){1,2}
HOUR (?:2[0123]|[01]?[0-9])
MINUTE (?:[0-5][0-9])
# '60' is a leap second in most time standards and thus is valid.
SECOND (?:(?:[0-5]?[0-9]|60)(?:[:.,][0-9]+)?)
TIME (?!<[0-9])%{HOUR}:%{MINUTE}(?::%{SECOND})(?![0-9])
# datestamp is YYYY/MM/DD-HH:MM:SS.UUUU (or something like it)
DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR}
DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR}
ISO8601_TIMEZONE (?:Z|[+-]%{HOUR}(?::?%{MINUTE}))
ISO8601_SECOND (?:%{SECOND}|60)
TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?
DATE %{DATE_US}|%{DATE_EU}
DATESTAMP %{DATE}[- ]%{TIME}
TZ (?:[APMCE][SD]T|UTC)
DATESTAMP_RFC822 %{DAY} %{MONTH} %{MONTHDAY} %{YEAR} %{TIME} %{TZ}
DATESTAMP_RFC2822 %{DAY}, %{MONTHDAY} %{MONTH} %{YEAR} %{TIME} %{ISO8601_TIMEZONE}
DATESTAMP_OTHER %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{TZ} %{YEAR}
DATESTAMP_EVENTLOG %{YEAR}%{MONTHNUM2}%{MONTHDAY}%{HOUR}%{MINUTE}%{SECOND}# Syslog Dates: Month Day HH:MM:SS
SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME}
PROG [\x21-\x5a\x5c\x5e-\x7e]+
SYSLOGPROG %{PROG:program}(?:
)?
SYSLOGHOST %{IPORHOST}
SYSLOGFACILITY <%{NONNEGINT:facility}.%{NONNEGINT:priority}>
HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT}# Shortcuts
QS %{QUOTEDSTRING}# Log formats
SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}:# Log Levels
LOGLEVEL ([Aa]lert|ALERT|[Tt]race|TRACE|[Dd]ebug|DEBUG|[Nn]otice|NOTICE|[Ii]nfo|INFO|[Ww]arn?(?:ing)?|WARN?(?:ING)?|[Ee]rr?(?:or)?|ERR?(?:OR)?|[Cc]rit?(?:ical)?|CRIT?(?:ICAL)?|[Ff]atal|FATAL|[Ss]evere|SEVERE|EMERG(?:ENCY)?|[Ee]merg(?:ency)?)
(1)內置正則表達式調用
格式:%{SYNTAX:SEMANTIC}
SYNTAX代表匹配值的類型,例如,0.11可以NUMBER類型所匹配,10.222.22.25可以使用IP匹配。
SEMANTIC表示存儲該值的一個變量聲明,它會存儲在elasticsearch當中方便kibana做字段搜索和統計,你可以將一個IP定義為客戶端IP地址client_ip_address,如%{IP:client_ip_address},所匹配到的值就會存儲到client_ip_address這個字段里邊,類似數據庫的列名,也可以把event log中的數字當成數字類型存儲在一個指定的變量當中,比如響應時間http_response_time,假設event log record如下:
messages:192.168.80.10 GET /index.html 15824 0.043
可以使用如下grok pattern來匹配這種記錄
%{IP:client_ip_address} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:http_response_time}
驗證:
瀏覽器訪問kibana:http://20.0.0.30:5601
左側點擊【開發工具】,點擊【Grok Debugger】
(2)自定義表達式調用
自定義正則匹配格式:(?<自定義的字段名稱>自定義的正則表達式)
192.168.80.10 GET /index.html 15824 0.043
可以自定義為
(?<remote_addr>%{IP}) (?<http_method>[A-Z]+) (?<request_uri>/.*) (?<response_bytes>[0-9]+) (?<response_time>[0-9\.]+)
驗證:

(3)示例
需求:
將訪問日志:192.168.9.1 - - [05/Jul/2024:18:59:56 +0800] "GET /favicon.ico HTTP/1.1" 404 153 "http://192.168.9.115/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0" "-" ? ? 以以下自定義的字段名稱進行分割客戶端地址:client_ip
日志時間:log_time
http方法:http_method
uri路徑:uri_path
狀態碼:status_num
%{IP:client_ip} - - \[(?<logtime>.+)\] "%{WORD:http_method} %{URIPATHPARAM:uri_path} .+" %{NUMBER:status_num} \d+ ".*" "(?<user_agent>.+)" .+
(4)將grok應用到nginx
20.0.0.40
修改nginx配置文件
cd /etc/nginx/conf.d
vim nginx_log.conf
input {file {path => "/var/log/nginx/access.log"type => "nginx_access"start_position => "beginning"sincedb_path => "/etc/logstash/sincedb_path/log_progress"}file {path => "/var/log/nginx/error.log"type => "nginx_error"start_position => "beginning"sincedb_path => "/etc/logstash/sincedb_path/log_progress"}
}filter {grok {match => ["message", "%{IP:client_ip} - - \[(?<log_time>.+)\] \"%{WORD:http_method} %{URIPATHPARAM:uri_path} .+\" %{NUMBER:status_num} \d+ \".*\" \"(?<user_agent>.+)\" .+"]}
}output {if [type] == "nginx_access" {elasticsearch {hosts => ["20.0.0.10:9200", "20.0.0.20:9200", "20.0.0.30:9200"]index => "nginx_access-%{+yyyy.MM.dd}"}}if [type] =="nginx_error" {elasticsearch {hosts => ["20.0.0.10:9200", "20.0.0.20:9200", "20.0.0.30:9200"]index => "access_error-%{+yyyy.MM.dd}"}}
}logstash -t -f nginx_log.conf #檢查配置
logstash -f nginx_log.conf #開啟
瀏覽器訪問nginx
kibana查看,刷新頁面
2、mutate
它提供了豐富的基礎類型數據處理能力。可以重命名,刪除,替換和修改事件中的字段。
Mutate 過濾器常用的配置選項
(1)?語法格式
將字段old_field重命名為new_field
filter {
? ? mutate {
? ? ? ? #寫法1,使用中括號括起來
? ? ? ? rename => ["old_field" => "new_field"]? ? ? ? #寫法2,使用大括號{}括起來
? ? ? ? rename => { "old_field" => "new_field" } ? ? ? ?
? ? }
}
將字段刪除
filter {
? ? mutate {
? ? ? ? remove_field ?=> ?["message", "@version", "tags"]
? ? }}
將filedName字段中所有"/“字符替換為”_"
filter {
? ? mutate {
? ? ? ? gsub => ["filedName", "/" , "_"]
? ? }
將filedName字段中所有",“字符后面添加空格
filter {
? ? mutate {
? ? ? ? gsub => ["filedName", "," , ", "]
? ? }
}
將filedName字段以"|"為分割符拆分數據成為數組
filter {
? ? mutate {
? ? ? ? split => ["filedName", "|"]
? ? }
}
合并 “filedName1” 和 “ filedName2” 兩個字段
filter {
? ? merge ?{ "filedName2" => "filedName1" }
}
用新值替換filedName字段的值
filter {
? ? mutate {
? ? ? ? replace => { "filedName" => "new_value" }
? ? }
}
添加字段first,值為message數組的第一個元素的值
filter {
? ? mutate {
? ? ? ? split => ["message", "|"]
? ? ? ? add_field => {
? ? ? ? ? ? "first" => "%{[message][0]}"
? ? ? ? }
? ? }
}
有條件的添加標簽
filter {
? ? #在日志文件路徑包含 access 的條件下添加標簽
? ? if [path] =~ "access" {
? ? ? ? mutate {
? ? ? ? ? ? add_tag => ["Nginx Access Log"]
? ? ? ? }
? ? }
? ??
? ? #在日志文件路徑是 /var/log/nginx/error.log 的條件下添加標簽
? ? if [path] == "/var/log/nginx/error.log" {
? ? ? ? mutate {
? ? ? ? ? ? add_tag => ["Nginx Error Log"]
? ? ? ? }
? ? }
}
(2)示例
20.0.0.40nginx服務器
cd /etc/nginx/conf.d
vim nginx_log.conf
mutate {rename => {"path" => "log_path" #修改path為log——path}remove_field => ["@version"] #刪除@versionadd_field => {"log_from" => "${HOSTNAME}" #添加字段名為log_from,從變量HOSTNAME獲取}}logstash -t -f nginx_log.conf
logstash -f nginx_log.conf
瀏覽器訪問頁面模擬測試(使用不同內容多訪問幾次nginx服務器以便查看日志)
kibana刷新查看日志
3、multiline多行合并插件
java錯誤日志一般都是一條日志很多行的,會把堆棧信息打印出來,當經過 logstash 解析后,每一行都會當做一條記錄存放到 ES,那這種情況肯定是需要處理的。 這里就需要使用 multiline 插件,對屬于同一個條日志的記錄進行拼接。
20.0.0.40
(1)安裝 multiline 插件
1)離線安裝插件
cd /usr/share/logstash
上傳logstash-offline-plugins-6.7.2.zip
bin/logstash-plugin install file:///usr/share/logstash/logstash-offline-plugins-6.7.2.zip
2)檢查下插件是否安裝成功
檢查下插件是否安裝成功,可以執行以下命令查看插件列表
bin/logstash-plugin list | grep mu #檢查
(2)使用 multiline 插件
第一步:每一條日志的第一行開頭都是一個時間,可以用時間的正則表達式匹配到第一行。
第二步:然后將后面每一行的日志與第一行合并。
第三步:當遇到某一行的開頭是可以匹配正則表達式的時間的,就停止第一條日志的合并,開始合并第二條日志。
第四步:重復第二步和第三步。filter {
? multiline {
? ? pattern => "^\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}.\d{3}"
? ? negate => true
? ? what => "previous"
? }
}
●pattern:用來匹配文本的表達式,也可以是grok表達式●what:如果pattern匹配成功的話,那么匹配行是歸屬于上一個事件,還是歸屬于下一個事件。previous: 歸屬于上一個事件,向上合并。next: 歸屬于下一個事件,向下合并
●negate:是否對pattern的結果取反。false:不取反,是默認值。true:取反。將多行事件掃描過程中的行匹配邏輯取反(如果pattern匹配失敗,則認為當前行是多行事件的組成部分)
測試:
20.0.0.40 nginx服務器
###準備一個測試日志文件
cd /opt
vim java.log
2022-11-11 17:09:19.774[XNIo-1 task-1]ERROR com.passjava.controlle .NembercController-查詢用>戶 活動數據失敗,異常信息為:com.passjava.exception.MemberException: 當前沒有配置活動規則at com.passjava.service.impL.queryAdmin(DailyServiceImpl.java:1444)at com.passjava.service.impl.dailyserviceImpL$$FastcLass
2022-11-11 17:10:56.256][KxNIo-1 task-1] ERROR com.passjava.controlle .NemberControl1er·查詢>員工 飯活動數據失敗,異常信息為:com.passjava.exception.MemberException: 當前沒有配置活動規則at com.passjava.service.impL.queryAdmin(DailyServiceImpl.java:1444)at com.passjava.service.impL.daiLyserviceImpL$$FastcLass
cd /etc/logstash/conf.d/
vim java.conf #準備測試腳本
input {file {path => "/opt/java.log"type => "javalog"start_position => "beginning"sincedb_path => "/etc/logstash/sincedb_path/log_progress"add_field => {"logfrom" => "${HOSTNAME}"}}
}filter {multiline {pattern => "^\d{4}-\d{2}-\d{2} \d{1,2}:\d{1,2}:\d{1,2}\.\d{3}"negate => truewhat => "previous"}
}output {elasticsearch {hosts => ["20.0.0.10:9200", "20.0.0.20:9200", "20.0.0.30:9200"]index => "javalog-%{+yyyy.MM.dd}"}
}logstash -t -f java.conf #測試
logstash -f java.conf #啟動
kibana瀏覽器查看驗證
4、date 時間處理插件
用于分析字段中的日期,然后使用該日期或時間戳作為事件的logstash時間戳
在Logstash產生了一個Event對象的時候,會給該Event設置一個時間,字段為“@timestamp”,同時,我們的日志內容一般也會有時間,但是這兩個時間是不一樣的,因為日志內容的時間是該日志打印出來的時間,而“@timestamp”字段的時間是input插件接收到了一條數據并創建Event的時間,所有一般來說的話“@timestamp”的時間要比日志內容的時間晚一點,因為Logstash監控數據變化,數據輸入,創建Event導致的時間延遲。這兩個時間都可以使用,具體要根據自己的需求來定。
filter {
? ? date {
? ? ? ? match => ["access_time", "dd/MMM/YYYY:HH:mm:ss Z", "UNIX", "yyyy-MM-dd HH:mm:ss", "dd-MMM-yyyy HH:mm:ss"]
? ? ? ? target => "@timestamp"
? ? ? ? timezone => "Asia/Shanghai"
? ? }?
}
●match:用于配置具體的匹配內容規則,前半部分內容表示匹配實際日志當中的時間戳的名稱,后半部分則用于匹配實際日志當中的時間戳格式,這個地方是整條配置的核心內容,如果此處規則匹配是無效的,則生成后的日志時間戳將會被input插件讀取的時間替代。
如果時間格式匹配失敗,會生成一個tags字段,字段值為 _dateparsefailure,需要重新檢查上邊的match配置解析是否正確。●target:將匹配的時間戳存儲到給定的目標字段中。如果未提供,則默認更新事件的@timestamp字段。
●timezone:當需要配置的date里面沒有時區信息,而且不是UTC時間,需要設置timezone參數。
(1)時間戳詳解
●年
yyyy ?#全年號碼。 例如:2015。
yy ? ?#兩位數年份。 例如:2015年的15。●月
M ? ? #最小數字月份。 例如:1 for January and 12 for December.。
MM ? ?#兩位數月份。 如果需要,填充零。 例如:01 for January ?and 12 for Decembe
MMM ? #縮短的月份文本。 例如: Jan for January。 注意:使用的語言取決于您的語言環境。 請參閱區域設置以了解如何更改語言。
MMMM ?#全月文本,例如:January。 注意:使用的語言取決于您的語言環境。●日
d ? #最少數字的一天。 例如:1月份的第一天1。
dd ?#兩位數的日子,如果需要的話可以填零.例如:01 for the 1st of the month。●時
H ? #最小數字小時。 例如:0表示午夜。
HH ?#兩位數小時,如果需要填零。 例如:午夜00。●分
m ? #最小的數字分鐘。 例如:0。
mm ?#兩位數分鐘,如果需要填零。 例如:00。●秒
s ? ?#最小數字秒。 例如:0。
ss ? #兩位數字,如果需要填零。 例如:00。●毫秒( 秒的小數部分最大精度是毫秒(SSS)。除此之外,零附加。)
S ? ?#十分之一秒。例如:0為亞秒值012
SS ? #百分之一秒 例如:01為亞秒值01
SSS ?#千分之一秒 例如:012為亞秒值012●時區偏移或身份
Z ? ?#時區偏移,結構為HHmm(Zulu/UTC的小時和分鐘偏移量)。例如:-0700。
ZZ ? #時區偏移結構為HH:mm(小時偏移和分鐘偏移之間的冒號)。 例如:-07:00。
ZZZ ?#時區身份。例如:America/Los_Angeles。 注意:有效的ID在列表中列出http://joda-time.sourceforge.net/timezones.html
(2)示例
在opt目錄下準備一個名字為ngx-access.log的文件,存放一些訪問日志,要求
cd /etc/logstash/conf.d/
vim access.conf
input {file {path => "/opt/ngx-access.log"type => "access"start_position => "beginning"sincedb_path => "/etc/logstash/sincedb_path/log_progress"}
}filter {grok {match => ["message", ".* - - \[(?<log_time>.+)\]"]}date{match => ["log_time", "dd/MMM/YYYY:HH:mm:ss", "UNIX", "yyyy-MM-dd HH:mm:ss", "dd-MMM-yyyy HH:mm:ss"]target => "@timestamp"timezone => "Asia/Shanghai"}
}output {elasticsearch {hosts => ["20.0.0.10:9200", "20.0.0.20:9200", "20.0.0.30:9200"]index => "access-%{+yyyy.MM.dd}"}
}logstash -t -f access.conf
logstash -f access.conf
kibana添加索引并查看