elk筆記5--logstash使用

1 logstash 簡介

Logstash是一個具有實時pipeline功能的開源數據收集引擎, 其可以動態統一來自不同來源的數據,並將數據標準化到目標位置。 也可以清洗數據並使其大衆化,以用於不同的高級下游分析和可視化用例。如圖1所示。
Logstash會動態提取,轉換和傳送數據,而不需要考慮數據的格式或複雜性,其使用grok從非結構化數據中獲取結構化的數據,從IP地址解密地理座標,對敏感字段進行匿名化或排除,並簡化整體處理。
在elk中,logstash 通過input,filter,output對數據進行處理,處理後寫入到具體的es索引中,如圖2所示。
圖1
在這裏插入圖片描述
圖2
在這裏插入圖片描述

2 logstash 使用案例

  1. 初步使用,輸入直接輸出
    bin/logstash -e ‘input{stdin{}} output{stdout{}}’
    在這裏插入圖片描述

  2. 將輸入直接寫入到es
    bin/logstash -e ‘input{stdin{}} output{elasticsearch{hosts=>[“127.0.0.1:9200”]} stdout{}}’
    output中去掉stdout{} 則沒有對應的輸出
    輸入hello,world後結果如下:
    在這裏插入圖片描述
    此時默認以 logstash-2020.04.13 新建對應的索引, 新建Index Pattern後可以從Discover查尋到輸入的hello world,如下所示:
    在這裏插入圖片描述
    由於默認爲5P 1R,一個節點時候會導致無法新建另外的1R,因此出現yellow狀態;更改配置爲5P0R後,恢復爲green;

  3. 收集系統日誌
    收集syslog和dmesg日誌,只需要在input和output中添加syslog和dmesg的規則即可。
    當規則較多的時候直接將其寫入到對應的配置文件中,此時啓動方式爲 bin/logstash -f …/pipeline/default.conf 。

    input{
     file{
     	path => "/var/log/syslog"
     	type => "syslog" 
     	start_position => "beginning"
     }
     file{
     	path => "/var/log/dmesg"
     	type => "dmesg"
     	start_position => "beginning"
     }
    }
    filter{
    }
    output{
     if [type] == "syslog" {
     	elasticsearch {
     		hosts => ["127.0.0.01:9200"]
     		index => "syslog-%{+YYYY.MM.dd}"
     	}
     }
     output{
     if [type] == "dmesg" {
     	elasticsearch {
     		hosts => ["127.0.0.01:9200"]
     		index => "dmesg-%{+YYYY.MM.dd}"
     	}
     }
    }
    
  4. 收集 es_error.log日誌
    此處需要使用codec,否則一個事件的多行沒有被統一處理;
    codec-plugins

    input{
     file{
     	path => "/home/xg/soft/bigdata/log/es6.8.8/es6.8.log"
     	type => "es_error"
     	start_position => "beginning"
     }
    }
    filter{
    }
    output{
     if [type] == "syslog" {
     	elasticsearch {
     		hosts => ["127.0.0.01:9200"]
     		index => "syslog-%{+YYYY.MM.dd}"
     	}
     }
     output{
     if [type] == "es_error" {
     	elasticsearch {
     		hosts => ["127.0.0.01:9200"]
     		index => "es_error-%{+YYYY.MM.dd}"
     	}
     }
    }
    

    此時,一個事件的多行被分隔爲多條日誌,需要使用codec加以處理, 具體處理如下所示:

     file{
     	path => "/home/xg/soft/bigdata/log/es6.8.8/es6.8.log"
     	type => "es_error"
     	start_position => "beginning"
     	codec => multiline {
           # Grok pattern names are valid! :)
           pattern => "^\["
           negate => true
           what => "previous"
         }
     }
    

    在這裏插入圖片描述
    改進後可以多行顯示java的堆棧信息,如下圖所示:
    在這裏插入圖片描述

  5. 收集apache 訪問日誌
    訪問apache日誌需要使用自定義的grok或者默認的grok解析,此處使用默認的%{COMBINEDAPACHELOG} 方式進行解析。
    相關的input,output,filter內容如下:

    input{
     file{
     	path => "/var/log/apache2/access.log"
     	type => "apache_access"
     	start_position => "beginning"
     }
    }
    filter{
     if [type] == "apache_access"{
     	grok {
         	match => { "message" => "%{COMBINEDAPACHELOG}"}
     	}
     }
    }
    output{
     if [type] == "apache_access" {
     	elasticsearch {
     		hosts => ["127.0.0.01:9200"]
     		index => "apache_access-%{+YYYY.MM.dd}"
     	}
     }
    }
    

    日誌收集後,即可在對應的discover查看,如下: 在這裏插入圖片描述

  6. 收集自定義日誌(grok解析)
    此處用python構建了2類日誌,一個爲自定義格式的字符串,另外一個是純json格式,相關代碼如下

    #!/usr/bin/python3
    
    import time
    import datetime
    import random
    import json
    
    company_list = [['baidu','39.156.69.79'],['ali','140.205.220.96'],['tencent','140.205.220.96'],['bytedance','36.110.162.63'],['google','216.58.200.46']]
    user_list = ['ally','bob','cindy','daid', 'friday','gad']
    type_list = ['buy','sell','search','other']
    def get_logs():
        date_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
        user = user_list[random.randint(0,len(user_list)-1)]
        type_str = type_list[random.randint(0,len(type_list)-1)]
        item = company_list[random.randint(0,len(company_list)-1)]
        msg =date_str.split('.')[0] +', '+user+' '+ type_str + ' on ' + item[0]
        str_log = '[' + date_str+'] ['+item[1]+'] ['+ user +'] [' + type_str + '] '+msg+'\n'
        dict_log = {'date_str':date_str,'ip':item[1],'user':user,'action':type_str,'msg':msg}
        json_log = json.dumps(dict_log)+'\n'
        return str_log, json_log
    
    def save_str_2_doc(data_str, filename):
        with open(filename,'a') as f:
            f.write(data_str)
    
    if __name__ == "__main__":
        path_str = '/home/xg/soft/bigdata/log/testlog/str.log'
        path_json = '/home/xg/soft/bigdata/log/testlog/json.log'
        while(True):
            str_log, json_log = get_logs()
            save_str_2_doc(str_log,path_str)
            save_str_2_doc(json_log,path_json)
            time.sleep(30)
    

    日誌收集後,使用grok解析對應日誌,然後在intpu,filter,output中添加對應的文件即可。具體內容如下:

    input{
     file{
     	path => "/home/xg/soft/bigdata/log/testlog/str.log"
     	type => "test_log"
     	start_position => "beginning"
     }
    }
    filter{
     if [type] == "test_log" {
     	grok {
         	match => { "message" => "\[%{GREEDYDATA:date_str}] \[%{IP:ip}] \[%{DATA:user}] \[%{DATA:action}] %{GREEDYDATA:msg}" }
     	}
     }
    }
    output{
     if [type] == "test_log" {
     	#stdout{}
     	elasticsearch {
     		hosts => ["127.0.0.01:9200"]
     		index => "test_log-%{+YYYY.MM.dd}"
     	}
     }
    }
    

    日誌收集後,即可在對應的discover查看,如下: 在這裏插入圖片描述

  7. 收集純json日誌
    使用6中的代碼生成純json字符串,在filter中使用json插件解析即可。具體內容如下:

    input{
     file{
     	path => "/home/xg/soft/bigdata/log/testlog/json.log"
     	type => "json_log"
     	start_position => "beginning"
     }
    }
    filter{
     if [type] == "json_log" {
     	json { 
     		source => "message"
     	}
     }
    }
    output{
     if [type] == "json_log" {
     	#stdout{}
     	elasticsearch {
     		hosts => ["127.0.0.01:9200"]
     		index => "json_log-%{+YYYY.MM.dd}"
     	}
     }
    }
    

    日誌解析出來後, 在discover中查看結果和6中一樣。
    此時,如果需要進一步解析ip歸屬等信息,可以在filter中添加geoip功能,具體內容如下。

     filter{
     if [type] == "json_log" {
     	json { 
     		source => "message"
     	}
     	geoip {
     		source => "ip"
             target => "ip_geo"
     	}
     }
    }
    

    解析後的效果如下:
    在這裏插入圖片描述

3 使用技巧

  1. 使用codec解決多行被切割爲多個日誌的問題
    默認情況下讀取文件每行爲一個時間, 對於產生多行的日誌會被分開爲多個事件,此時需要使用codec對其進行多行處理

  2. geo ip處理注意事項
    最簡單的使用方法即: 在geoip中添加source和target字段即可,其中source是需要解析的源ip。

  3. json處理
    純json,只需要使用在filter中使用json插件加以處理即可。

  4. 注意
    若測試時候使用多個type來區分不同的日誌,則在json字段或者grok的字段中不應該有type字段,否則使用grok或者json解析的時候會出錯。
    具體案例即爲: 上述使用type=>"test_log"後, 在grok中不可以繼續使用type字段,需要換成其它不同的字段。

4 說明

測試使用的elk版本爲6.8.8
logstash/6.8/index

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