重点参考:

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

  1. start_position:设置beginning保证从文件开头读取数据。
  2. path:填入文件路径。
  3. type:自定义类型为tradelog,由用户任意填写。
  4. codec:设置读取文件的编码为GB2312,用户也可以设置为UTF-8等等
  5. discover_interval:每隔多久去检查一次被监听的 path 下是否有新文件,默认值是15秒
  6. sincedb_path:设置记录源文件读取位置的文件,默认为文件所在位置的隐藏文件。
  7. 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

  1. start_position:设置beginning保证从文件开头读取数据。
  2. path:填入文件路径。
  3. type:自定义类型为tradelog,由用户任意填写。
  4. codec:multiline插件
  5. discover_interval:每隔多久去检查一次被监听的 path 下是否有新文件,默认值是15秒
  6. sincedb_path:设置记录源文件读取位置的文件,默认为文件所在位置的隐藏文件。
  7. 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的最佳实战-项目实战的更多相关文章

  1. Linux运维企业架构项目实战系列

    Linux运维企业架构项目实战系列 项目实战1—LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2—LVS.nginx实现负载均衡系列2.1 项目实战2.1—实现基于LVS负载均衡集群 ...

  2. Linux运维项目实战系列

    Linux运维项目实战系列 项目实战1-LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2-项目实战2-实现基于LVS负载均衡集群的电商网站架构 2.1项目实战2.1-nginx 反向 ...

  3. 云计算Docker全面项目实战(Maven+Jenkins、日志管理ELK、WordPress博客镜像)

    2013年,云计算领域从此多了一个名词“Docker”.以轻量著称,更好的去解决应用打包和部署.之前我们一直在构建Iaas,但通过Iaas去实现统一功  能还是相当复杂得,并且维护复杂.将特殊性封装到 ...

  4. Node.js 实战 & 最佳 Express 项目架构

    Node.js 实战 & 最佳 Express 项目架构 Express Koa refs https://github.com/xgqfrms/learn-node.js-by-practi ...

  5. 快读《ASP.NET Core技术内幕与项目实战》WebApi3.1:WebApi最佳实践

    本节内容,涉及到6.1-6.6(P155-182),以WebApi说明为主.主要NuGet包:无 一.创建WebApi的最佳实践,综合了RPC和Restful两种风格的特点 1 //定义Person类 ...

  6. Elasticsearch.net项目实战

    elasticsearch.net项目实战 目录 Elasticsearch+kibana 环境搭建 windows 10环境配置 安装Elasticsearch head安装(非必需) 安装kiba ...

  7. JavaEE在职加薪课好客租房项目实战视频教程

    JavaEE在职加薪课好客租房项目实战视频教程课程介绍:       本课程采用SOA架构思想进行设计,基于目前主流后端技术框架SpringBoot.SpringMVC.Mybaits.Dubbo等来 ...

  8. angularJs项目实战!02:前端的页面分解与组装

    自从上一篇文章到现在已经有将近一个月的时间,我将精力放在了前端页面分解与组装,和angularjs如何与jquery.bootstrap.D3等一系列其他类库结合使用的经验总结上.由于公司新招了一些员 ...

  9. 项目实战——企业级Zabbix监控实战(一)

    项目实战--企业级Zabbix监控实战 实验一:Zabbix监控的搭建 1.实验准备 centos系统服务器3台. 一台作为监控服务器, 两台台作为被监控节点, 配置好yum源. 防火墙关闭. 各节点 ...

随机推荐

  1. U-Boot添加menu命令的方法及U-Boot命令执行过程

    转;http://chenxing777414.blog.163.com/blog/static/186567350201141791224740/ 下面以添加menu命令(启动菜单)为例讲解U-Bo ...

  2. 课程学习:Linux系统管理

    版本 内核版本 发行版本 常见Linux发行版本 ubuntu: 易用,可靠:技术支持付费,生态稍弱 debin: 精简,稳定,可靠; 更新较慢, 无技术支持,软件过时, 企业不太用 opensuse ...

  3. JCA 了解

    JCA (J2EE 连接器架构,Java Connector Architecture)是对 J2EE标准集的重要补充.因为它注重的是将 Java程序连接到非Java程序和软件包中间件的开发.连接器特 ...

  4. logback中打印sql语句

    To log SQL statements for particular mybatis mapper set DEBUG (TRACE to see query parameters and res ...

  5. android 启动socket 失败:socket(af_inet sock_stream 0) 返回-1

    Android 启动socket 失败:socket(af_inet sock_stream 0) 返回-1 原因权限问题, 应该添加如下权限: <uses-permission android ...

  6. [转载]《Delphi 版 everything、光速搜索代码》 关于获取文件全路径 GetFullFileName 函数的优化

    Delphi 版 everything.光速搜索代码>,文章中关于获取文件全路径的函数:GetFullFileName,有一个地方值得优化. 就是有多个文件,它们可能属于同一个目录. 譬如 Sy ...

  7. limit是mysql的语法

    select * from table limit m,n 其中m是指记录开始的index,从0开始,表示第一条记录 n是指从第m+1条开始,取n条. , 即取出第3条至第6条,4条记录 转自:htt ...

  8. Android avd XDM authorization key matches an existing client

    在启动 android avd 调试程序的时候,突然出现这个错误; XDM authorization key matches an existing client avd 怎么也启动不起来.网上搜也 ...

  9. 【MVC5】后台修改的Model值反映不到客户端的问题

    画面上的检索结果有翻页功能,就在画面上追加了几个隐藏控件保存上次检索时的检索条件. 检索时更新这些隐藏控件的值,Debug时确实把Model中对应的属性值变掉了,但是到了客户端又变回之前的值了. 百思 ...

  10. HKC显示器开机亮一下就不显示了

    一台HKC显示器开机显一下就黑了 最近加了一个显示器做扩展屏幕,可以不亮有问题啊     芯片坏了引起的~ 不是自己的,不能拆机啊啊   文章来源:刘俊涛的博客 欢迎关注,有问题一起学习欢迎留言.评论 ...