Elasticsearch+Kibana+Logstash 搭建日誌平臺

使用elk方式對日誌系統的解析php

 

Java 環境部署

網上不少教程,此處只作出測試html

 

java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

Elasticsearch 搭建

curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.5.1.tar.gz
tar zxvf elasticsearch-1.5.1.tar.gz
cd elasticsearch-1.5.1/
./bin/elasticsearch
bin/elasticsearch -d #(後臺運行)

 

es在此處不須要設置多少東西,基本上默認的就能夠知足咱們的要求了...java

Logstash 搭建

初步搭建

curl -O http://download.elastic.co/logstash/logstash/logstash-1.5.1.tar.gz

 

如今你應該有了一個叫logstash-1.5.2.tar.gz的文件了。 咱們把它解壓一下linux

 

tar zxvf logstash-1.4.2.tar.gz
cd logstash-1.5.1


如今咱們來運行一下:git

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


咱們如今能夠在命令行下輸入一些字符,而後咱們將看到logstash的輸出內容:
hello world
2015-06-17T01:22:14.405+1000 0.0.0.0 hello worldgithub

 

Ok,還挺有意思的吧... 以上例子咱們在運行logstash中,定義了一個叫"stdin"的input還有一個"stdout"的output,不管咱們輸入什麼字符,Logstash都會按照某種格式來返回咱們輸入的字符。這裏注意咱們在命令行中使用了-e參數,該參數容許Logstash直接經過命令行接受設置。這點尤爲快速的幫助咱們反覆的測試配置是否正確而不用寫配置文件。
讓咱們再試個更有意思的例子。首先咱們在命令行下使用CTRL-C命令退出以前運行的Logstash。如今咱們從新運行Logstash使用下面的命令:web

 

bin/logstash -e 'input { stdin { } } output { stdout { codec => rubydebug } }'


咱們再輸入一些字符,此次咱們輸入"goodnight moon" 將出現:正則表達式

 

goodnight moon
{
  "message" => "goodnight moon",
  "@timestamp" => "2013-11-20T23:48:05.335Z",
  "@version" => "1",
  "host" => "my-laptop"
}

 

以上示例經過從新設置了叫"stdout"的output(添加了"codec"參數),咱們就能夠改變Logstash的輸出表現。相似的咱們能夠經過在你的配置文件中添加或者修改inputs、outputs、filters,就可使隨意的格式化日誌數據成爲可能,從而訂製更合理的存儲格式爲查詢提供便利。apache

 

集成Elasticsearch插入數據

以上的步驟已經成功的搭建了logstash,接下來增長logstash的配置文件,使其配置文件啓動,將數據存入ES中,顯示json

 

一、在/root/config/目錄下面增長logs.conf

input{
    file{
        type => "all"
        path => "/root/tomcat7/logs/catalina.out"
    }
    file{
        type => "access"
        path => "/root/tomcat7/logs/access.log"
    }
}filter {
    multiline {
      pattern => "^[^\[]"
      what => "previous"
    }
    if [type] == "access" {
      grok {
        pattern => "(?<request_info>{.*}$)"
      }
      json {
        source => request_info
      }
      geoip {
        source => "client_ip"
        fields => ["country_name", "region_name", "city_name", "real_region_name", "latitude", "longitude"]
        remove_field => [ "[geoip][longitude]", "[geoip][latitude]","location","region_name" ]
      }
      useragent {
          source => "user_agent"
          prefix => "useragent_"
          remove_field => [ "useragent_device", "useragent_major", "useragent_minor" ,"useragent_patch","useragent_os","useragent_o
s_major","useragent_os_minor"]
      }
    } else if [type] == 'all' {
      grok {
	pattern => "\[(?<level>\w*).*\] (?<datetime>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2},\d{3})\s"
      }
    }
    mutate {
      remove_field => [ "request_info", "@version", "tags" ]
      remove_tag => [ "_grokparsefailure" ]
      replace => [ "host", "gd1_prd_yowoo_tomcat4" ]
    }
}
output {
  stdout { codec => rubydebug }
  elasticsearch {
    host => "localhost"
    index => "logstash-%{type}-%{+YYYY.MM.dd}"
    index_type => "%{type}"
  }
}

 

二、啓動logstash(配置文件啓動)

 

sh logstash -f /root/config/logs.conf

 

三、在上述的配置文件中,有指定了tomcat的日誌,all是tomcat的日誌,access是咱們本身在程序中寫的的日誌,在log4j.xml中有:

 

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
	<!-- all log for console -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} %l %M - %m%n" />
		</layout>
	</appender>

	<!-- access log -->
	<appender name="access" class="org.apache.log4j.DailyRollingFileAppender">
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} - %m%n" />
		</layout>
		<param name="Append" value="true" />
		<param name="File" value="/root/tomcat7/logs/access.log"<span style="font-family: Arial, Helvetica, sans-serif;"> /></span>
		<param name="DatePattern" value="'.'yyyy-MM-dd'.'" />
		<filter class="com.lives.platform.common.log.AccessLogFilter" />
	</appender>


	<root>
		<priority value="debug" />
		<appender-ref ref="console" />
		<appender-ref ref="access" />
	</root>

</log4j:configuration>


在log4j.xml中配置的是日滾的日誌文件,logstash指向了生成日誌文件的地址,進行監聽,日誌不會的,我在博客中有一個分類叫日誌,進去看哇...

 

Kibana 搭建

下載Kibana

wget https://download.elastic.co/kibana/kibana/kibana-4.1.0-linux-x64.tar.gz

 

解壓出來就好了...

配置使其讀取ES的數據展現

進入Kibana目錄/config中,修改kibana.yml文件,指定ES訪問地址(ps:之前的版本是修改conf.js,不要讓被人誤導你...)

# Kibana is served by a back end server. This controls which port to use.
port: 5601

# The host to bind the server to.
host: "0.0.0.0"

# The Elasticsearch instance to use for all your queries.
elasticsearch_url: "http://localhost:9200"


最後進入web頁面中查看 

 

 

 

下面咱們講解一下logstash中config配置參數

首先咱們能看到的是三個input,filter和output,分別是讀取日誌,過濾分割和輸出日誌,重點在filter上:

 

1

2

3

4

5

6

7

8

9

10

11

[03-Jun-2013 13:15:29] PHP Fatal error:  Uncaught exception 'Leb_Exception' in /data1/www/bbs.xman.com/htdocs/framework/xbox/ufo.php:68

Stack trace:

#0 /data/www/bbs.xman.com/htdocs/framework/dao/abstract.php(299): Leb_Dao_Pdo->connect(Array, 'read')

#1 /data/www/bbs.xman.com/htdocs/framework/dao/pdo.php(108): Leb_Dao_Abstract->initConnect(false)

#2 /data/www/bbs.xman.com/htdocs/framework/dao/abstract.php(1123): Leb_Dao_Pdo->query('SELECT * FROM `...')

#3 /data/www/bbs.xman.com/htdocs/framework/dao/abstract.php(1217): Leb_Dao_Abstract->select(Array)

#4 /data/www/bbs.xman.com/htdocs/framework/model.php(735): Leb_Dao_Abstract->daoSelect(Array, false)

#5 /data/www/bbs.xman.com/htdocs/app/configure/model/configure.php(40): Leb_Model->find()

#6 /data/www/bbs.xman.com/htdocs/app/search/default.php(131): Configure->get_configure_by_type('news')

#7 /data/www/bbs.xman.com/htdocs/framework/dispatcher.php(291): defaultController->indexAction()

#8 /data/www/bbs.xman.com/htdocs/framework/dispatcher.php(222): Leb_Di in /data1/www/bbs.xman.com/htdocs/framework/dao/pdo.php on line 68

 

 這個時候 logstash通常會只記錄上面一行,因此這類的日誌就看不全了。怎麼辦呢?logstash提供了一個功能解決了這個問題就是"multiline"
這個filter的功能顧名思義就是對多行的日誌進行處理 這個是官網上的說明
multiline filter
This filter will collapse multiline messages into a single event.
The multiline filter is for combining multiple events from a single source into the same event. 

下面看下格式

1

2

3

4

5

6

7

8

filter {

  multiline {

    type => "type"   #類型,很少說

    pattern => "pattern, a regexp" #參數,也能夠認爲是字符,有點像grep ,若是符合什麼字符就交給下面的 what 去處理

    negate => boolean

    what => "previous" or "next" #這個是符合上面 pattern 的要求後具體怎麼處理,處理方法有兩種,合併到上面一條日誌或者下面的日誌

  }

}

The 'negate' can be "true" or "false" (defaults false). If true, a message not matching the pattern will constitute a match of the multiline filter and the what will be applied. (vice-versa is also true)
這個 negate 有兩種 true 或者 false,默認是 true,若是選了false 的話估計就是取反的意思。
看看例子

1

2

3

4

5

6

filter {

  multiline {

    pattern => "^[^\[]"

    what => "previous"

  }

  }

這個例子是針對我上面的php日誌寫的,意思就是 若是不是以 "["開頭的日誌 都跟上一個日誌合併在一塊兒。以此類推遇到其餘的多行日誌也能夠按照這個方法來作合併。

二、logstash 根據@message內容來觸發命令"exec"
 我當初的想法是這樣的,若是php日誌文件中出現 "PHP Fatal error"的時候將相關的錯誤日誌發給相關開發的負責人。一開始想到了 output 的 email 功能,但我嘗試
了不少次這個email功能不太穩定,有時候能發出來郵件有的時候卻發不出來。不知道是郵件服務器的問題仍是 logstash自己的問題,具體配置以下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

output {

email {

   match => [ "@message""aaaaa" ]

   to => "storyskya@gmail.com"

   from => "monitor@mib.com.cn"

   options => [ "smtpIporHost""smtp.mibnet.com",

                "port""25",

                "userName""monitor@mib.com.cn",

                "starttls""true",

                "password""opmonitor",

                "authenticationType""login"

              ]

   subject => "123"

   body => '123'

   via => smtp

}

}

 

下面咱們介紹grop插件,對日誌文件的解析,

 

grok {
	pattern => "\[(?<level>\w*).*\] (?<datetime>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2},\d{3})\s"
}

上面的這個配置,就是將日誌文件進行了解析,其中的level/datetime等字段會被抽取出來做爲es的搜索鍵存在,可是整個日誌信息是存在於message這個字段中的,其他的鍵都是爲了找尋這條message,可是若是咱們想要改變這個message的信息,怎麼辦呢?這時候就須要用到match這個參數,他能夠對匹配成功的正則日誌,進行相應的處理,例如

 

日誌文件信息:  55.3.244.1 GET /index.html 15824 0.043

grok {
match => [ "message", "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}" ]
}

對其日誌進行匹配成功後呢,message信息就變成了這樣的,也就是說,對其日誌進行了match後呢,只要是知足正則的,那麼都會被存在於message中

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

在上面的正則中咱們看到了有IP,WORD這樣的字段,這些是logstash內置的正則表達式,在 https://github.com/elastic/logstash/blob/v1.4.2/patterns/grok-patterns 這裏都是能夠找到的,

我給出一個grop的正則在線測試的網址 http://grokdebug.herokuapp.com/

相關文章
相關標籤/搜索