概述
logstash是负责采集和解析日志的,将日志解析成需要的格式存储在elasticsearch或者其他地方。logstash提供了很多非常强大的插件,这些插件可以有效的把日志信息转换成需要的格式。
一:安装
首先取官网下载logstash安装包,这次版本选择最新的6.1.1
安装:wget https://artifacts.elastic.co/downloads/logstash/logstash-6.1.1.tar.gz
解压
二:配置
logstash提供了非常多的插件,使用这些插件需要配置启动文件。启动配置文件的编写对于logstash至关重要,可以说logstash就是依靠强大的配置文件来工作的。
logstash的配置文件主要分为三个部分input,filter和output。
intput负责从各个地方获取日志信息,filter负责解析和转换日志信息为需要的格式,譬如json,output负责将解析后的日志信息发送到指定的地方。
输入插件(input)配置
输入插件根据现在的使用场景主要从filebeat或者kafka接受日志信息。
从filebeat接受消息
input {
beats {
port => 5044
}
}
从kafka接受消息
input {
kafka {
zk_connect => "localhost:2181" #zookeeper地址
topic_id => "nginx-access-log" #kafka中topic名称,记得创建该topic
group_id => "nginx-access-log" #默认为“logstash”
codec => "plain" #与Shipper端output配置项一致
consumer_threads => 1 #消费的线程数
decorate_events => true #在输出消息的时候回输出自身的信息,包括:消费消息的大小、topic来源以及consumer的group信息。
type => "nginx-access-log"
}
}
过滤器插件(Filter)配置
丰富的过滤器插件的存在是 logstash 威力如此强大的重要因素。名为过滤器,其实提供的不单单是过滤的功能。它扩展了进入过滤器的原始数据,进行复杂的逻辑处理,甚至可以无中生有的添加新的 logstash
事件到后续的流程中去!
Grok 正则捕获
Grok 正则捕获是logstash最核心的功能,它的作用是将输入的字符串解析成需要的数据格式。logstash提供了一些默认的正则表达式,也可以自己定义正则表达式。
正则表达式检测网站: http://grokdebug.herokuapp.com/
这个网站可以检测编写的正则表达式是否正确,也提供了默认的正则表达式查看。
gork插件用法
filter {
grok {
match => {
"message" => "\s+(?<request_time>\d+(?:\.\d+)?)\s+"
}
}
}
使用默认正则表达式解析nginx日志
首先要定义nginx日志格式
log_format custom '[$time_local] $server_addr $remote_addr $body_bytes_sent $request_time $upstream_response_time ''$upstream_addr $upstream_status "$request_uri" "$http_x_forwarded_for" "$http_referer" "$http_user_agent" $status';
然后编写相应的gork日志解析文件
NGINXACCESS \[%{HTTPDATE:logtime}\] %{IPORHOST:host} %{IPORHOST:remoteaddr} (?:%{NUMBER:size}|-) %{NUMBER:responsetime} (?:%{NUMBER:upstreamtime}|-) %{URIHOST:upstreamhost} %{BASE10NUM:upstreamstatus} %{QS:url} %{QS:clientip} %{QS:referrer} %{QS:agent} %{INT:status}
在logstash中引用日志文件所在的文件夹就可以使用了
grok {
patterns_dir => "/data1/app/logstash-5.5.2/pattern"
match => {
"message" => "%{NGINXACCESS}"
}
}
使用自定义增则表达式解析Java日志
很多时候收集各个业务系统日志的时候会定义一套根据业务产生的日志。这时候就需要自定义的增则表达式了
配置Java中logback或者log4j输出日志格式:
logging.pattern.file=%d{yyyy-MM-dd HH\:mm\:ss} %p [%c]\: %m%n
编写自定义的日志解析文件
DATE ([1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d)
JAVALOG %{DATE:time} %{WORD:level} \[%{JAVACLASS:class}\]: %{GREEDYDATA:message}
在logstash中配置
grok {
patterns_dir => "/data1/app/logstash-5.5.2/pattern"
match => {
"message" => "%{JAVALOG}"
}
}
时间处理(Date)插件
很多时候日志的日志logstash并不能识别,这时候filters/date 插件可以用来转换你的日志记录中的时间字符串,变成 LogStash::Timestamp 对象,然后转存到 @timestamp 字段里。
date {
match => ["logtime", "dd/MMM/yyyy:HH:mm:ss Z"]
target => "@timestamp"
}
数据修改(Mutate)
filters/mutate 插件是 Logstash 另一个重要插件。它提供了丰富的基础类型数据处理能力。包括类型转换,字符串处理和字段处理等。可以设置的转换类型包括:”integer”,”float” 和 “string”
转换nginx日志格式
mutate {
convert => {
"responsetime" => "float"
"upstreamtime" => "float"
"size" => "integer"
}
}
输出(output)插件
输出插件会将解析后的日志输出到elasticsearch或者其他什么地方。这时候就需要定义一些配置来定义输出条件。
document_id=>” ” 为索引提供document id ,对重写elasticsearch中相同id词目很有用
document_type=>” ”事件要被写入的document type,一般要将相似事件写入同一type,可用%{}引用事件type,默认type=log
index=>”logstash-%{+YYYY,MM.dd}” 事件要被写进的索引,可是动态的用%{foo}语句
hosts=>[“127.0.0.0”] [“127.0.0.1:9200”,”127.0.0.2:9200”] [“https://127.0.0.1:9200“][“https://127.0.0.1:9200/mypath“]
manage_template=>true 一个默认的es mapping 模板将启用(除非设置为false 用自己的template)
template=>”” 有效的filepath 设置自己的template文件路径,不设置就用已有的
template_name=>”logstash” 在es内部模板的名字。
配置格式
output {
elasticsearch {
hosts => "xxx:9200"
manage_template => true
index => "%{[fields][logIndex]}-%{+YYYY.MM.dd}"
document_type => "%{[fields][docType]}"
template_overwrite=> true
}
if [fields][logIndex] == "tomcat" {
kafka {
codec => json
bootstrap_servers => "xxx:9092"
topic_id => "tomcat-log"
codec => plain {
format => "%{message}"
}
}
}
}
其中模板的配置十分重要,日志解析成固定的格式后还需要elasticsearch的模板配合,将该格式存储为指定的数据类型。譬如将需要分词的数据存储为text类型,需要固定查询的数据存储为key类型。
编码插件(Codec)
在此之前,logstash 只支持纯文本形式输入,然后以过滤器处理它。但现在,我们可以在输入输出期处理不同类型的数据,这全是因为有了 codec 设置。
codec 的引入,使得 logstash 可以更好更方便的与其他有自定义数据格式的运维产品共存,比如graphite、fluent、netflow、collectd,以及使用 msgpack、json、edn 等通用数据格式的其他产品等。
上面发送给kafka的日志数据,我旧使用了codec插件将日志信息转换为了json数据格式,不然kafka接收到的消息就只是一个消息名称。
codec => json