ELK之logstash

ELK架构图:
logstash

官方网站:https://www.elastic.co/
logstash工作模式:Agent---Server
logstash工作流程:input---(filter,codec)---output
Agent与Server并无区别。
常用插件:
input plugins: stdin,file,redis,
filter plugins:grok,
output plugins:stdout,redis,elasticsearch,
logstash是属于重量级数据收集工具,需要有JDK环境。

部署JDK
# yum install -y java-1.8.0-openjdk-headles java-1.8.0-openjdk-devel java-1.8.0-openjdk
# echo "export JAVA_HOME=/usr" > /etc/profile.d/java.sh
# source /etc/profile.d/java.sh
安装Logstash

Logstash版本有:1.X,2.X,5.X
(vm做实验可以设置CPU双核四线程,2G内存,重量级)
# yum install -y logstash-1.5.4-1.noarch.rpm
# echo "export PATH=/opt/logstash/bin:$PATH" > /etc/profile.d/logstash.sh //logstash命令路径
# /etc/sysconfig/logstash 启动参数
# /etc/logstash/conf.d/ 此目录下的所有文件
# logstash --help //需要好一会儿才出现帮助,启动比较慢
编辑测试文件:
# vim /etc/logstash/conf.d/simple.conf
# input { //设置数据输入方式
# stdin {} //标准输入,键盘
# }
# output { //设置数据输出方式
# stdout { //标准输出,屏幕
# codec => rubydebug //采用输出格式
# }
# }
运行:
# logstash -f /etc/logstash/conf.d/simple.conf --configtest //测试配置文件编写是否正确
# Configuration OK
# logstash -f /etc/logstash/conf.d/simple.conf //运行
# Logstash startup completed //信息提示启动完成
# hello,logstash //此时等待我们从标准输入数据(键盘),接着会在标准输出(屏幕)打印如下数据
# {
# "message" => "hello,logstash",
# "@version" => "1",
# "@timestamp" => "2017-03-02T09:35:12.773Z",
# "host" => "elk"
# }
Logstash基本工作流程完成,接下来就是研究各类插件。

input plugins:file, udp

file作为数据输入,参考说明https://www.elastic.co/guide/en/logstash/1.5/plugins-inputs-file.html#_file_rotation //官方说明
# vim /etc/logstash/conf.d/file-simple.conf
# input {
# file {
# path => ["/var/log/httpd/access_log"] //数组,可以输入多个日志文件
# type => "system" //归类,可以在filter插件中调用
# start_position => "beginning" //文件内容的监控位置从最先开始,(日志滚动是从新的日志文件第一行开始监控)
# }
# }
# output {
# stdout {
# codec => rubydebug
# }
# }
# logstash -f /etc/logstash/conf.d/file-simple.conf --configtest
# logstash -f /etc/logstash/conf.d/file-simple.conf
采用udp方式来输入数据到logstash,官方说明:https://www.elastic.co/guide/en/logstash/1.5/plugins-inputs-udp.html
数据生产者将数据以udp协议的方式通过网络发送至logstash指定的udp端口
数据生产者采用collectd性能监控工具实现,epel源中安装。
# 另外一台主机
# yum install collectd -y
# [root@elknode1 ~]# grep -Ev "(#|$)" /etc/collectd.conf
# Hostname "elk-node1"
# LoadPlugin syslog
# LoadPlugin cpu
# LoadPlugin df
# LoadPlugin disk
# LoadPlugin interface
# LoadPlugin load
# LoadPlugin memory
# LoadPlugin network
# <Plugin network>
# <Server "192.168.9.77" "25826"> //将监控数据发送至此Server
# </Server>
# </Plugin>
# Include "/etc/collectd.d"
# systemctl start collectd.service
配置logstash文件:
# vim /etc/logstash/conf.d/udp-simple.conf
# input {
# udp {
# port => "25826"
# codec => collectd {}
# type => "collectd"
# }
# }
# output {
# stdout {
# codec => rubydebug
# }
# }
# logstash -f /etc/logstash/conf.d/udp-simple.conf --configtest
# logstash -f /etc/logstash/conf.d/udp-simple.conf
启动完成就会有日志信息送过来
# {
# "host" => "elk-node1",
# "@timestamp" => "2017-02-28T23:46:14.354Z",
# "plugin" => "disk",
# "plugin_instance" => "dm-1",
# "collectd_type" => "disk_ops",
# "read" => 322,
# "write" => 358,
# "@version" => "1",
# "type" => "collectd"
# }

filter plugins:grok(web日志核心插件)

grok用于分析并结构化文本数据
格式化模版:
/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-0.3.0/patterns 此目录下放置很多默认模版:
aws bro firewalls grok-patterns haproxy java junos linux-syslog mcollective mongodb nagios postgresql rails redis ruby
# COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} [%{HTTPDATE:timestamp}] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)
# 以上就是apache的common日志格式模版,
# 以IPORHOST为例:模版文件中定义了如何去匹配IP或者HOST
# IPORHOST (?:%{HOSTNAME}|%{IP})
# 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}
# IPV4 (?<

..)(?![0-9])
# IP (?:%{IPV6}|%{IPV4}) // ipv6太长了,就不复制贴上了
# 这个配置文件都定义好了,如何去匹配IP,HOST,HOSTNAME等各种各样的信息
# 当然也可以自定义
# %{SYNTAX:SEMANTIC}
SYNTAX:预定义模式名称(自定义有,没有的话需要自己定义),用于如何识别数据
SEMANTIC:匹配到的文本的自定义标识符
举个例子:
# 192.168.0.215 - - [02/Mar/2017:18:03:40 +0800] "GET /images/apache_pb.gif HTTP/1.1" 304 - "http://192.168.9.77/" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0"
# 以此日志为例,匹配模版如下:
# COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} [%{HTTPDATE:timestamp}] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)
# 格式化之后的信息如下
# clientip : 192.168.0.215
# ident : -
# auth : -
# timestamp : 02/Mar/2017:18:03:40 +0800
# verb : GET
# request : /images/apache_pb.gif
# httpversion : 1.1
# ......
测试匹配apache日志:
# vim /etc/logstash/conf.d/grok-apache.conf
# input {
# file {
# path => ["/var/log/httpd/access_log"]
# type => "apachelog"
# }
# }
# filter {
# grok {
# match => { "message" => "%{COMBINEDAPACHELOG}" }
# }
# }
# output {
# stdout {
# codec => rubydebug
# }
# }
# logstash -f /etc/logstash/conf.d/grok-apache.conf --configtest
# logstash -f /etc/logstash/conf.d/grok-apache.conf
输出显示:
# {
# "message" => "192.168.0.215 - - [02/Mar/2017:19:45:17 +0800] "GET /noindex/css/fonts/Bold/OpenSans-Bold.ttf HTTP/1.1" 404 238 "http://192.168.9.77/noindex/css/open-sans.css" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0"",
# "@version" => "1",
# "@timestamp" => "2017-03-02T11:45:17.834Z",
# "host" => "elk",
# "path" => "/var/log/httpd/access_log",
# "type" => "apachelog",
# "clientip" => "192.168.0.215",
# "ident" => "-",
# "auth" => "-",
# "timestamp" => "02/Mar/2017:19:45:17 +0800",
# "verb" => "GET",
# "request" => "/noindex/css/fonts/Bold/OpenSans-Bold.ttf",
# "httpversion" => "1.1",
# "response" => "404",
# "bytes" => "238",
# "referrer" => ""http://192.168.9.77/noindex/css/open-sans.css"",
# "agent" => ""Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0""
# }
测试匹配nginx日志:
需要自定义nginx日志,默认没有此日志模版,
在/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-0.3.0/patterns此目录下创建nginx文件
# NGUSERNAME [a-zA-Z.@-+_%]+
# NGUSER %{NGUSERNAME}
# NGINXACCESS %{IPORHOST:clientip} - %{NOTSPACE:remote_user} [%{HTTPDATE:timestamp}] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{NOTSPACE:http_x_forwarded_for}
nginx日志的logstash配置文件:
# vim /etc/logstash/conf.d/grok-nginx.conf
# input {
# file {
# path => ["/var/log/nginx/access.log"]
# type => "nginxlog"
# }
# }
# filter {
# grok {
# match => { "message" => "%{NGINXACCESS}" }
# }
# }
# output {
# stdout {
# codec => rubydebug
# }
# }
# logstash -f /etc/logstash/conf.d/grok-nginx.conf --configtest
# logstash -f /etc/logstash/conf.d/grok-nginx.conf
检查输出结构化数据信息:
# {
# "message" => "192.168.0.215 - - [02/Mar/2017:20:06:02 +0800] "GET /poweredby.png HTTP/1.1" 200 2811 "http://192.168.9.77/" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0" "-"",
# "@version" => "1",
# "@timestamp" => "2017-03-02T12:06:02.984Z",
# "host" => "elk",
# "path" => "/var/log/nginx/access.log",
# "type" => "nginxlog",
# "clientip" => "192.168.0.215",
# "remote_user" => "-",
# "timestamp" => "02/Mar/2017:20:06:02 +0800",
# "verb" => "GET",
# "request" => "/poweredby.png",
# "httpversion" => "1.1",
# "response" => "200",
# "bytes" => "2811",
# "referrer" => ""http://192.168.9.77/"",
# "agent" => ""Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0"",
# "http_x_forwarded_for" => ""-""
# }

output plugins:redis, elasticsearch

(在ELK图中logstash server的数据来源很有可能是redis,也就是在input plugins上采用redis插件)
redis作为数据输出对象,https://www.elastic.co/guide/en/logstash/1.5/plugins-outputs-redis.html
部署redis:
# yum install -y redis
# vim /etc/redis.conf
# bind 0.0.0.0
# systemctl start redis.service
测试redis正常工作:
# [root@elk patterns]# redis-cli
# 127.0.0.1:6379> SET name neo
# OK
# 127.0.0.1:6379> get name
# "neo"
# 127.0.0.1:6379>
将nginx日志数据结构化之后输出到redis数据库中:
# vim /etc/logstash/conf.d/grok-nginx-redis.conf
# input {
# file {
# path => ["/var/log/nginx/access.log"]
# type => "nginxlog"
# }
# }
# filter {
# grok {
# match => { "message" => "%{NGINXACCESS}" }
# }
# }
# output {
# redis {
# port => "redis"
# host => "192.168.9.77"
# data_type => "list" //list,channel两种模式
# key => "logstash-nginxlog" //The name of a Redis list or channel.
# }
# }
# logstash -f grok-nginx-redis.conf.conf --configtest
# systemctl -f /etc/logstash/conf.d/grok-nginx-redis.conf
在redis数据库中检查数据:
# [root@elk patterns]# redis-cli -h 192.168.9.77
# 192.168.9.77:6379> llen logstash-nginxlog
# (integer) 66
# 192.168.9.77:6379> lindex logstash-nginxlog 65
# "{"message":"192.168.0.215 - - [02/Mar/2017:21:38:07 +0800] \"GET /poweredby.png HTTP/1.1\" 200 2811 \"http://192.168.9.77/\" \"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0\" \"-\"","@version":"1","@timestamp":"2017-03-02T13:38:07.870Z","host":"elk","path":"/var/log/nginx/access.log","type":"nginxlog","clientip":"192.168.0.215","remote_user":"-","timestamp":"02/Mar/2017:21:38:07 +0800","verb":"GET","request":"/poweredby.png","httpversion":"1.1","response":"200","bytes":"2811","referrer":"\"http://192.168.9.77/\"","agent":"\"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0\"","http_x_forwarded_for":"\"-\""}"
# 192.168.9.77:6379>
#已经可以查看到redis收到了logstash发送过来的数据
elasticsearch作为logstash的数据输出对象:
# vim /etc/elasticsearch/elasticsearch.yml
# cluster.name: myes
# node.name: "elk"
# network.bind_host: 192.168.9.77
# transport.tcp.port: 9300
# http.port: 9200
配置elasticsearch输出的logstash配置文件:以访问日志文件作为输入,经过grok数据结构化处理输出至es
# vim /etc/logstash/conf.d/grok-nginx-es.conf
# input {
# file {
# path => ["/var/log/nginx/access.log"]
# type => "nginxlog"
# }
# }
# filter {
# grok {
# match => { "message" => "%{NGINXACCESS}" }
# }
# }
# output {
# elasticsearch {
# cluster => "myes"
# index => "logstash-%{+YYYY.MM.dd}"
# }
# }
# logstash -f /etc/logstash/conf.d/grok-nginx-es.conf --configtest
# logstash -f /etc/logstash/conf.d/grok-nginx-es.conf
测试查看es上的存储数据:
# [root@elk patterns]# curl -XGET 'http://192.168.9.77:9200/_cat/indices'
# yellow open .marvel-2017.03.02 1 1 15208 0 19.9mb 19.9mb
# yellow open .marvel-2017.03.01 1 1 2054 0 4.4mb 4.4mb
# yellow open logstash-2017.03.02 5 1 45 0 141.2kb 141.2kb
# logstash-2017.03.02 索引数据就是日志数据的索引
# curl -XGET 'http://192.168.9.77:9200/logstash-2017.03.02/_search?pretty' //查看所有数据
通过在es安装head插件,来web展示搜索数据:


redis作为logstash的数据输入源类似作为输出对象。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容