ElasticSearch实战系列七: Logstash实战使用-图文讲解
前言
在上一篇中我们介绍了Logstash快速入门,本文主要介绍的是ELK日志系统中的Logstash的实战使用。实战使用我打算从以下的几个场景来进行讲解。
时区问题解决方案
在我们使用logstash将采集的数据传输到ES中的时候,会发现采集的时间@timestamp
的时间和我们本地的不一致,这个主要是因为时区的问题导致的,我们在计算时间的时候需要将这个时间增加8小时,但是这样会很不方便。为了永久解决这个问题,我们可以在logstash中的filter中对该字段进行转换,增加8小时。
添加的配置如下:
ruby {
code => "event.set('timestamp', event.get('@timestamp').time.localtime + 8*60*60)"
}
ruby {
code => "event.set('@timestamp',event.get('timestamp'))"
}
mutate {
remove_field => ["timestamp"]
}
原本示例图:
添加配置之后的示例图:
可以看到添加配置之后@timestamp
时间已经和本地时间基本一致了。
日志内容切分
我们在进行采集日志到ES中的时候,有时需要对日志内容进行切割。比如得到日志内容的时间以及日志级别等等。这时我们就可以通过grok来对日志内容进行切分,比如将制定好的日志内容切割为日志时间、线程名称、日志级别、类名以及详细内容等等。我们只需要在logstash的filter中使用grok语法即可完成日志内容切割。
这里我们使用JAVA的Logback来制定日志输出格式,然后通过日志的格式编写grok语法,最后将grok配置添加到logstash的filter中。
Logback输出配置:
|%d{yyyy-MM-dd HH:mm:ss.SSS}|[%thread]|%-5level|%logger{50}|-%msg%n
日志样例数据:
|2020-07-24 17:08:33.159|[Thread-5]|INFO|com.pancm.Application|-测试示例三: All things in their being are good for something. 天生我才必有用3
grok模式:
|%{DATA:log_time}|%{DATA:thread}|%{DATA:log_level}|%{DATA:class_name}|-%{GREEDYDATA:content}
使用grok分析
可以看到以及分析匹配成功了。
然后我们在filter中添加如下配置:
grok {
match => { "message" =>"|%{DATA:log_time}|%{DATA:thread}|%{DATA:log_level}|%{DATA:class_name}|-%{GREEDYDATA:content}"
}
}
最终输出的日志到ES的示例图:
自定义模板
我们在使用Logstash采集日志的时候,如果没有指定索引库或模板,则会使用ElasticSearch默认自带的名字为”logstash”的模板,默认应用于Logstash写入数据到ElasticSearch使用。但是我们希望使用自定义的索引模板,将采集的日志按照我们自身的想法来写入,此时我们就需要用到自定义模板了。
主要有两种方式,一种是在logstash的output插件中使用template指定本机器上的一个模板json路径, 例如 template => "/home/logstash.json"
,json里面的内容为我们自定的索引mapping,虽然这种方式简单,但是分散在Logstash机器上,维护起来比较麻烦。还有一种是在elasticsearc服务端自定义配置模板,事先将模板设置好,然后在logstash的output输出中指定该模板即可,这种方式比较灵活方便,可动态更改,全局生效。
这里我们还是通过一个示例来进行说明,我们首先创建一个template_mylog的模板,配置这几个字段:
log_time、thread、log_level、class_name、content。
语句如下:
PUT _template/template_mylog
{
"index_patterns" : [
"mylog-*"
],
"order" : 10,
"settings": {
"index.number_of_shards": 3,
"number_of_replicas": 1
},
"mappings" : {
"properties" : {
"log_level" : { "type" : "keyword" },
"thread" : { "type" : "keyword" },
"class_name" : { "type" : "keyword" },
"content" : { "type" : "keyword" },
"log_time" : { "type" : "date","format" : "yyyy-MM-dd HH:mm:ss.SSS"}
}
}
}
示例图:
注:上述的配置比其他mapping而言多了两个新配置,一个是index_patterns,该配置表明自动创建的索引开头以mylog-
的索引库都会采用该模板;而order表示顺序级别,在有相同的索引模板中,该值越大,优先级越高。
创建成功之后,我们只需在output中的添加如下配置即可。
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "mylog-%{+YYYY.MM.dd}"
}
然后我们启动logstash进行日志的采集。
效果图:
写入多个索引库
我们在使用logstash采集日志的时候,有时有多种不同的日志并且需要采集到不同的索引库中,这时我们就可以通过标记来进行写入。比如采集/home/logs目录下的日志我定义一个标记为java,采集/home/logs2目录下的日志我定义一个标记为java2,那么在写入ElasticSearch的时候只需要根据该标记区分写入即可。
logstash input配置示例:
file {
path => ["/home/logs/mylog-2020-08-13.0.txt"]
type => "java"
start_position => "beginning"
sincedb_path => "/dev/null"
}
file {
path => ["/home/logs2/*.txt"]
type => "java2"
start_position => "beginning"
sincedb_path => "/dev/null"
}
logstash output配置示例:
if [type] == "java"{
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "mylog-%{+YYYY.MM.dd}"
}
}
if [type] == "java2"{
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "mylog-%{+YYYY.MM}"
}
}
示例图在多行内容合并场景中。
多行内容合并
我们在采集日志的时候,经常会遇到异常日志,并且异常日志并非为一行内容,如果我们按照原有的方式采集,在ElasticSearch中显示的是一行一行的内容,这样的话我们排查问题会很头疼。幸好Logstash中支持多行日志合并,使用multiline.pattern、multiline.negate和multiline.what来实现配置实现。
下面的配置中,我们通过制定匹配规则将以空格开头的所有行合并到上一行,并把以Caused by开头的也追加到上一行。
在Logstash的input配置中添加如下配置:
codec => multiline {
pattern => "\s*\["
negate => "true"
what => "previous"
}
异常日志:
原异常日志在ElasticSearch中示例图:
多行合并之后的效果图:
完整配置
logstash-test.conf 配置
input{
file {
path => ["/home/logs/mylog-2020-08-13.0.txt"]
type => "java"
start_position => "beginning"
sincedb_path => "/dev/null"
}
file {
path => ["/home/logs2/*.txt"]
type => "java2"
codec => multiline {
pattern => "\s*\["
negate => "true"
what => "previous"
}
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
grok {
match => { "message" =>"\|%{DATA:log_time}\|%{DATA:thread}\|%{DATA:log_level}\|%{DATA:class_name}\|-%{GREEDYDATA:content}" }
}
ruby {
code => "event.set('timestamp', event.get('@timestamp').time.localtime + 8*60*60)"
}
ruby {
code => "event.set('@timestamp',event.get('timestamp'))"
}
mutate {
remove_field => ["timestamp"]
}
}
output {
stdout {
codec => rubydebug
}
if [type] == "java"{
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "mylog-%{+YYYY.MM.dd}"
}
}
if [type] == "java2"{
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "mylog-%{+YYYY.MM}"
}
}
}
异常问题解决方案
1.logstash: Could not execute action: PipelineAction::Create, action_result: false
解决办法: 斜杆采用“/”
2, logstash: object mapping for [host] tried to parse field [host] as object, but found a concrete value
解决办法: 在filter里面添加如下配置:
mutate {
rename => { "host" => "host.name" }
}
其它
- ElasticSearch实战系列一: ElasticSearch集群+Kinaba安装教程
- ElasticSearch实战系列二: ElasticSearch的DSL语句使用教程---图文详解
- ElasticSearch实战系列三: ElasticSearch的JAVA API使用教程
- ElasticSearch实战系列四: ElasticSearch理论知识介绍
- ElasticSearch实战系列五: ElasticSearch的聚合查询基础使用教程之度量(Metric)聚合
- ElasticSearch实战系列六: Logstash快速入门
音乐推荐
原创不易,如果感觉不错,希望给个推荐!您的支持是我写作的最大动力!
版权声明:
作者:虚无境
博客园出处:http://www.cnblogs.com/xuwujing
CSDN出处:http://blog.csdn.net/qazwsxpcm
个人博客出处:http://www.panchengming.com
ElasticSearch实战系列七: Logstash实战使用-图文讲解的更多相关文章
- ElasticSearch实战系列六: Logstash快速入门和实战
前言 本文主要介绍的是ELK日志系统中的Logstash快速入门和实战 ELK介绍 ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是 ...
- MP实战系列(七)之集成springboot
springboot是现在比较流行的微服使用的框架,springboot本质上就是将spring+springmvc+mybatis零配置化,基本上springboot的默认配置符合我们的开发.当然有 ...
- ATT&CK实战系列 红队实战(一)————环境搭建
首先感谢红日安全团队分享的靶机实战环境.红队实战系列,主要以真实企业环境为实例搭建一系列靶场,通过练习.视频教程.博客三位一体学习. 靶机下载地址:http://vulnstack.qiyuanxue ...
- memcached实战系列(七)理解Memcached的数据过期方式、新建过程、查找过程
1.1.1. 新建Item分配内存过程 1:快速定位slab classid,先计算Item长度 key键长+flag+suffix(16字节)+value值长+结构大小(32字节),如90byte ...
- shiro实战系列(七)之Realm
Realm 是一个能够访问应用程序特定的安全数据(如用户.角色及权限)的组件.Realm 将应用程序特定的数据转 换成一种 Shiro 能够理解的格式,这样 Shiro 能够提供一个单一的易理解的 S ...
- ElasticSearch优化系列七:优化建议
尽量运行在Sun/Oracle JDK1.7以上环境中,低版本的jdk容易出现莫名的bug,ES性能体现在在分布式计算中,一个节点是不足以测试出其性能,一个生产系统至少在三个节点以上. ES集群节点规 ...
- Elasticsearch学习系列七(Es分布式集群)
核心概念 集群(Cluster) 一个Es集群由多个节点(Node)组成,每个集群都有一个共同的集群名称作为标识 节点(Node) 一个Es实例就是一个Node.Es的配置文件中可以通过node.ma ...
- ATT&CK实战系列——红队实战(一)
一.环境搭建 1.环境搭建测试 最近想要开始学习内网渗透,搜集了一些教程,准备先实验一个vulnstack靶机,熟悉一下内网渗透操作再学习基础知识. 靶场下载地址:http://vulnstack.q ...
- 【红日安全-VulnStack】ATT&CK实战系列——红队实战(二)
一.环境搭建 1.1 靶场下载 靶场下载地址:http://vulnstack.qiyuanxuetang.net/vuln/detail/3/ 靶机通用密码: 1qaz@WSX 1.2 环境配置 ...
随机推荐
- 题解 UVA501 【Black Box】
思路与中位数一题,解决方案比较像,使用对顶堆来解决. 具体实现为,使用两个堆,大根堆维护较小的值,小根堆维护较大的值,即小根堆的堆顶是较大的数中最小的,大根堆的堆顶是较小的数中最大的. 将大于大根堆堆 ...
- python爬虫入门(3)----- scrapy
scrapy 简介 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 其最初是为了 页面抓取 (更确切来说, 网络 ...
- LeetCode 86 | 链表基础,一次遍历处理链表中所有符合条件的元素
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第53篇文章,我们一起来看LeetCode第86题,Partition List(链表归并). 本题的官方难度是M ...
- js获得url地址携带参数
function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...
- java 控制语句、数组、方法
一.控制语句 1.if 语句 if语句是指如果满足某种条件,就进行某种处理. 流程图: 2. if…else语句 语法格式: if (判断条件){ 执行语句1 …… }else{ 执行语句2 …… } ...
- PD快充和QC快充
参考链接:https://zhidao.baidu.com/question/246420719602653564.html PD快充协议 PD即USB Power Delivery Specific ...
- MacOS下如何设置hosts?
hosts文件是什么? hosts文件是一个系统文件,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”.当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中 ...
- __getattribute__小例子
class student(object): def __init__(self,name=None,age=None): self.name = name self.age = age def __ ...
- java反序列化——apache-shiro复现分析
本文首发于“合天智汇”公众号 作者:Fortheone 看了好久的文章才开始分析调试java的cc链,这个链算是java反序列化漏洞里的基础了.分析调试的shiro也是直接使用了cc链.首先先了解一些 ...
- css浮动属性
1.为什么需要浮动 HTML中的标签元素大致分为三类:块状元素.内联元素.内联块元素. 每种元素都有其各自的特点,其中块状元素会独占一行,而内联元素和内联块元素则会在一行内显示.如果我们想让两个甚至多 ...