論logstash的玩法(ELK)

一寸HUI發表於2020-06-17

本篇文章採用的採用的是logstash-7.7.0版本,主要從如下幾個方面介紹

1、logstash是什麼,可以用來幹啥

2、logstash的基本原理是什麼

3、怎麼去玩這個elk的元件logstash

一、logstash是什麼,有哪些作用

1.1、概念

官方概念:Logstash是免費且開放的伺服器端資料處理管道,能夠從多個來源採集資料,轉換資料,然後將資料傳送到您最喜歡的“儲存庫”中。

1.2、功能

Logstash能夠動態地採集、轉換和傳輸資料,不受格式或複雜度的影響。利用Grok從非結構化資料中派生出結構,從IP地址解碼出地理座標,匿名化或排除敏感欄位,並簡化整體處理過程。

採集資料:

  能夠採集各種樣式、大小和來源的資料往往以各種各樣的形式,比如log日誌,收集redis、kafka等熱門分散式技術的資料,並且還可以收集實現了java的JMS規範的訊息中心的資料,或分散或集中地存在於很多系統中。Logstash支援各種輸入選擇,可以同時從眾多常用來源捕捉事件。能夠以連續的流式傳輸方式,輕鬆地從日誌、指標、Web應用、資料儲存以及各種AWS服務採集資料

 

 

 

解析資料和轉換:

  資料從源傳輸到儲存庫的過程中,Logstash過濾器能夠解析各個事件,識別已命名的欄位以構建結構,並將它們轉換成通用格式,以便進行更強大的分析和實現商業價值。
Logstash能夠動態地轉換和解析資料,不受格式或複雜度的影響:

  • 利用Grok從非結構化資料中解析出結構資料
  • 從IP地址破譯出地理座標
  • 將PII資料匿名化,完全排除敏感欄位
  • 簡化整體處理,不受資料來源、格式或架構的影響

  資料輸入端從各種資料來源收集到的資料可能會有很多不是我們想要的,這時我們可以給Logstash定義過濾器,過濾器可以定義多個,它們依次執行,最終把我們想要的資料過濾出來,然後把這些資料解析成目標資料庫,如elasticsearch等能支援的資料格式儲存資料。

 

資料轉存:

  選擇好儲存庫,匯出資料到儲存庫進行儲存,儘管Elasticsearch是我們的首選輸出方向,能夠為我們的搜尋和分析帶來無限可能,但它並非唯一選擇。Logstash提供眾多輸出選擇,可以將資料傳送到您要指定的地方,比如redis、kafka等

 

 

 

 

二、logstash的基本原理

  logstash分為三個步驟:inputs(必須的)→ filters(可選的)→ outputs(必須的),inputs生成時間,filters對其事件進行過濾和處理,outputs輸出到輸出端或者決定其儲存在哪些元件裡。inputs和outputs支援編碼和解碼。

 

執行模型:

Logstash是協調inputs、filters和outputs執行事件處理的管道。

  Logstash管道中的每個input階段都在自己的執行緒中執行。將寫事件輸入到記憶體(預設)或磁碟上的中心佇列。每個管道工作執行緒從該佇列中取出一批事件,通過配置的filter處理該批事件,然後通過output輸出到指定的元件儲存。管道處理資料量的大小和管道工作執行緒的數量是可配置的

  預設情況下,Logstash使用管道階段(input→filter和filter→output)之間的記憶體限制佇列來緩衝事件。如果Logstash不安全地終止,儲存在記憶體中的所有事件都將丟失。為了幫助防止資料丟失,可以啟用Logstash將飛行中的事件持久化到磁碟。有關詳細資訊,請參閱持久佇列https://www.elastic.co/guide/en/logstash/current/persistent-queues.html

如下是目前logstash7.7.0支援的inputs、outputs、filters

inputs:

azure_event_hubs,beats,cloudwatch,couchdb_changes,dead_letter_queue,elasticsearch,exec,file,ganglia,gelf,generator,github,google_cloud_storage,google_pubsub,graphite,heartbeat,http,http_poller,imap,irc,java_generator,java_stdin,jdbc,jms,jmx,kafka,kinesis,log4j,lumberjack,meetup,pipe,puppet_facter,rabbitmq,redis,relp,rss,s3,s3-sns-sqs,salesforce,snmp,snmptrap,sqlite,sqs,stdin,stomp,syslog,tcp,twitter,udp,unix,varnishlog,websocket,wmi,xmpp

outputs:

boundary, circonus, cloudwatch, csv, datadog, datadog_metrics, elastic_app_search, elasticsearch, email, exec, file, ganglia, gelf, google_bigquery, google_cloud_storage, google_pubsub, graphite, graphtastic, http, influxdb, irc, sink, java_stdout, juggernaut, kafka, librato, loggly, lumberjack, metriccatcher, mongodb, nagios, nagios_nsca, opentsdb, pagerduty, pipe, rabbitmq, redis, redmine, riak, riemann, s3, sns, solr_http, sqs, statsd, stdout, stomp, syslog, tcp, timber, udp, webhdfs, websocket, xmpp, zabbix

filters:

aggregate, alter, bytes, cidr, cipher, clone, csv, date, de_dot, dissect, dns, drop, elapsed, elasticsearch, environment, extractnumbers, fingerprint, geoip, grok, http, i18n, java_uuid, jdbc_static, jdbc_streaming, json, json_encode, kv, memcached, metricize, metrics, mutate, prune, range, ruby, sleep, split, syslog_pri, threats_classifier, throttle, tld, translate, truncate, urldecode, useragent, uuid, xml

三、玩一玩logstash

3.1、壓縮包方式安裝

下載地址1:https://www.elastic.co/cn/downloads/logstash   

下載地址2:https://elasticsearch.cn/download/

這裡需要安裝jdk,我使用的是elasticsearch7.7.0自帶的jdk:

解壓即安裝:

tar -zxvf logstash-7.7.0.tar.gz

來個logstash版本的HelloWorld:

./bin/logstash -e 'input { stdin { } } output { stdout {} }'

 

 

 

3.2、logstash配置檔案

 logstash.yml:包含Logstash配置標誌。您可以在此檔案中設定標誌,而不是在命令列中傳遞標誌。在命令列上設定的任何標誌都會覆蓋logstash中的相應設定

 pipelines.yml:包含在單個Logstash例項中執行多個管道的框架和指令。

 jvm.options:包含JVM配置標誌。使用此檔案設定總堆空間的初始值和最大值。您還可以使用此檔案為Logsta設定語言環境

 log4j2.properties:包含log4j 2庫的預設設定

 start.options (Linux):用於配置啟動服務指令碼

logstash.yml檔案詳解:

node.name  #預設主機名,該節點的描述名字
path.data  #LOGSTASH_HOME/data ,Logstash及其外掛用於任何持久需求的目錄
pipeline.id #預設main,pipeline的id
pipeline.java_execution #預設true,使用java執行引擎
pipeline.workers #預設為主機cpu的個數,表示並行執行管道的過濾和輸出階段的worker的數量
pipeline.batch.size #預設125 表示單個工作執行緒在嘗試執行過濾器和輸出之前從輸入中收集的最大事件數
pipeline.batch.delay #預設50 在建立管道事件時,在將一個小批分派給管道工作者之前,每個事件需要等待多長時間(毫秒)
pipeline.unsafe_shutdown  #預設false,當設定為true時,即使記憶體中仍有執行的事件,強制Logstash在關閉期間將會退出。預設情況下,Logstash將拒絕退出,直到所有接收到的事件都被推入輸出。啟用此選項可能導致關機期間資料丟失
pipeline.ordered #預設auto,設定管道事件順序。true將強制對管道進行排序,如果有多個worker,則阻止logstash啟動。如果為false,將禁用維持秩序所需的處理。訂單順序不會得到保證,但可以節省維護訂單的處理成本
path.config #預設LOGSTASH_HOME/config  管道的Logstash配置的路徑
config.test_and_exit #預設false,設定為true時,檢查配置是否有效,然後退出。請注意,使用此設定不會檢查grok模式的正確性
config.reload.automatic #預設false,當設定為true時,定期檢查配置是否已更改,並在更改時重新載入配置。這也可以通過SIGHUP訊號手動觸發
config.reload.interval  #預設3s ,檢查配置檔案頻率
config.debug #預設false 當設定為true時,將完全編譯的配置顯示為除錯日誌訊息
queue.type #預設memory ,用於事件緩衝的內部排隊模型。為基於記憶體中的遺留佇列指定記憶體,或為基於磁碟的離線佇列(持久佇列)指定持久記憶體
path.queue #預設path.data/queue  ,在啟用持久佇列時儲存資料檔案的目錄路徑
queue.page_capacity #預設64mb ,啟用持久佇列時(佇列),使用的頁面資料檔案的大小。佇列資料由分隔為頁面的僅追加資料檔案組成
queue.max_events #預設0,表示無限。啟用持久佇列時,佇列中未讀事件的最大數量
queue.max_bytes  #預設1024mb,佇列的總容量,以位元組為單位。確保磁碟驅動器的容量大於這裡指定的值
queue.checkpoint.acks #預設1024,當啟用持久佇列(佇列)時,在強制執行檢查點之前被隔離的事件的最大數量
queue.checkpoint.writes #預設1024,當啟用持久佇列(佇列)時,強制執行檢查點之前的最大寫入事件數
queue.checkpoint.retry #預設false,啟用後,對於任何失敗的檢查點寫,Logstash將對每個嘗試的檢查點寫重試一次。任何後續錯誤都不會重試。並且不推薦使用,除非是在那些特定的環境中
queue.drain #預設false,啟用後,Logstash將等待,直到持久佇列耗盡,然後關閉
path.dead_letter_queue#預設path.data/dead_letter_queue,儲存dead-letter佇列的目錄
http.host #預設"127.0.0.1" 表示endpoint REST端點的繫結地址。
http.port #預設9600 表示endpoint REST端點的繫結埠。
log.level #預設info,日誌級別fatal,error,warn,info,debug,trace,
log.format #預設plain 日誌格式
path.logs  #預設LOGSTASH_HOME/logs 日誌目錄

3.3、keystore

keystore可以保護一些敏感的資訊,使用變數的方式替代,比如使用ES_PWD代替elasticsearch的密碼,可以通過${ES_PWD}來獲取elasticsearch的密碼,這樣就是的密碼不再是明文密碼。

./bin/logstash-keystore create   #建立一個keyword
 ./bin/logstash-keystore add ES_PWD #建立一個elastic的passwd,然後通過${ES_PWD}使用該密碼
 ./bin/logstash-keystore list  #檢視已經設定好的鍵值對
 ./bin/logstash-keystore remove ES_PWD #刪除在keyword中的key

例如:

 

 

 3.4、logstash命令

注意:引數和logstash.yml配置檔案對應(這裡不詳解,請檢視3.2節)

-n, --node.name NAME          
-f, --path.config CONFIG_PATH 
-e, --config.string CONFIG_STRING
--field-reference-parser MODE 
--modules MODULES             
-M, --modules.variable MODULES_VARIABLE
--setup                      
--cloud.id CLOUD_ID                                            
--cloud.auth CLOUD_AUTH       
--pipeline.id ID              
-w, --pipeline.workers COUNT 
--pipeline.ordered ORDERED   
--java-execution                                               
--plugin-classloaders         
-b, --pipeline.batch.size SIZE 
-u, --pipeline.batch.delay DELAY_IN_MS 
--pipeline.unsafe_shutdown    
--path.data PATH              
-p, --path.plugins PATH       
-l, --path.logs PATH         
--log.level LEVEL             
--config.debug                
-i, --interactive SHELL      
-V, --version                 
-t, --config.test_and_exit    
-r, --config.reload.automatic 
--config.reload.interval 
--http.host HTTP_HOST         
--http.port HTTP_PORT         
--log.format FORMAT           
--path.settings SETTINGS_DIR

3.5、logstash配置檔案的格式和value type

1、logstash配置檔案的格式如下:

輸入,解析過濾,輸出,其中filter不是必須的,其他兩個是必須的。

input {
  ...
}

filter {
  ...
}

output {
  ...
}

2、value types(logstash支援的資料型別)

array:陣列可以是單個或者多個字串值。

users => [ {id => 1, name => bob}, {id => 2, name => jane} ]

Lists:集合

path => [ "/var/log/messages", "/var/log/*.log" ]
uris => [ "http://elastic.co", "http://example.net" ]

Boolean:true 或者false

ssl_enable => true

Bytes:位元組型別

my_bytes => "1113"   # 1113 bytes
my_bytes => "10MiB"  # 10485760 bytes
my_bytes => "100kib" # 102400 bytes
my_bytes => "180 mb" # 180000000 bytes

Codec:編碼型別

codec => "json"

Hash:雜湊(雜湊)

match => {
  "field1" => "value1"
  "field2" => "value2"
  ...
}
# or as a single line. No commas between entries:
match => { "field1" => "value1" "field2" => "value2" }

Number:數字型別

port => 33

Password:密碼型別

my_password => "password"

URI:uri型別

my_uri => "http://foo:bar@example.net"

Path: 路徑型別

my_path => "/tmp/logstash"

String:字串型別,字串必須是單個字元序列。注意,字串值被括在雙引號或單引號中

3.6、logstash的許可權配置

配置賬號,一個種是role,一種是user,配置方式有兩種,一種是通過elasticsearch的API配置,一種是通過kibana配置:

第一種方式:通過elasticsearch的API配置:

#新增一個logstash_writer的角色
POST _xpack/security/role/logstash_writer
{
  "cluster": ["manage_index_templates", "monitor", "manage_ilm"], 
  "indices": [
    {
      "names": [ "logstash-*" ],  #索引的模式匹配
      "privileges": ["write","create","delete","create_index","manage","manage_ilm"]   #許可權內容
    }
  ]
}

#新增一個有logstash_writer角色許可權的使用者:logstash_internal
POST _xpack/security/user/logstash_internal
{
  "password" : "x-pack-test-password",
  "roles" : [ "logstash_writer"],  #分配角色
  "full_name" : "Internal Logstash User"
}

#新增一個logstash_reader角色,只有read許可權
POST _xpack/security/role/logstash_reader
{
  "indices": [
    {
      "names": [ "logstash-*" ], 
      "privileges": ["read","view_index_metadata"]
    }
  ]
}

#新增一個有logstash_reader角色許可權的使用者:logstash_user
POST _xpack/security/user/logstash_user
{
  "password" : "x-pack-test-password",
  "roles" : [ "logstash_reader", "logstash_admin"], 
  "full_name" : "Kibana User for Logstash"
}

第二種:通過kibana的介面配置

Management > Roles
Management > Users

 

 

 許可權選擇見elasticsearch官網:

https://www.elastic.co/guide/en/elasticsearch/reference/current/authorization.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/security-privileges.html

 3.7、多管道配置

  如果需要在同一個程式中執行多個管道,Logstash提供了一種通過名為pipelines.yml的配置檔案來實現此目的的方法。

例如:

- pipeline.id: my-pipeline_1
  path.config: "/etc/path/to/p1.config"
  pipeline.workers: 3
- pipeline.id: my-other-pipeline
  path.config: "/etc/different/path/p2.cfg"
  queue.type: persisted

  該檔案在YAML檔案格式中,幷包含一個字典列表,其中每個字典描述一個管道,每個鍵/值對指定該管道的設定。該示例展示了通過id和配置路徑描述的兩個不同管道。對於第一個管道,為pipeline.workers的值設定為3,而在另一箇中,持久佇列特性被啟用。未在pipelines.yml顯式設定的值。yml檔案將使用到logstash中指定的預設值。
  當啟動Logstash不帶引數時,它將讀取管道pipelines.yml。yml檔案並例項化檔案中指定的所有管道。另一方面,當使用-e或-f時,Logstash會忽略管道。

注意:

  • 如果當前配置的事件流不共享相同的輸入/過濾器和輸出,並且使用標記和條件將它們彼此分離,這顯得多個管道尤其重要
  • 在單個例項中擁有多個管道還允許這些事件流具有不同的效能和永續性引數(例如,pipeline.workers和persistent queues的不同設定)。這種分離意味著一條管道中的阻塞輸出不會對另一條管道產生反壓力。
  • 考慮管道之間的資源競爭是很重要的,因為預設值是針對單個管道調優的。因此,例如,考慮減少每個管道使用pipeline.worker的數量,因為每個管道在預設情況下每個CPU核使用一個worker。
  • 每個管道都隔離持久佇列和死信佇列,它們的位置名稱空間為pipeline.id的值

各管道之間的通訊原理:https://www.elastic.co/guide/en/logstash/current/pipeline-to-pipeline.html,有興趣的可以瞭解下。

3.8、配置的重新載入

在我們執行logstash的過程,不想停掉logstash程式,但是又想修改配置,就可以使用到配置的重新載入了,有兩種方式。

第一種是在啟動的時候指定引數:

bin/logstash -f apache.config --config.reload.automatic

Logstash每3秒檢查一次配置更改。要更改此間隔,請使用--config.reload.interval <interval>選項,其中interval指定Logstash檢查配置檔案更改的頻率(以秒為單位),請注意,必須使用單位限定符(s)

第二種就是強制載入配置檔案

kill -SIGHUP pid  #pid為logstash的pid

自動配置重新載入配置注意點:

  • 當Logstash檢測到配置檔案中的更改時,它將通過停止所有輸入來停止當前管道,並嘗試建立使用更新後的配置的新管道。驗證新配置的語法後,Logstash驗證所有輸入和輸出都可以初始化(例如,所有必需的埠都已開啟)。如果檢查成功,則Logstash會將現有管道與新管道交換。如果檢查失敗,舊管道將繼續執行,並且錯誤將傳播到控制檯。
  • 在自動重新載入配置期間,不會重新啟動JVM。管道的建立和交換都在同一過程中進行。
  • 對grok模式檔案的更改也將重新載入,但僅在配置檔案中的更改觸發重新載入(或重新啟動管道)時。

3.9、常用filter介紹

1、grok

注:grok外掛是一個十分耗費資源的外掛

官網:https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html

Grok是將非結構化日誌資料解析為結構化和可查詢內容的好方法,非常適合syslog日誌,apache和其他Web伺服器日誌,mysql日誌等等

首先官方提供了120中的匹配模式(但是我一直都沒開啟這個網址):https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns

還有一個用來驗證自定義的解析是否正確的一個網址:http://grokdebug.herokuapp.com/

既然我沒能開啟官方提供的120個的模式匹配,從一片部落格中找到了一部分的匹配模式(如下):https://blog.csdn.net/cui929434/article/details/94390617

論logstash的玩法(ELK)
USERNAME [a-zA-Z0-9._-]+
USER %{USERNAME}
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]+)))\b

POSINT \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}

# 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])(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))(?![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)
HOST %{HOSTNAME}
IPORHOST (?:%{HOSTNAME}|%{IP})
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-z+]+)?
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(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?: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 (?:[PMCE][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 (?:[\w._/%-]+)
SYSLOGPROG %{PROG:program}(?:\[%{POSINT:pid}\])?
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}:
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}

# 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)?)
grok內建的一些匹配模式

基礎語法,一種是自帶的模式,一種是自定義的模式:

自帶的模式語法:  %{SYNTAX:SEMANTIC}

SYNTAX是將匹配文字模式的名稱,grok自帶的那些匹配模式名
SEMANTIC是你給一段文字的標識相匹配該匹配模式匹配到的內容,相當於一個欄位名

例如:

%{NUMBER:duration} %{IP:client}

比如要解析如下的日誌:

55.3.244.1 GET /index.html 15824 0.043

就可以使用該匹配模式去匹配:

%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}

得出的結果如下:

client: 55.3.244.1
method: GET
request: /index.html
bytes: 15824
duration: 0.043

 

自定義的模式語法:(?<field_name>the pattern here)

例如:

(?<queue_id>[0-9A-F]{10,11})  #表示10-11個字元的16進位制

我們可以建立一個目錄pattters,把我自定義的模式新增進去,在使用的時候就可以使用grok自帶的匹配模式的語法,例如:

我們在./patterns/postfix檔案中新增如下內容
POSTFIX_QUEUEID [0-9A-F]{10,11}

如上我們就定義了一個匹配模式了,可以使用如下的方式使用。假如我們有如下的日誌格式:

Jan  1 06:25:43 mailserver14 postfix/cleanup[21403]: BEF25A72965: message-id=<20130101142543.5828399CCAF@mailserver14.example.com>

然後我們對其就行解析:

filter {
      grok {
        patterns_dir => ["./patterns"]  #指定自定義的匹配模式路徑
        match => { "message" => "%{SYSLOGBASE} %{POSTFIX_QUEUEID:queue_id}: %{GREEDYDATA:syslog_message}" }
      }
    }

解析出的結果如下:

timestamp: Jan  1 06:25:43
logsource: mailserver14
program: postfix/cleanup
pid: 21403
queue_id: BEF25A72965
syslog_message: message-id=<20130101142543.5828399CCAF@mailserver14.example.com>

 grok的配置選項

break_on_match
值型別是布林值
預設是true
描述:match可以一次設定多組,預設會依照順序設定處理,如果日誌滿足設定條件,則會終止向下處理。但有的時候我們會希望讓Logstash跑完所有的設定,這時可以將break_on_match設為false。

keep_empty_captures
值型別是布林值
預設值是 false
描述:如果為true,捕獲失敗的欄位將設定為空值

match
值型別是陣列
預設值是 {}
描述:欄位值的模式匹配
例如:
filter {
  grok { match => { "message" => "Duration: %{NUMBER:duration}" } }
}
#如果你需要針對單個欄位匹配多個模式,則該值可以是一組,例如:
filter {
  grok { match => { "message" => [ "Duration: %{NUMBER:duration}", "Speed: %{NUMBER:speed}" ] } }
}

named_captures_only
值型別是布林值
預設值是 true
描述:如果設定為true,則僅儲存來自grok的命名捕獲

overwrite
值型別是 array
預設是[]
描述:覆蓋已經存在的欄位內容
例如:

filter {
  grok {
    match => { "message" => "%{SYSLOGBASE} %{DATA:message}" }
    overwrite => [ "message" ]
  }
}
如果日誌是May 29 16:37:11 sadness logger: hello world經過match屬性match => { “message” => “%{SYSLOGBASE} %{DATA:message}” }處理後,message的值變成了hello world。這時如果使用了overwrite => [ “message” ]屬性,那麼原來的message的值將被覆蓋成新值。

pattern_definitions
值型別是 陣列
預設值是 {}
描述:模式名稱和模式正規表示式,也是用於定義當前過濾器要使用的自定義模式。匹配現有名稱的模式將覆蓋預先存在的定義。可以將此視為僅適用於grok定義的內聯模式,patterns_dir是將模式寫在外部。
例如:
filter {
    grok {
        patterns_dir => "/usr/local/elk/logstash/patterns"
        pattern_definitions => {"MYSELFTIMESTAMP" => "20%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{HOUR}:?%{MINUTE}(?::?%{SECOND})"}
        match => {"message" => ["%{MYSELFTIMESTAMP:timestamp} %{JAVACLASS:message}","%{MYSELF:content}"]}
    }
}

patterns_dir
值型別是陣列
預設值是 []
描述:一些複雜的正規表示式,不適合直接寫到filter中,可以指定一個資料夾,用來專門儲存正規表示式的檔案,需要注意的是該資料夾中的所有檔案中的正規表示式都會被依次載入,包括備份檔案。

patterns_dir => ["/opt/logstash/patterns", "/opt/logstash/extra_patterns"]
正則檔案以文字格式描述:

patterns_file_glob
屬性值的型別:string
預設值:“*”
描述:針對patterns_dir屬性中指定的資料夾裡哪些正則檔案,可以在這個filter中生效,需要本屬性來指定。預設值“*”是指所有正則檔案都生效。

tag_on_failure
值型別是陣列
預設值是 [“_grokparsefailure”]
描述:沒有成功匹配時,將值附加到欄位到tags

tag_on_timeout
值型別是字串
預設值是 “_groktimeout”
描述:如果Grok正規表示式超時,則應用標記。

timeout_millis
值型別是數字
預設值是 30000
描述: 嘗試在這段時間後終止正規表示式。如果應用了多個模式,則這適用於每個模式。這將永遠不會提前超時,但超時可能需要一些時間。實際的超時時間是基於250ms量化的近似值。設定為0以禁用超時。

各元件的公共配置選項

break_on_match
值型別是布林值
預設是true
描述:match可以一次設定多組,預設會依照順序設定處理,如果日誌滿足設定條件,則會終止向下處理。但有的時候我們會希望讓Logstash跑完所有的設定,這時可以將break_on_match設為false。

keep_empty_captures
值型別是布林值
預設值是 false
描述:如果為true,捕獲失敗的欄位將設定為空值

match
值型別是陣列
預設值是 {}
描述:欄位值的模式匹配
例如:

filter {
  grok { match => { "message" => "Duration: %{NUMBER:duration}" } }
}

#如果你需要針對單個欄位匹配多個模式,則該值可以是一組,例如:
filter {
  grok { match => { "message" => [ "Duration: %{NUMBER:duration}", "Speed: %{NUMBER:speed}" ] } }
}

named_captures_only
值型別是布林值
預設值是 true
描述:如果設定為true,則僅儲存來自grok的命名捕獲

overwrite
值型別是 array
預設是[]
描述:覆蓋已經存在的欄位內容
例如:

filter {
  grok {
    match => { "message" => "%{SYSLOGBASE} %{DATA:message}" }
    overwrite => [ "message" ]
  }
}

如果日誌是May 29 16:37:11 sadness logger: hello world經過match屬性match => { “message” => “%{SYSLOGBASE} %{DATA:message}” }處理後,message的值變成了hello world。這時如果使用了overwrite => [ “message” ]屬性,那麼原來的message的值將被覆蓋成新值。

pattern_definitions
值型別是 陣列
預設值是 {}
描述:模式名稱和模式正規表示式,也是用於定義當前過濾器要使用的自定義模式。匹配現有名稱的模式將覆蓋預先存在的定義。可以將此視為僅適用於grok定義的內聯模式,patterns_dir是將模式寫在外部。
例如:

filter {
    grok {
        patterns_dir => "/usr/local/elk/logstash/patterns"
        pattern_definitions => {"MYSELFTIMESTAMP" => "20%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{HOUR}:?%{MINUTE}(?::?%{SECOND})"}
        match => {"message" => ["%{MYSELFTIMESTAMP:timestamp} %{JAVACLASS:message}","%{MYSELF:content}"]}
    }
}

patterns_dir
值型別是陣列
預設值是 []
描述:一些複雜的正規表示式,不適合直接寫到filter中,可以指定一個資料夾,用來專門儲存正規表示式的檔案,需要注意的是該資料夾中的所有檔案中的正規表示式都會被依次載入,包括備份檔案。

patterns_dir => ["/opt/logstash/patterns", "/opt/logstash/extra_patterns"]
正則檔案以文字格式描述:


patterns_file_glob
屬性值的型別:string
預設值:“*”
描述:針對patterns_dir屬性中指定的資料夾裡哪些正則檔案,可以在這個filter中生效,需要本屬性來指定。預設值“*”是指所有正則檔案都生效。

tag_on_failure
值型別是陣列
預設值是 [“_grokparsefailure”]
描述:沒有成功匹配時,將值附加到欄位到tags

tag_on_timeout
值型別是字串
預設值是 “_groktimeout”
描述:如果Grok正規表示式超時,則應用標記。

timeout_millis
值型別是數字
預設值是 30000
描述: 嘗試在這段時間後終止正規表示式。如果應用了多個模式,則這適用於每個模式。這將永遠不會提前超時,但超時可能需要一些時間。實際的超時時間是基於250ms量化的近似值。設定為0以禁用超時。

常用選項
所有過濾器外掛都支援以下配置選項:


dd_field
值型別是雜湊
預設值是 {}
描述:如果匹配成功,向此事件新增任意欄位。欄位名可以是動態的,並使用%{Field}包含事件的一部分
filter {
      grok {
        add_field => { "foo_%{somefield}" => "Hello world, from %{host}" }
      }
    }

# 你也可以一次新增多個欄位
filter {
  grok {
    add_field => {
      "foo_%{somefield}" => "Hello world, from %{host}"
      "new_field" => "new_static_value"
    }
  }
}

add_tag
值型別是陣列
預設值是 []
描述:如果此過濾器成功,請向該事件新增任意標籤。標籤可以是動態的,並使用%{field} 語法包含事件的一部分。
例如:

filter {
  grok {
    add_tag => [ "foo_%{somefield}" ]
  }
}

# 你也可以一次新增多個標籤
filter {
  grok {
    add_tag => [ "foo_%{somefield}", "taggedy_tag"]
  }
}

enable_metric
值型別是布林值
預設值是 true
描述:禁用或啟用度量標準

id
值型別是字串
此值沒有預設值。
描述:向外掛例項新增唯一ID,此ID用於跟蹤外掛特定配置的資訊。
例如:

filter {
  grok {
    id => "ABC"
  }
}

periodic_flush
值型別是布林值
預設值是 false
描述:如果設定為ture,會定時的呼叫filter的更新函式(flush method)

remove_field
值的型別:array
預設值:[]
描述:刪除當前文件中的指定filted

filter {
  grok {
    remove_field => [ "foo_%{somefield}" ]
  }
}
# 你也可以一次移除多個欄位:
filter {
  grok {
    remove_field => [ "foo_%{somefield}", "my_extraneous_field" ]
  }
}

remove_tag
值型別是陣列
預設值是 []
描述:如果此過濾器成功,請從該事件中移除任意標籤。標籤可以是動態的,並使用%{field} 語法包括事件的一部分。
例如:

filter {
  grok {
    remove_tag => [ "foo_%{somefield}" ]
  }
}
# 你也可以一次刪除多個標籤
filter {
  grok {
    remove_tag => [ "foo_%{somefield}", "sad_unwanted_tag"]
  }
}

2、mutate

官網網址:https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html

mutate允許對欄位執行常規改變。可以重新命名、刪除、替換和修改事件中的欄位。

二話不說,來個例子先:

filter {
    mutate {
        split => ["hostname", "."]  #切分
        add_field => { "shortHostname" => "%{hostname[0]}" } #獲取切分後的第一個欄位作為新增欄位
    }
    mutate {
        rename => ["shortHostname", "hostname" ] #重新命名
    }
}

mutate的配置選項:

常用的一些操作:
convert:轉換資料型別,資料型別hash
可以裝換的資料型別有:integer,string,integer_eu(和integer相同,顯示格式為1.000),float,float_eu,boolean
例項:
filter {
      mutate {
        convert => {
          "fieldname" => "integer"
          "booleanfield" => "boolean"
        }
      }
    }

copy:型別hash,將現有欄位複製到另一個欄位。現有的目標域將被覆蓋
例項:
 filter {
      mutate {
         copy => { "source_field" => "dest_field" }
      }
    }
    
gsub:型別array,根據欄位值匹配正規表示式,並用替換字串替換所有匹配項。只支援字串或字串陣列的欄位。對於其他型別的欄位,將不採取任何操作。
例項:
filter {
      mutate {
        gsub => [
          # replace all forward slashes with underscore
          "fieldname", "/", "_",
          # replace backslashes, question marks, hashes, and minuses
          # with a dot "."
          "fieldname2", "[\\?#-]", "."
        ]
      }
    }
    
join:型別hash,用分隔符連線陣列。對非陣列欄位不執行任何操作
例項:
filter {
     mutate {
       join => { "fieldname" => "," }
     }
   }
  
lowercase:型別array,轉為小寫
例項:
filter {
      mutate {
        lowercase => [ "fieldname" ]
      }
    }
    
merge:型別hash,合併陣列或雜湊的兩個欄位。字串欄位將自動轉換為陣列
例項:
filter {
     mutate {
        merge => { "dest_field" => "added_field" }
     }
   }
   
coerce:型別hash,設定存在但為空的欄位的預設值
例項:
filter {
      mutate {
        # Sets the default value of the 'field1' field to 'default_value'
        coerce => { "field1" => "default_value" }
      }
    }
    
rename:型別hash,重新命名
例項:
filter {
      mutate {
        # Renames the 'HOSTORIP' field to 'client_ip'
        rename => { "HOSTORIP" => "client_ip" }
      }
    }
    
replace:型別hash,用新值替換欄位的值
例項:
filter {
      mutate {
        replace => { "message" => "%{source_host}: My new message" }
      }
    }
    
split:型別hash,使用分隔符將欄位分割為陣列。只對字串欄位有效
例項:
filter {
      mutate {
         split => { "fieldname" => "," }
      }
    }
    
strip:型別array,欄位中刪除空白。注意:這隻對前導和後導空格有效。
例項:
filter {
      mutate {
         strip => ["field1", "field2"]
      }
    }
    
update:型別hash,使用新值更新現有欄位。如果該欄位不存在,則不採取任何操作。
例項:
filter {
      mutate {
        update => { "sample" => "My new message" }
      }
    }
    
uppercase:型別array,轉為大寫
例項:
filter {
      mutate {
        uppercase => [ "fieldname" ]
      }
    }
    
capitalize:型別array,將字串轉換為等效的大寫字母。
例項:
filter {
      mutate {
        capitalize => [ "fieldname" ]
      }
    }

tag_on_failure:型別string,如果在應用此變異篩選器期間發生故障,則終止其餘操作,預設值:_mutate_error

公共配置見:grok公共配置

3、date

date filter用於從欄位解析日期,然後使用該日期或時間戳作為事件的logstash時間戳

date常用的配置選項:

match:型別array,欄位名在前,格式模式在後的陣列[ field,formats... ],表示該欄位能夠匹配到的時間模式,時間模式可以有多種
例項:
filter {
      date {
        match => [ "logdate", "MMM dd yyyy HH:mm:ss" ]
      }
    }
    
tag_on_failure:型別array,預設值["_dateparsefailure"],當沒有成功匹配時,將值追加到tags欄位

target:型別String,預設值"@timestamp",將匹配的時間戳儲存到給定的目標欄位中。如果沒有提供,預設更新事件到@timestamp欄位。

timezone:型別String,表示時區,可以在該網址檢視:http://joda-time.sourceforge.net/timezones.html

公共配置見:grok公共配置

這裡只對如上三種filter說明,具體其他的filter請見官網:https://www.elastic.co/guide/en/logstash/current/filter-plugins.html

3.10、案例一、apache日誌解析

這個例子屬官網的一個例子:https://www.elastic.co/guide/en/logstash/current/advanced-pipeline.html

但是我這裡不弄這麼負責,我們不使用filebeat,直接使用logstash,apache日誌的資料集下載:https://download.elastic.co/demos/logstash/gettingstarted/logstash-tutorial.log.gz

我這裡不打算安裝apach,所以直接使用官方提供的資料集。

下載資料集,然後解壓檔案,就可以得到我們的一個日誌檔案:logstash-tutorial.log

首先我們看一下apache日誌的格式:

[elk@lgh ~]$ tail -3 logstash-tutorial.log 
86.1.76.62 - - [04/Jan/2015:05:30:37 +0000] "GET /projects/xdotool/ HTTP/1.1" 200 12292 "http://www.haskell.org/haskellwiki/Xmonad/Frequently_asked_questions" "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20140205 Firefox/24.0 Iceweasel/24.3.0"
86.1.76.62 - - [04/Jan/2015:05:30:37 +0000] "GET /reset.css HTTP/1.1" 200 1015 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20140205 Firefox/24.0 Iceweasel/24.3.0"
86.1.76.62 - - [04/Jan/2015:05:30:37 +0000] "GET /style2.css HTTP/1.1" 200 4877 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20140205 Firefox/24.0 Iceweasel/24.3.0"

然後開始配置:

cd logstash-7.7.0/ && mkdir conf.d
cd conf.d/ 
vim  apache.conf
#############apache.conf的內容如下###################
input {
        file {
            path => "/home/elk/logstash-tutorial.log"
            type => "log"
            start_position => "beginning"
            }
    }
filter {
    grok {
        match => { "message" => "%{COMBINEDAPACHELOG}"}
    }
}

output {
    stdout { codec => rubydebug }
}

然後啟動命令(可以選擇用nohup後臺啟動):

 cd logstash-7.7.0/ && ./bin/logstash -f conf.d/apache.conf

執行結果如下(部分結果):

論logstash的玩法(ELK)
{
           "verb" => "GET",
          "bytes" => "8948",
           "type" => "log",
           "host" => "gxt_126_233",
    "httpversion" => "1.0",
        "message" => "67.214.178.190 - - [04/Jan/2015:05:20:59 +0000] \"GET /blog/geekery/installing-windows-8-consumer-preview.html HTTP/1.0\" 200 8948 \"http://www.semicomplete.com/\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:21.0) Gecko/20100101 Firefox/21.0\"",
      "timestamp" => "04/Jan/2015:05:20:59 +0000",
       "referrer" => "\"http://www.semicomplete.com/\"",
     "@timestamp" => 2020-06-17T01:23:47.817Z,
           "path" => "/data/hd05/elk/logstash-tutorial.log",
          "ident" => "-",
       "response" => "200",
       "@version" => "1",
        "request" => "/blog/geekery/installing-windows-8-consumer-preview.html",
       "clientip" => "67.214.178.190",
          "agent" => "\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:21.0) Gecko/20100101 Firefox/21.0\"",
           "auth" => "-"
}
{
           "verb" => "GET",
          "bytes" => "1015",
           "type" => "log",
           "host" => "gxt_126_233",
    "httpversion" => "1.1",
        "message" => "66.249.73.185 - - [04/Jan/2015:05:18:48 +0000] \"GET /reset.css HTTP/1.1\" 200 1015 \"-\" \"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\"",
      "timestamp" => "04/Jan/2015:05:18:48 +0000",
       "referrer" => "\"-\"",
     "@timestamp" => 2020-06-17T01:23:47.815Z,
           "path" => "/data/hd05/elk/logstash-tutorial.log",
          "ident" => "-",
       "response" => "200",
       "@version" => "1",
        "request" => "/reset.css",
       "clientip" => "66.249.73.185",
          "agent" => "\"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\"",
           "auth" => "-"
}
{
           "verb" => "GET",
          "bytes" => "28370",
           "type" => "log",
           "host" => "gxt_126_233",
    "httpversion" => "1.0",
        "message" => "207.241.237.220 - - [04/Jan/2015:05:21:16 +0000] \"GET /blog/tags/projects HTTP/1.0\" 200 28370 \"http://www.semicomplete.com/blog/tags/C\" \"Mozilla/5.0 (compatible; archive.org_bot +http://www.archive.org/details/archive.org_bot)\"",
      "timestamp" => "04/Jan/2015:05:21:16 +0000",
       "referrer" => "\"http://www.semicomplete.com/blog/tags/C\"",
     "@timestamp" => 2020-06-17T01:23:47.817Z,
           "path" => "/data/hd05/elk/logstash-tutorial.log",
          "ident" => "-",
       "response" => "200",
       "@version" => "1",
        "request" => "/blog/tags/projects",
       "clientip" => "207.241.237.220",
          "agent" => "\"Mozilla/5.0 (compatible; archive.org_bot +http://www.archive.org/details/archive.org_bot)\"",
           "auth" => "-"
}
執行結果

2.11、案例二、nginx日誌解析

首先安裝nginx:nginx功能介紹和基本安裝

這裡我們也不使用filebeat,因為這篇文章只是介紹logstash

配置:

cd conf.d/ 
vim  nginx.conf
############nginx.conf配置如下#####################
input {
        file {
            path => "/usr/local/nginx/logs/access.log"
            type => "log"
            start_position => "beginning"
            }
    }
   
filter {
grok {
        match => { "message" => ["(?<RemoteIP>(\d*.\d*.\d*.\d*)) - %{DATA:[nginx][access][user_name]} \[%{HTTPDATE:[nginx][access][time]}\] \"%{WORD:[nginx][access][method]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}\" %{NUMBER:[nginx][access][response_code]} %{NUMBER:[nginx][access][body_sent][bytes]} \"%{DATA:[nginx][access][referrer]}\" \"%{DATA:[nginx][access][agent]}\""] }
        add_field => {
                "Device" => "Charles Desktop"
        }
        remove_field => "message"
        remove_field => "beat.version"
        remove_field => "beat.name"
    }
}
    output {    
             elasticsearch {
                    hosts => ["192.168.110.130:9200"]
                    index => "nginx-log-%{+YYYY.MM.dd}"
                }
    }

如上的配置中輸出到elasticsearch中,這裡沒有設定密碼,所以不需要使用者和密碼,還有就是這裡使用的預設模板,如果想要修改的話可以使用,可以新增如下配置:

user => "elastic"  #使用者
password => "${ES_PWD}" #通過keystore儲存的密碼
manage_template => false #關閉預設的模板
template_name => "elastic-slowquery" #指定自定義的模板

執行命令啟動logstash

cd logstash-7.7.0/ && ./bin/logstash -f conf.d/nginx.conf

執行的結果(檢視elasticsearch叢集):

 

 

 從上面的兩個圖看,一個建立了我們在nginx.conf中指定的一個索引,然後索引的內容都是解析出來的一些欄位內容。

3.12、案例三、elasticsearch慢日誌解析

這是例項我們採用filebeat+logstash+elasticsearch,還有許可權驗證進行試驗:

這裡主要是對elasticsearch的慢日誌查詢做解析,雖然我在一篇文章搞懂filebeat(ELK)中篇文章中直接通過filebeat的elasticsearch(beat版本)的模組對其做過解析,但是解析的還是不夠特別完善,這裡引入logstash對其解析,過濾。

首先配置filebeat檔案(這裡只配置了一個輸入和一個輸出,沒有做多餘的處理,只是用來收集日誌):

#=========================== Filebeat inputs =============================
filebeat.inputs:

# Each - is an input. Most options can be set at the input level, so
# you can use different inputs for various configurations.
# Below are the input specific configurations.

- type: log

  # Change to true to enable this input configuration.
  enabled: true

  # Paths that should be crawled and fetched. Glob based paths.
  paths:
    - /var/logs/es_aaa_index_search_slowlog.log
    - /var/logs/es_bbb_index_search_slowlog.log
    #- c:\programdata\elasticsearch\logs\*

#================================ Outputs =====================================

# Configure what output to use when sending the data collected by the beat.

#----------------------------- Logstash output --------------------------------
output.logstash:
  # The Logstash hosts
  hosts: ["192.168.110.130:5044","192.168.110.131:5044","192.168.110.132:5044"]
  loadbalance: true   #這裡採用負載均衡機制,

  # Optional SSL. By default is off.
  # List of root certificates for HTTPS server verifications
  #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"]

  # Certificate for SSL client authentication
  #ssl.certificate: "/etc/pki/client/cert.pem"

  # Client Certificate Key
  #ssl.key: "/etc/pki/client/cert.key"

然後啟動filebeat:

cd filebeat-7.7.0-linux-x86_64 && ./filebeat -e

然後配置logstash的配置檔案:

cd conf.d/ 
vim  es.conf
############es.conf配置如下##############
input {
        beats{
                port => 5044
        }
    }
   
filter {
grok {
        match => {"message" => "\[%{TIMESTAMP_ISO8601:query_time},%{NUMBER:number1}\]\s*\[%{DATA:log_type}\]\s*\[%{DATA:index_query_type}\]\s*\[%{DATA:es_node}\]\s*\[%{DATA:index_name}\]\s*\[%{NUMBER:share_id}\]\s*took\[%{DATA:times_s}\],\s*took_millis\[%{NUMBER:query_times_ms}\],\s*types\[%{DATA:types}\],\s*stats\[%{DATA:status}\],\s*search_type\[%{DATA:search_type}\],\s*total_shards\[%{NUMBER:total_shards}\],\s*source\[%{DATA:json_query}\],\s*extra_source"}
        remove_field => ["message","@version","status","times_s","@timestamp","number1"]
    }
  mutate{
        convert => {
        "query_times_ms" => "integer"
}
}
}
    output {    
             elasticsearch {
                    hosts => ["192.168.110.130:9200","192.168.110.131:9200","192.168.110.132:9200"]
                    index => "elastic-slowquery-222"
                    user => "elastic"
                    password => "${ES_PWD}"
                    manage_template => false
                    template_name => "elastic-slowquery"
                }
    }

如上配置使用了使用者的許可權驗證,以及elasticsearch的自定義模板

啟動logstash

cd logstash-7.7.0/ && ./bin/logstash -f conf.d/es.conf

登入es檢視結果:

 

logstash就介紹到這裡了,如果有疑問多看官網比較好

 

參考:

logstash官網:https://www.elastic.co/guide/en/logstash/current/index.html

相關文章