怎么样听起来挺厉害的吧?
在一个典型的使用场景下(ELK):用Elasticsearch做为后台数据的存储,kibana用来前端的报表展现。php
Logstash在其过程当中担任搬运工的角色,它为数据存储。报表查询和日志解析建立了一个功能强大的管道链。css
Logstash提供了多种多样的 input,filters,codecs和output组件,让使用者轻松实现强大的功能。好了让咱们開始吧
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)
curl -O https://download.elasticsearch.org/logstash/logstash/logstash-1.4.2.tar.gz现在你应该有了一个叫logstash-1.4.2.tar.gz的文件了。 咱们把它解压一下
tar zxvf logstash-1.4.2.tar.gz cd logstash-1.4.2现在咱们来执行一下:
bin/logstash -e 'input { stdin { } } output { stdout {} }'咱们现在可以在命令行下输入一些字符。而后咱们将看到logstash的输出内容:
hello world 2013-11-21T01:22:14.405+0000 0.0.0.0 hello worldOk,还挺有意思的吧... 以上样例咱们在执行logstash中,定义了一个叫"stdin"的input另外一个"stdout"的output,无论咱们输入什么字符。Logstash都会依照某种格式来返回咱们输入的字符。
这里注意咱们在命令行中使用了-e參数,该參数赞成Logstash直接经过命令行接受设置。这点尤为高速的帮助咱们重复的測试配置是否正确而不用写配置文件。前端
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,就可以使任意的格式化日志数据成为可能,从而订制更合理的存储格式为查询提供便利。
说的好,那么接下来咱们将创建Elasticsearch来存储输入到Logstash的日志数据。假设你尚未安装Elasticsearch。你可以下载RPM/DEB包或者手动下载tar包。经过下面命令:java
curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.1.1.tar.gz tar zxvf elasticsearch-1.1.1.tar.gz cd elasticsearch-1.1.1/ ./bin/elasticsearch
不一样的Logstash版本号都有相应的建议Elasticsearch版本号。请确认你使用的Logstash版本号!git
默认的配置对于Logstash和Elasticsearch已经足够,咱们忽略一些额外的选项来设置elasticsearch做为output:github
bin/logstash -e 'input { stdin { } } output { elasticsearch { host => localhost } }'任意的输入一些字符。Logstash会像以前同样处理日志(只是此次咱们将不会看到不论什么的输出,因为咱们没有设置stdout做为output选项)
you know, for logs咱们可以使用curl命令发送请求来查看ES是否接收到了数据:
curl 'http://localhost:9200/_search?pretty'返回内容例如如下:
{ "took" : 2, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 1.0, "hits" : [ { "_index" : "logstash-2013.11.21", "_type" : "logs", "_id" : "2ijaoKqARqGvbMgP3BspJA", "_score" : 1.0, "_source" : {"message":"you know, for logs","@timestamp":"2013-11-21T18:45:09.862Z","@version":"1","host":"my-laptop"} } ] } }恭喜,至此你已经成功利用Elasticsearch和Logstash来收集日志数据了。
安装elasticsearch-kopf,仅仅要在你安装Elasticsearch的文件夹中运行下面命令就能够:web
bin/plugin -install lmenezes/elasticsearch-kopf接下来訪问 http://localhost:9200/_plugin/kopf 来浏览保存在Elasticsearch中的数据,设置及映射!
bin/logstash -e 'input { stdin { } } output { elasticsearch { host => localhost } stdout { } }'当咱们输入了一些词组以后。这些输入的内容回回显到咱们的终端,同一时候还会保存到Elasticsearch!
(可以使用curl和kopf插件来验证)。redis
在午夜(GMT),Logstash本身主动依照时间戳更新索引。咱们可以根据追溯多长时间的数据做为根据来制定保持多少数据。固然你也可以把比較老的数据迁移到其它的地方(又一次索引)来方便查询,此外假设不过简单的删除一段时间数据咱们可以使用Elasticsearch Curator。shell
Logstash经过创建一条事件处理的管道。从你的日志提取出数据保存到Elasticsearch中。为高效的查询数据提供基础。
为了让你高速的了解Logstash提供的多种选项,让咱们先讨论一下最常用的一些配置。
不少其它的信息,请參考Logstash事件管道。
redis通常在Logstash消费集群中做为"broker"角色,保存events队列共Logstash消费。
Grok 是眼下最好的方式来将无结构的数据转换为有结构可查询的数据。
有120多种匹配规则,会有一种知足你的需要。
Codecs可以帮助你轻松的切割发送过来已经被序列化的数据。流行的codecs包含 json,msgpack,plain(text)。
比方:java异常信息和堆栈信息
内容例如如下:
input { stdin { } } output { elasticsearch { host => localhost } stdout { codec => rubydebug } }接下来,运行命令:
bin/logstash -f logstash-simple.conf咱们看到logstash依照你刚刚建立的配置文件来执行样例。这样更加的方便。注意,咱们使用-f參数来从文件获取而取代以前使用-e參数从命令行中获取配置。以上演示很easy的样例。固然解析来咱们继续写一些复杂一些的样例。
input { stdin { } } filter { grok { match => { "message" => "%{COMBINEDAPACHELOG}" } } date { match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ] } } output { elasticsearch { host => localhost } stdout { codec => rubydebug } }运行Logstash依照例如如下參数:
bin/logstash -f logstash-filter.conf
127.0.0.1 - - [11/Dec/2013:00:01:45 -0800] "GET /xampp/status.php HTTP/1.1" 200 3891 "http://cadenza/xampp/navi.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0"你将看到相似例如如下内容的反馈信息:
{ "message" => "127.0.0.1 - - [11/Dec/2013:00:01:45 -0800] \"GET /xampp/status.php HTTP/1.1\" 200 3891 \"http://cadenza/xampp/navi.php\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0\"", "@timestamp" => "2013-12-11T08:01:45.000Z", "@version" => "1", "host" => "cadenza", "clientip" => "127.0.0.1", "ident" => "-", "auth" => "-", "timestamp" => "11/Dec/2013:00:01:45 -0800", "verb" => "GET", "request" => "/xampp/status.php", "httpversion" => "1.1", "response" => "200", "bytes" => "3891", "referrer" => "\"http://cadenza/xampp/navi.php\"", "agent" => "\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0\"" }正像你看到的那样,Logstash(使用了grok过滤器)能够将一行的日志数据(Apache的"combined log"格式)切割设置为不一样的数据字段。这一点对于往后解析和查询咱们本身的日志数据很实用。比方:HTTP的返回状态码。IP地址相关等等。很的easy。不多有匹配规则没有被grok包括,因此假设你正尝试的解析一些常见的日志格式。也许已经有人为了作了这种工做。假设查看具体匹配规则。參考logstash grok patterns。
你或许注意到在这个样例中@timestamp字段是设置成December 11, 2013, 说明logstash在日志产生以后一段时间进行处理的。这个字段在处理日志中回添到数据中的,举例来讲... 这个值就是logstash处理event的时间戳。
首先。咱们建立一个文件名称是logstash-apache.conf的配置文件。内容例如如下(你可以依据实际状况改动你的文件名称和路径):
input { file { path => "/tmp/access_log" start_position => beginning } } filter { if [path] =~ "access" { mutate { replace => { "type" => "apache_access" } } grok { match => { "message" => "%{COMBINEDAPACHELOG}" } } } date { match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ] } } output { elasticsearch { host => localhost } stdout { codec => rubydebug } }接下来。咱们依照上面的配置建立一个文件(在样例中是"/tmp/access.log"),可以将如下日志信息做为文件内容(也可以用你本身的webserver产生的日志):
71.141.244.242 - kurt [18/May/2011:01:48:10 -0700] "GET /admin HTTP/1.1" 301 566 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3" 134.39.72.245 - - [18/May/2011:12:40:18 -0700] "GET /favicon.ico HTTP/1.1" 200 1189 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.2; .NET4.0C; .NET4.0E)" 98.83.179.51 - - [18/May/2011:19:35:08 -0700] "GET /css/main.css HTTP/1.1" 200 1837 "http://www.safesand.com/information.htm" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"现在使用-f參数来运行一下上面的样例:
bin/logstash -f logstash-apache.conf
此外,数据中type的字段值会被替换成"apache_access"(这个功能在配置中已经指定)。
input { file { path => "/tmp/*_log" ...
然而,假设你检查了你的数据(或许用elasticsearch-kopf),你将发现access_log日志被分红不一样的字段,但是error_log确没有这样。这是因为咱们使用了“grok”filter并只配置匹配combinedapachelog日志格式,这样知足条件的日志就会本身主动的被切割成不一样的字段。咱们可以经过控制日志依照它本身的某种格式来解析日志,不是很是好的吗?对吧。
这个概念普通状况下应该被大多数的Logstash用户熟悉掌握。
你可以像其它普通的编程语言同样来使用if,else if和else语句。让咱们把每个event依赖的日志文件类型都标记出来(access_log,error_log其它以log结尾的日志文件)。
input { file { path => "/tmp/*_log" } } filter { if [path] =~ "access" { mutate { replace => { type => "apache_access" } } grok { match => { "message" => "%{COMBINEDAPACHELOG}" } } date { match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ] } } else if [path] =~ "error" { mutate { replace => { type => "apache_error" } } } else { mutate { replace => { type => "random_logs" } } } } output { elasticsearch { host => localhost } stdout { codec => rubydebug } }
input { tcp { port => 5000 type => syslog } udp { port => 5000 type => syslog } } filter { if [type] == "syslog" { grok { match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" } add_field => [ "received_at", "%{@timestamp}" ] add_field => [ "received_from", "%{host}" ] } syslog_pri { } date { match => [ "syslog_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ] } } } output { elasticsearch { host => localhost } stdout { codec => rubydebug } }
bin/logstash -f logstash-syslog.conf
首先咱们打开一个新的shell窗体,而后输入如下的命令:
telnet localhost 5000
Dec 23 12:11:43 louis postfix/smtpd[31499]: connect from unknown[95.75.93.154] Dec 23 14:42:56 louis named[16000]: client 199.48.164.7#64817: query (cache) 'amsterdamboothuren.com/MX/IN' denied Dec 23 14:30:01 louis CRON[619]: (www-data) CMD (php /usr/share/cacti/site/poller.php >/dev/null 2>/var/log/cacti/poller-error.log) Dec 22 18:28:06 louis rsyslogd: [origin software="rsyslogd" swVersion="4.2.0" x-pid="2253" x-info="http://www.rsyslog.com"] rsyslogd was HUPed, type 'lightweight'.
{ "message" => "Dec 23 14:30:01 louis CRON[619]: (www-data) CMD (php /usr/share/cacti/site/poller.php >/dev/null 2>/var/log/cacti/poller-error.log)", "@timestamp" => "2013-12-23T22:30:01.000Z", "@version" => "1", "type" => "syslog", "host" => "0:0:0:0:0:0:0:1:52617", "syslog_timestamp" => "Dec 23 14:30:01", "syslog_hostname" => "louis", "syslog_program" => "CRON", "syslog_pid" => "619", "syslog_message" => "(www-data) CMD (php /usr/share/cacti/site/poller.php >/dev/null 2>/var/log/cacti/poller-error.log)", "received_at" => "2013-12-23 22:49:22 UTC", "received_from" => "0:0:0:0:0:0:0:1:52617", "syslog_severity_code" => 5, "syslog_facility_code" => 1, "syslog_facility" => "user-level", "syslog_severity" => "notice" }