logstash详解

Logstash

官网

Logstash 是免费且开放的服务器端数据处理管道,能够从多个来源采集数据,转换数据,然后将数据发送到您最喜欢的存储库中。

官网



核心概念

Pipeline

  • 包含了input—filter—output三个阶段的处理流程
  • 插件生命周期管理
  • 队列管理

Logstash Event

  • 数据在内部流转时的具体表现形式。数据在input 阶段被转换为Event,在 output被转化成目标格式数据
  • Event 其实是一个Java Object,在配置文件中,可以对Event 的属性进行增删改查

Codec (Code / Decode)

  • 编码与解码。将原始数据decode成Event; 将Event encode成目标数据

在这里插入图片描述



数据传输原理

  1. 数据采集与输入

    Logstash支持各种输入选择,能够以连续的流式传输方式,轻松地从日志、指标、Web应用以及数据存储中采集数据。

  2. 实时解析和数据转换

    通过Logstash过滤器解析各个事件,识别已命名的字段来构建结构,并将它们转换成通用格式,最终将数据从源端传输到存储库中。

  3. 存储与数据导出

    Logstash提供多种输出选择,可以将数据发送到指定的地方。

Logstash通过管道完成数据的采集与处理,管道配置中包含input、output和filter(可选)插件,input和output用来配置输入和输出数据源、filter用来对数据进行过滤或预处理。

在这里插入图片描述



安装

需要jdk环境

官方文档

下载并解压logstash

下载地址 , 选择7.17.3版本

#下载Logstash
#windows
https://artifacts.elastic.co/downloads/logstash/logstash-7.17.3-windows-x86_64.zip
#linux
https://artifacts.elastic.co/downloads/logstash/logstash-7.17.3-linux-x86_64.tar.gz



测试:运行最基本的logstash管道

[root@hs-es-node1 ~]# cd logstash-7.17.3
#-e选项表示,直接把配置放在命令中,这样可以有效快速进行测试    stdin { }表示的是标准控制台
[root@hs-es-node1 logstash-7.17.3]# bin/logstash -e 'input { stdin { } } output { stdout {} }'



Logstash配置文件结构

参考:https://www.elastic.co/guide/en/logstash/7.17/configuration.html

Logstash的管道配置文件对每种类型的插件都提供了一个单独的配置部分,用于处理管道事件。

[root@hs-es-node1 logstash-7.17.3]# vim logstash-demo.conf

input {
  stdin { }			# 控制台输入
}

filter {
  grok {		# grok 正则匹配解析
    match => { "message" => "%{COMBINEDAPACHELOG}" }
  }
  date {		# 日期解析 
    match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
  }
}

output {
  elasticsearch { hosts => ["localhost:9200"]}  			# 输出到本机的es中
  stdout { codec => rubydebug }			# stdout表示控制台,使用 rubydebug 输出详细格式
}

每个配置部分可以包含一个或多个插件。例如,指定多个filter插件,Logstash会按照它们在配置文件中出现的顺序进行处理。

#运行 通过-f指定配置文件  也可以加上-t参数 检查配置文件是否存在语法错误
[root@hs-es-node1 logstash-7.17.3]# bin/logstash -f logstash-demo.conf -t
[root@hs-es-node1 logstash-7.17.3]# bin/logstash -f logstash-demo.conf




在这里插入图片描述

在这里插入图片描述



output部分做以下修改

output {
  elasticsearch { 
  	hosts => ["localhost:9200"]
  	index => "hs_test"		# 指定数据写入到哪一个index索引中
  	user => "elastic"
    password => "123456"
  }  			
  stdout { codec => rubydebug }			
}

在这里插入图片描述

在这里插入图片描述



Input Plugins

官方文档

这里列举出来很多的插件,直接参考官方文档的案例即可

在这里插入图片描述



一个 Pipeline可以有多个input插件

  • Stdin / File

  • Beats / Log4J /Elasticsearch / JDBC / Kafka /Rabbitmq /Redis

  • JMX/ HTTP / Websocket / UDP / TCP

  • Google Cloud Storage / S3

  • Github / Twitter



Output Plugins

官方文档

在这里插入图片描述

将Event发送到特定的目的地,是 Pipeline 的最后一个阶段。

常见 Output Plugins:

  • Elasticsearch
  • Email / Pageduty
  • Influxdb / Kafka / Mongodb / Opentsdb / Zabbix
  • Http / TCP / Websocket



Codec Plugins

官方文档

将原始数据decode成Event; 将Event encode成目标数据

内置的Codec Plugins:

  • Line / Multiline
  • JSON / Avro / Cef (ArcSight Common Event Format)
  • Dots / Rubydebug



Codec Plugin测试

# 输入的一行line的情况
# 如下图一所示
bin/logstash -e "input{stdin{codec=>line}}output{stdout{codec=> rubydebug}}"

# 使用json进行编码,如果我还是就输出一个hushang字符串就会警告 如下图二所示
bin/logstash -e "input{stdin{codec=>json}}output{stdout{codec=> rubydebug}}"

在这里插入图片描述

在这里插入图片描述



Codec Plugin —— Multiline 多行输入的情况

设置参数:

  • pattern: 设置行匹配的正则表达式 正则表达式基本语法

  • what : 如果匹配成功,那么匹配行属于上一个事件还是下一个事件

    • previous / next
  • negate : 是否对pattern结果取反

    • true / false
# 多行数据,异常。这些几行数据应该是要当做一条数据来看的,不能把他们拆分成多条数据。
Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
        at com.example.myproject.Author.getBookTitles(Author.java:25)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)
[root@hs-es-node1 logstash-7.17.3]# vim config/multiline-exception.conf
input {
  stdin {
    codec => multiline {
      pattern => "^\s"			# 匹配空格   \s 是匹配所有空白符,包括换行     \S 非空白符,不包括换行。
      what => "previous"		# 如果匹配成功,匹配行属于上一个事件
    }
  }
}

filter {}

output {
  stdout { codec => rubydebug }		# 控制台输出
}
#执行管道
[root@hs-es-node1 logstash-7.17.3]# bin/logstash -f config/multiline-exception.conf

在这里插入图片描述



Filter Plugins

官方文档

Filter Plugin可以对Logstash Event进行各种处理,例如解析,删除字段,类型转换

  • date: 日期解析

  • dissect: 分割符解析

  • grok: 正则匹配解析

  • mutate: 对字段做各种操作

    • convert : 类型转换
    • gsub : 字符串替换
    • split /join /merge: 字符串切割,数组合并字符串,数组合并数组
    • rename: 字段重命名
    • update / replace: 字段内容更新替换
    • remove_field: 字段删除
  • ruby: 利用Ruby 代码来动态修改Event



Logstash Queue

设置logstash处理的数据是否要进行持久化,默认是内存机制。

  • In Memory Queue

    进程Crash,机器宕机,都会引起数据的丢失

  • Persistent Queue

    机器宕机,数据也不会丢失; 数据保证会被消费; 可以替代 Kafka等消息队列缓冲区的作用

[root@hs-es-node1 logstash-7.17.3]# vim config/pipelines.yml
queue.type: persisted (默认是memory)
queue.max_bytes: 4gb



案例 Logstash导入csv数据到ES

测试数据集下载:https://grouplens.org/datasets/movielens/

title这一列中括号中保存的是年份,genres这一列可以转换为数组

在这里插入图片描述

准备logstash-movie.conf配置文件

input file插件详情filter csv插件详情filter mutate插件详情output elasticsearch插件

input {
	file {
		path => "/root/movies.csv"			# 必选项,指定文件路径
		start_position => "beginning"		# 非必选项
		sincedb_path => "/dev/null"			# 非必选项
	}
}

filter {
	csv {
		separator => ","					# 非必选项 定义列分隔符值。如果未指定,则默认为逗号
		columns => ["id","content","genre"]	# 定义一个列名列表。如果没有配置列,或者没有指定足够的列,默认的列名是“column1”、“column2”等。
	}
	
	mutate {
		split => { "genre" => "|" }			# 对genre列使用 | 分割
		remove_field => ["path", "host","@timestamp","message"]		# 移除一些不需要的字段
	}
	
	mutate {
		split => { "content" => "("}  			# 使用 ( 进行分割
		add_field => { "title" => "%{[content][0]}"}		# 添加两个字段  取值分别为分割后数组对应位置的值
    	add_field => { "year" => "%{[content][1]}"}
	}
	
	mutate {
		convert => {
			"year"  => "integer"
		}
		strip => ["year"] 		# 去除头尾空格
		remove_field => ["path", "host","@timestamp","message","content"]  # 移除不需要的字段
	}
}

output {
	elasticsearch {
        hosts => "http://localhost:9200"
        index => "movies"
        document_id => "%{id}"		# 指定文档id, %{}取字段中的值  id为字段名
        user => "elastic"
     	password => "123456"
    }
 	stdout {}		# 控制台也输出看看
}



运行logstash

# 检查配置文件是否存在语法错误 如果没问题会输出  Using config.test_and_exit mode. Config Validation Result: OK. Exiting Logstash
[root@hs-es-node1 logstash-7.17.3]# bin/logstash -t -f logstash-movie.conf
[root@hs-es-node1 logstash-7.17.3]# bin/logstash -f logstash-movie.conf
  • -t 或 --config.test_and_exit : 检查配置文件的有效语法,然后退出。
  • –config.reload.automatic: 启用自动配置加载,就是配置文件更改后会自动加载更改后的配置

运行结果,因为我在最后添加了stdout {}同时在控制台输出,输入结果如下图所示

在这里插入图片描述



案例 同步数据库数据到Elasticsearch

需求: 将数据库中的数据同步到ES,借助ES的全文搜索,提高搜索速度

  • 需要把新增用户信息同步到Elasticsearch中
  • 用户信息Update 后,需要能被更新到Elasticsearch
  • 支持增量更新
  • 用户注销后,不能被ES所搜索到



实现思路

  • 基于canal同步数据(全量更新)

  • 借助JDBC Input Plugin将数据从数据库读到Logstash (增量更新) 官方文档

    • 需要自己提供所需的 JDBC Driver;

    • JDBC Input Plugin 支持定时任务 Scheduling,其语法来自 Rufus-scheduler,其扩展了 Cron,使用 Cron 的语法可以完成任务的触发;

    • JDBC Input Plugin 支持通过 Tracking_column / sql_last_value 的方式记录 State,最终实现增量的更新;



JDBC Input Plugin实现步骤

拷贝jdbc依赖到logstash-7.17.3/drivers目录下

[root@hs-es-node1 logstash-7.17.3]# mkdir drivers
[root@hs-es-node1 logstash-7.17.3]# ll ./drivers/
total 2088
-rw-r--r--. 1 root root 2134905 Aug 16 13:16 mysql-connector-java-8.0.15.jar



准备mysql-demo.conf配置文件

[root@hs-es-node1 logstash-7.17.3]# vim mysql-demo.conf
input {
    jdbc {
    	jdbc_driver_library => "/root/logstash-7.17.3/drivers/mysql-connector-java-8.0.15.jar"
    	jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
        jdbc_connection_string => "jdbc:mysql://192.168.5.49:3306/test?serverTimezone=UTC&useSSL=false&useUnicode=true"
        jdbc_user => "root"
        jdbc_password => "1234"
        
        #启用追踪,如果为true,则需要指定tracking_column
    	use_column_value => true
    	#指定追踪的字段,
    	tracking_column => "update_time"
        #追踪字段的类型,目前只有数字(numeric)和时间类型(timestamp),默认是数字类型
    	tracking_column_type => "timestamp"
        # 记录最后一次运行的结果
    	record_last_run => true
    	# 上面运行结果的保存位置  这个文件中保存着最后一次查询,update_time字段的值,下一次查询就可以用这个值来做where条件
    	last_run_metadata_path => "jdbc-position.txt"
        
        # 因为我上面使用的是timestamp追踪字段类型,sql_last_value这里开始的值是1970-01-01 00:00:00
        # 之后sql_last_value 的值就是最后一次查询 追踪字段的值,这个值保存在上方定义的 jdbc-position.txt文件中
        statement => "SELECT * from sys_user where update_time >:sql_last_value"
        # cron 定时  每秒执行一次
        schedule => " * * * * * *"
    }
}

output {
	elasticsearch {
        hosts => "http://localhost:9200"
        index => "user"
        document_id => "%{id}"		# 指定文档id, %{}取字段中的值  id为字段名
        user => "elastic"
     	password => "123456"
    }
    # 控制台也输出看看
 	stdout {
 		codec => rubydebug
 	}		
}



运行logstash

# -t 检查配置文件是否存在语法错误
[root@hs-es-node1 logstash-7.17.3]# bin/logstash -t -f mysql-demo.conf 
[root@hs-es-node1 logstash-7.17.3]# bin/logstash -f mysql-demo.conf 

因为我数据表里面实现就有两条数据,所以这里就直接查询出来了

在这里插入图片描述

之后每隔1秒执行一次查询语句,即使重启之后这个where查询条件的时间还是保存了,因为我们上方配置文件中配置了 记录最后一次运行的结果

在这里插入图片描述

数据表中事先就存在两条数据

在这里插入图片描述

在这里插入图片描述



测试新增

INSERT INTO `test`.`sys_user`(`id`, `username`, `password`, `name`, `description`, `status`, `create_time`, `update_time`) VALUES (1819212905845895170, 'deimkf_test', '$2a$10$jyQQSxxVp', 'test', 'test', 1, NOW(), NOW());

可以看到,这里之后的查询时间就使用的最新的

在这里插入图片描述



测试修改

UPDATE `test`.`sys_user` SET `username` = 'deimkf_update',  `update_time` = now() WHERE `id` = 1819212905845895170;

在这里插入图片描述
在这里插入图片描述



测试逻辑删除

# 修改status字段的值
UPDATE `test`.`sys_user` SET `status` = 0,  `update_time` = now() WHERE `id` = 1819212905845895170;

在这里插入图片描述

此时,直接ES查询是还能查询到数据的

在这里插入图片描述

#ES中查询
# 创建 alias,只显示没有被标记 deleted的用户,也就是status=1的用户
POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "user",
        "alias": "sys_user",
        "filter": {			# 这里就过滤掉了status为0的数据
          "term": {
            "status": 1
          }
        }
      }
    }
  ]
}

# 根据别名查询
GET /sys_user/_search

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值