[elk]logstash的最佳实战-项目实战
重点参考:
http://blog.csdn.net/qq1032355091/article/details/52953837
不得不说这是一个伟大的项目实战,是正式踏入logstash门槛的捷径
Logstash的使用
logstash支持把配置写入文件 xxx.conf,然后通过读取配置文件来采集数据
./bin/logstash –f xxx.conf
logstash最终会把数据封装成json类型,默认会添加@timestamp时间字段、host主机字段、type字段。原消息数据会整个封装进message字段。如果数据处理过程中,用户解析添加了多个字段,则最终结果又会多出.。
Logstash的结构
Logstash由 input,filter,output三个组件去完成采集数据
如下是一个logstash的配置实例:
input {
file {
type => "log"
path => "/log/*/*.log"
discover_interval => 10
start_position => "beginning"
}
}
filter {
}
output {
elasticsearch {
index => "log-%{+YYYY.MM.dd}"
hosts => ["172.16.0.14:9200", "172.16.0.15:9200", "172.16.0.16:9200"]
}
stdout {codec => rubydebug}
}
input
input组件负责读取数据,可以采用file插件读取本地文本文件,stdin插件读取标准输入数据,tcp插件读取网络数据,log4j插件读取log4j发送过来的数据等等。
filter
filter插件负责过滤解析input读取的数据,可以用grok插件正则解析数据,date插件解析日期,json插件解析json等等。
output
output插件负责将filter处理过的数据输出。可以用elasticsearch插件输出到es,rediss插件输出到redis,stdout插件标准输出,kafka插件输出到kafka等等
trade.log日志采集。
trade.log日志采集
配置内容如下:
[ruby] view plain copy
input {
file {
type => "tradelog"
path => "/home/elk/his/trade.log*"
discover_interval => 5
start_position => "beginning"
sincedb_path => "/home/elk/myconf/sincedb_trade.txt"
sincedb_write_interval => 15
codec => plain { charset => "GB2312" }
}
}
filter {
grok {
match => { "message" => "%{DATESTAMP_CN:[@metadata][logdate]} .* - %{WORD:opeType}\|%{WORD:name}\|Oid: %{WORD:oid}\|IP: %{IP:ip}\|MAC: %{GREEDYDATA:mac}\|%{WORD:result}\|%{GREEDYDA
match => { "message" => "%{DATESTAMP_CN:[@metadata][logdate]} .* - %{WORD:opeType}\|%{WORD:name}\|Oid: %{WORD:oid}\|IP: %{IP:ip}\|MAC: %{GREEDYDATA:mac}\|%{WORD:result}\|" }
match => { "message" => "%{DATESTAMP_CN:[@metadata][logdate]} .* - %{WORD:opeType}\|%{WORD:name}\|Oid: %{WORD:oid}\|IP: %{IP:ip}\|MAC: %{GREEDYDATA:mac}\|" }
match => { "message" => "%{DATESTAMP_CN:[@metadata][logdate]} .* - %{WORD:opeType}\|IP: %{IP:ip}\|MAC: %{GREEDYDATA:mac}\|%{WORD:result}\|" }
match => { "message" => "%{DATESTAMP_CN:[@metadata][logdate]} .* - %{WORD:opeType}\|IP: %{IP:ip}\|MAC: %{GREEDYDATA:mac}\|" }
remove_field => "message"
}
date {
match => ["[@metadata][logdate]", "YYYY-MM-dd HH:mm:ss,SSS"]
}
}
output {
if "_grokparsefailure" not in [tags] and "_dateparsefailure" not in [tags] {
stdout {codec => rubydebug}
elasticsearch {
index => "log4j-tradelog"
hosts => ["168.7.1.67:9200"]
manage_template => true
template_overwrite => true
template_name => "log4j-tradelog"
template => "/home/elk/myconf/tradelog_template.json"
}
}
}
input
- start_position:设置beginning保证从文件开头读取数据。
- path:填入文件路径。
- type:自定义类型为tradelog,由用户任意填写。
- codec:设置读取文件的编码为GB2312,用户也可以设置为UTF-8等等
- discover_interval:每隔多久去检查一次被监听的 path 下是否有新文件,默认值是15秒
- sincedb_path:设置记录源文件读取位置的文件,默认为文件所在位置的隐藏文件。
- sincedb_write_interval:每隔15秒记录一下文件读取位置
filter
日志格式如下:
2016-05-09 09:49:13,817 [] [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)' [INFO ] com.c.command.StartLogCommand.execute(StartLogCommand.java:46) - FrontPage
2016-05-09 09:49:13,928 [] [ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)' [INFO ] com.c.command.EndLogCommand.execute(EndLogCommand.java:44) - FrontPageAdve|
grok插件
因为该日志中有5种格式如下,以最后几个我需要的字段为例说明:
交易名|登录名|编号|ip地址|mac地址|返回结果|异常信息
交易名|登录名|编号|ip地址|mac地址|返回结果|
交易名|登录名|编号|ip地址|mac地址|
交易名|ip地址|mac地址|返回结果|
交易名|ip地址|mac地址|
所以采用5种正则规则去匹配,logstash默认会从上到下按规则去匹配,直到匹配上为止。(日志中的多行错误信息,匹配不上,logstash会在tags字段添加”_ grokparsefailure”,所以后面输出的时候会用if条件.)
注意:5种正则规则的上下顺序,下面的规则放在上面会导致可能内容解析不全,比如源数据是:请求交易名|操作员登录名|操作员编号|ip地址|mac地址|返回结果|异常信息,如果按照“请求交易名|ip地址|mac地址。
logstash内置了很多正则匹配规则,用户可以直接调用这些规则来解析,例如%{WORD:result} 表示调用WORD规则(即识别字符串规则)来解析并最后赋值给result字段(result字段会自动创建)。
下面以第一条match规则为例来说明:
match => { "message" => "%{DATESTAMP_CN:[@metadata][logdate]} .* - %{WORD:opeType}\|%{WORD:name}\|Oid: %{WORD:oid}\|IP: %{IP:ip}\|MAC: %{GREEDYDATA:mac}\|%{WORD:result}\|%{GREEDYDATA:excep
首先行首使用DATESTAMP_CN规则来识别时间,并赋值给logdate字段名;然后.识别任意字符串(.代表任意一个字符,包括特殊字符,代表个数是任意个);然后使用WORD规则(即匹配字符串规则,不包含特殊字.。
注意:[@metadata]表示logdate这个字段在数据处理过程中只是一个临时字段,最后不会真的输出。避免了使用remove_field手动移除字段。
注意:logstash默认不支持”YYYY-MM-dd HH:mm:ss,SSS”格式的时间匹配,需要自己定义正则表达式到logstash-2.3.1/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-2.0.5/patterns/grok-patterns文件:
DATE_CN %{YEAR}[./-]%{MONTHNUM}[./-]%{MONTHDAY}
DATESTAMP_CN %{DATE_CN} %{TIME}
注意:logstash的正则表达式采用ruby语言正则表达式,具体语法可以参考网上。
remove_field => "message"表示解析完成之后删除原来的 message字段,避免重复。
date插件
match => ["[@metadata][logdate]", "YYYY-MM-dd HH:mm:ss,SSS"]
logstash默认的时间字段是@timestamp,如果不设置的话,默认是数据采集时候的时间,这里我们将日志打印的时间(即解析出的logdate字段的内容)设置为@timestamp内容,方便之后kibana根据时间检索。
注意:解析出来的@timestamp会比实际时间早8个小时,这是内置utc时间格式问题,kibana页面展示的时候会根据浏览器当前时区自动转换回来,这里不作处理。
output
if "_grokparsefailure" not in [tags] and "_dateparsefailure" not in [tags] {
stdout {codec => rubydebug}
elasticsearch {
index => "log4j-tradelog"
hosts => ["134.7.1.67:9200"]
manage_template => true
template_overwrite => true
template => "/home/elk/myconf/tradelog_template.json"
}
}
前面提到过,如果grok解析失败,会在tags字段自动添加_grokparsefailure值,如果date解析失败,会在tags字段自动添加_dateparsefailure值。所以最后的输出,我们采用条件过滤掉解析失败的行内容。最终的。
elasticsearch插件
index:要导入的es索引
host:es地址,有多个节点配置多个节点
template:指定elasticsearch的mapping模板文件,如果该索引不存在,logstash会根据这个mapping模板去自动创建索引。
stdout插件
rubydebug标准输出,便于调试,可以不使用该插件。
最终解析出结果示例如下:
{
"@version" => "1",
"@timestamp" => "2016-05-09T01:44:48.366Z",
"path" => "/home/elk/e.log",
"host" => "ccc7",
"type" => "tradelog",
"opeType" => "WZQry",
"name" => "lhcsssz2",
"oid" => "abzzak",
"ip" => "192.168.44.105",
"mac" => "A1345C05-26C1-4253-8845-01CFCA8EC4FD",
"result" => "Success"
}
error.log采集
日志实例:
2016-09-29 17:13:24,184|ncid=1100343164|oid=acaatv|loginName=zhenglw1|transId=Withdraw|traceId=N/A-_A-88C4D-043|exceptType=com.intenft.exception.AppRTException|exceptCode=CORESYST_TXN_NATI到
配置文件如下:
input {
file {
path => "/home/elk/his/error.log*"
type => "errorlog"
start_position => "beginning"
discover_interval => 5
codec => multiline {
charset => "GB2312"
pattern => "^%{DATESTAMP_CN}"
negate => true
what => "next"
}
sincedb_path => "/home/elk/myconf/sincedb_error.txt"
sincedb_write_interval => 15
}
}
filter {
grok {
match => { "message" => "%{DATESTAMP_CN:[@metadata][logdate]}%{GREEDYDATA:[@metadata][keyvalue]}" }
remove_field => "message"
}
date {
match => ["[@metadata][logdate]", "YYYY-MM-dd HH:mm:ss,SSS"]
}
kv {
source => "[@metadata][keyvalue]"
field_split => "\|"
value_split => "="
}
}
output {
if "multiline" in [tags] {
stdout {codec => rubydebug}
elasticsearch {
index => "log4j-errorlog-3"
hosts => ["168.7.1.67:9200"]
manage_template => true
template_overwrite => true
template => "/home/elk/myconf/errorlog_template.json"
}
}
}
input
- start_position:设置beginning保证从文件开头读取数据。
- path:填入文件路径。
- type:自定义类型为tradelog,由用户任意填写。
- codec:multiline插件
- discover_interval:每隔多久去检查一次被监听的 path 下是否有新文件,默认值是15秒
- sincedb_path:设置记录源文件读取位置的文件,默认为文件所在位置的隐藏文件。
- sincedb_write_interval:每隔15秒记录一下文件读取位置
multiline插件
logstash默认读取一行内容为一个消息,因为错误日志包含堆栈信息,多行对应一个消息,所以使用该插件合并多行为一条消息。
pattern:以”YYYY-MM-dd HH:mm:ss,SSS”格式开头的匹配为一条消息。
negate:true 表示正向使用该patttern
what:匹配到的日期属于下一条消息
charset:设置文件编码
filter
grok插件
匹配日期到logdata字段,匹配剩下的所有字符串到keyvalue临时字段,”GREEDYDATA”正则表达式为”.*”
date插件
match => ["[@metadata][logdate]", "YYYY-MM-dd HH:mm:ss,SSS"]
logstash默认的时间字段是@timestamp,如果不设置的话,默认是数据采集时候的时间,这里我们将日志打印的时间(即解析出的logdate字段的内容)设置为@timestamp内容,方便之后kibana根据时间检索。
注意:解析出来的@timestamp会比实际时间早8个小时,这是内置utc时间格式问题,kibana页面展示的时候会根据浏览器当前时区自动转换回来,这里不作处理。
kv插件
source:解析前面grok获取的keyvalue字段
(比如:|ncid=1100783164|oid=acaatv|loginName=zhew1|transId=Withdraw|traceId=N/A-_A-88C4D-043|exceptType=com.inteft.exception.AppRTException|exceptCode=CORESYST_TXN_NATIVE_89042|exceptMsg= .
field_split:按”|”切分key-value对
value_split:按”=”切分key 和 value,最终切分出来key作为字段名,value作为字段值
output
output {
if "multiline" in [tags] {
stdout {codec => rubydebug}
elasticsearch {
index => "log4j-errorlog-3"
hosts => ["168.7.1.67:9200"]
manage_template => true
template_overwrite => true
template => "/home/elk/myconf/errorlog_template.json"
}
}
}
该日志有2种格式的日志,一种是单行的错误信息日志,一种是多行的包含堆栈信息的日志,这2种日志内容重复,那么只需要解析单行格式的日志。kv插件解析多行格式的日志时, tags字段里没有”multipline”值.。
elasticsearch插件
index:要导入的es索引
host:es地址,有多个节点配置多个节点
template:指定elasticsearch的mapping模板文件,如果该索引不存在,logstash会根据这个mapping模板去自动创建索引。
最终解析的结果示例如下:
{
"@timestamp" => "2016-09-29T09:14:22.194Z",
"@version" => "1",
"tags" => [
[0] "multiline"
],
"path" => "/home/elk/stst.log",
"host" => "ci7",
"type" => "sttlog",
"ncid" => "1143164",
"oid" => "acav",
"loginName" => "zhew1",
"transId" => "MyQuery",
"traceId" => "N/A8C4E-047",
"exceptType" => "com.exception.AppRTException",
"exceptCode" => "CORESYNATIVE_82243",
"exceptMsg" => "对不起!根据账号获取客户信息错误"
}
总结:
注意:
logstash filter中的每一个插件都有add_field,remove_field,add_tag,remove_tag 4个功能。
附录:
mapping模板文件
tradelog:
{
"template": "log4j-tradelog*",
"settings": {
"index.number_of_shards": 3,
"number_of_replicas": 0
},
"mappings": {
"tradelog": {
"_all": {
"enabled": false
},
"properties": {
"@timestamp": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis",
"doc_values": true
},
"@version": {
"type": "string",
"index": "not_analyzed"
},
"exception": {
"type": "string",
"index": "analyzed"
},
"path": {
"type": "string",
"index": "not_analyzed"
},
"host": {
"type": "string",
"index": "not_analyzed"
},
"ip": {
"type": "ip",
"index": "not_analyzed"
},
"logger_name": {
"type": "string",
"index": "not_analyzed"
},
"mac": {
"type": "string",
"index": "not_analyzed"
},
"name": {
"type": "string",
"index": "not_analyzed"
},
"oid": {
"type": "string",
"index": "not_analyzed"
},
"opeType": {
"type": "string",
"index": "not_analyzed"
},
"priority": {
"type": "string",
"index": "not_analyzed"
},
"result": {
"type": "string",
"index": "not_analyzed"
},
"type": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
error.log
{
"template": "log4j-errorlog*",
"settings": {
"index.number_of_shards": 3,
"number_of_replicas": 0
},
"mappings": {
"errorlog": {
"_all": {
"enabled": false
},
"properties": {
"host": {
"type": "string",
"index": "not_analyzed"
},
"ncid": {
"type": "string",
"index": "not_analyzed"
},
"type": {
"type": "string",
"index": "not_analyzed"
},
"@version": {
"type": "string",
"index": "not_analyzed"
},
"exceptType": {
"type": "string",
"index": "not_analyzed"
},
"@timestamp": {
"format": "strict_date_optional_time||epoch_millis",
"type": "date"
},
"exceptCode": {
"type": "string",
"index": "not_analyzed"
},
"transId": {
"type": "string",
"index": "not_analyzed"
},
"priority": {
"type": "string",
"index": "not_analyzed"
},
"oid": {
"type": "string",
"index": "not_analyzed"
},
"traceId": {
"type": "string",
"index": "not_analyzed"
},
"exceptMsg": {
"type": "string",
"index": "analyzed"
},
"path": {
"type": "string",
"index": "not_analyzed"
},
"logger_name": {
"type": "string",
"index": "not_analyzed"
},
"loginName": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
[elk]logstash的最佳实战-项目实战的更多相关文章
- Linux运维企业架构项目实战系列
Linux运维企业架构项目实战系列 项目实战1—LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2—LVS.nginx实现负载均衡系列2.1 项目实战2.1—实现基于LVS负载均衡集群 ...
- Linux运维项目实战系列
Linux运维项目实战系列 项目实战1-LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2-项目实战2-实现基于LVS负载均衡集群的电商网站架构 2.1项目实战2.1-nginx 反向 ...
- 云计算Docker全面项目实战(Maven+Jenkins、日志管理ELK、WordPress博客镜像)
2013年,云计算领域从此多了一个名词“Docker”.以轻量著称,更好的去解决应用打包和部署.之前我们一直在构建Iaas,但通过Iaas去实现统一功 能还是相当复杂得,并且维护复杂.将特殊性封装到 ...
- Node.js 实战 & 最佳 Express 项目架构
Node.js 实战 & 最佳 Express 项目架构 Express Koa refs https://github.com/xgqfrms/learn-node.js-by-practi ...
- 快读《ASP.NET Core技术内幕与项目实战》WebApi3.1:WebApi最佳实践
本节内容,涉及到6.1-6.6(P155-182),以WebApi说明为主.主要NuGet包:无 一.创建WebApi的最佳实践,综合了RPC和Restful两种风格的特点 1 //定义Person类 ...
- Elasticsearch.net项目实战
elasticsearch.net项目实战 目录 Elasticsearch+kibana 环境搭建 windows 10环境配置 安装Elasticsearch head安装(非必需) 安装kiba ...
- JavaEE在职加薪课好客租房项目实战视频教程
JavaEE在职加薪课好客租房项目实战视频教程课程介绍: 本课程采用SOA架构思想进行设计,基于目前主流后端技术框架SpringBoot.SpringMVC.Mybaits.Dubbo等来 ...
- angularJs项目实战!02:前端的页面分解与组装
自从上一篇文章到现在已经有将近一个月的时间,我将精力放在了前端页面分解与组装,和angularjs如何与jquery.bootstrap.D3等一系列其他类库结合使用的经验总结上.由于公司新招了一些员 ...
- 项目实战——企业级Zabbix监控实战(一)
项目实战--企业级Zabbix监控实战 实验一:Zabbix监控的搭建 1.实验准备 centos系统服务器3台. 一台作为监控服务器, 两台台作为被监控节点, 配置好yum源. 防火墙关闭. 各节点 ...
随机推荐
- Android 卡顿优化 3 布局优化 工具 Hierarchy Viewer
欲善其事, 先利其器. 分析布局, 就不得不用到Hierarchy Viewer了. 本文工具使用皆以GithubApp的详情界面RepoDetailActivity为例说明. 为了不影响阅读体验, ...
- 对Storm ETL的初步思考
ETL简介 ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过萃取(extract).转置(transform).加载(load)至目的端的过程. ETL ...
- Java内存缓存
1.缓存为什么要存在 应用服务器资源是有限的,数据库每秒中接受请求的次数也是有限的.如果利用有限的资源来提供尽可能大的吞吐量呢,一个办法:减少计 算量,缩短请求流程(减少网络io或者硬盘io),这时候 ...
- oracle 解锁表的一个小问题
最近开发的时候遇到一个小问题,执行一段sql之后发现 表被锁了 显示错误为:ora-00054:resource busy and acquire with nowait specified 百度之后 ...
- JAVA的面向对象编程
JAVA的面向对象编程 面向对象主要针对面向过程. 面向过程的基本单元是函数. 什么是对象:EVERYTHING IS OBJECT(万物皆对象) 全部的事物都有两个方面: 有什么(属性):用来描写叙 ...
- 一个Tomcat配置参数引发的血案
转载:https://mp.weixin.qq.com/s/3IuTcDCTB3yIovp6o_vuKA 一.现象 有用户反馈访问PC首页偶尔会出现白页情况,也偶尔会收到听云的报警短信 二.监控(听云 ...
- DataBase 之 数据库设计六大范式
范式是符合某一种级别的关系模式的集合.关系数据库中的关系必须满足一定的要求,即满足不同的范式. 目前关系数据库有六种范式:第一范式(1NF).第二范式(2NF).第三范式(3NF).第四范式(4NF) ...
- Flutter网络请求与JSON解析
本文介绍如何在Flutter中创建HTTP网络请求和对请求的json string进行类型解析. 网络请求 官方使用的是用dart io中的HttpClient发起的请求,但HttpClient本身功 ...
- Python/MOOC /翻Wall和互联网编程的那些事
Python MOOC 翻Wall和互联网编程的那些事 声明: 1)本报告由博客园bitpeach撰写,版权所有,免费转载,请注明出处,并请勿作商业用途. 2)若本文档内有侵权文字或图片等内容,请联系 ...
- Odoo环境下Ubuntu服务器性能优化--参数调整
公司在使用Odoo进行内部信息化管理,随着业务增长,服务器性能问题变成了瓶颈,为了解决这些问题,最近的工作重点将移到性能调整上来,同时也会在此记录整个处理过程,以便日后回顾. 1.根据相关资料建议,在 ...