Logstash 教程

1.简介

Logstash是一个数据同步工具,在ELK(Elasticsearch + Logstash + Kibana)技术栈中解决数据同步问题。日常项目中数据主要存储在MYSQL、日志文件中,通过Logstash可以将MYSQL、日志文件、redis等多种数据源的数据同步到ES,这样就可以通过ES搜索数据。

logstash部署架构 logstash教程_数据

MYSQL同步数据到Elasticsearch,主要有下面几种策略:

  • 双写策略,更新MYSQL数据的同时通过ES API直接写入数据到ES (同步方式)
  • 通过Logstash同步数据到ES (异步方式)
  • 通过订阅MYSQL Binlog,将数据同步到ES (异步方式)

这里主要介绍Logstash如何同步数据。

2.安装

2.1.环境依赖

依赖Java 8 或者 Java 11环境,可以是更高的版本。

2.2.安装方式

2.2.1. centos

更新key

sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch

创建文件 /etc/yum.repos.d/logstash.repo 内容如下

[logstash-7.x]
name=Elastic repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

安装Logstash

sudo yum install logstash
2.2.2. ubuntu

按顺序执行下面命令

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

sudo apt-get install apt-transport-https

echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list

sudo apt-get update && sudo apt-get install logstash
2.2.3. 通过压缩包安装

通过下面地址下载最新版本的压缩包(linux/mac系统下载tar.gz, windows下载zip)

https://www.elastic.co/cn/downloads/logstash

将压缩包解压到自定义目录即可。

linux系统例子:

tar -zxvf logstash-7.7.1.tar.gz

3.测试安装

下面验证logstash安装是否成功

# 切换到安装目录
cd logstash-7.7.1
# 执行命令
bin/logstash -e 'input { stdin { } } output { stdout {} }'

等一会,logstash启动后在控制台输入tizi365.com 按回车,可以看到类似下面的输出

tizi365.com
{
    "@timestamp" => 2020-06-09T15:45:38.147Z,
       "message" => "tizi365.com",
      "@version" => "1",
          "host" => "jogindembp"
}

添加config.reload.automatic命令参数,自动加载配置,不需要重新启动logstash

bin/logstash -f tizi.conf --config.reload.automatic

4.配置文件

可以将Logstash的配置都写入一个配置文件中,下面是配置文件的格式,主要有三部分组成

# 输入插件配置, 主要配置需要同步的数据源,例如:MYSQL
input {
}
# 过滤器插件配置, 主要用于对输入的数据进行过滤,格式化操作,filter是可选的。
filter {
 }
# 输出插件配置,主要配置同步数据的目的地,例如同步到ES
output {
}

提示:logstash的input、filter、output都是由各种插件组成。

例子:

创建一个tizi.conf配置文件,内容如下:

input {
    stdin {}
}
output {
    stdout { codec => rubydebug }
}

说明:

这个配置文件的意思是,从控制台标准输入(stdin)接收输入,然后直接将结果在控制台标准输出(stdout)打印出来。

通过配置文件启动logstash

bin/logstash -f tizi.conf

5.同步nginx日志到ES

下面是将Nginx的访问日志同步到ES中的配置

配置文件名:tizi.conf

input {
    # 实时监控日志文件的内容,类似tail -f 命令的作用
    file {
        # nginx日志文件路径
        path => [ "/data/nginx/logs/nginx_access.log" ]
        start_position => "beginning"
        ignore_older => 0
    }
}
# 配置过滤器对日志文件进行格式化
filter {
    # 使用grok插件对日志内容进行格式化,提取日志内容,方便转换成json格式
    # %COMBINEDAPACHELOG 是grok插件内置的apache日志内容处理模板,其实就是一些表达式,用来格式日志文本内容,也可以格式化Nginx日志
    grok {
        match => {
            "message" => "%{COMBINEDAPACHELOG}"
        }
    }
}
# 配置输出目的地,这里配置同步到ES中
output {
    elasticsearch {
        # es服务器地址
        hosts => ["127.0.0.1:9200"]
        # 目标索引
        index => "nginx-access"
    }
}

启动logstash

bin/logstash -f tizi.conf

Logstash 工作原理

Logstash同步数据,主要有三个核心环节:inputs → filters → outputs,流程如下图。

logstash部署架构 logstash教程_bc_02

inputs模块负责收集数据,filters模块可以对收集到的数据进行格式化、过滤、简单的数据处理,outputs模块负责将数据同步到目的地,Logstash的处理流程,就像管道一样,数据从管道的一端,流向另外一端。

提示:inputs/filters/outputs是通过插件机制扩展各种能力。

inputs

inputs可以收集多种数据源的数据,下面是常见的数据源:

  • file - 扫描磁盘中的文件数据,例如: 扫描日志文件。
  • mysql - 扫描Mysql的表数据
  • redis
  • Filebeat - 轻量级的文件数据采集器,可以取代file的能力。
  • 消息队列kafka、rabbitmq等 - 支持从各种消息队列读取数据。

filters

filters是一个可选模块,可以在数据同步到目的地之前,对数据进行一些格式化、过滤、简单的数据处理操作。

常用的filters功能:

  • grok - 功能强大文本处理插件,主要用于格式化文本内容。
  • drop - 丢弃一些数据

outputs

Logstatsh的最后一个处理节点,outputs负责将数据同步到目的地。

下面是常见的目的地:

  • elasticsearch
  • file - 也可以将数据同步到一个文件中

Codecs

codecs就是编码器,负责对数据进行序列号处理,主要就是json和文本两种编码器。

Logstash - 同步MYSQL数据到Elasticsearch

在实际项目场景中,业务数据主流的存储方案还是MYSQL,但是MYSQL处理海量数据的搜索能力较差,目前MYSQL搭配ES,为业务提供强大的数据搜索能力是业界主流的方案,因此需要解决如何将MYSQL中的数据导入到ES中,下面介绍通过Logstash准实时的将MYSQL数据导入到ES中。

1.jdbc插件介绍

Logstash通过jdbc input插件实现定时同步MYSQL数据,了解JAVA的同学应该对jdbc不陌生,就是访问数据库的API标准,我们常见的数据库都可以使用jdbc接口进行访问。

使用jdbc访问数据库,通常都需要安装对应数据库的jdbc驱动,例如:MYSQL的jdbc驱动,到MYSQL官网下载对应的jar包就可以。

MYSQL jdbc驱动下载地址:

https://mvnrepository.com/artifact/mysql/mysql-connector-java

找到MYSQL对应的版本下载JAR包即可,例如下面下载8.0.15版本。

logstash部署架构 logstash教程_bc_03

2.简单的同步例子

关键配置有两点:

  • 配置input jdbc输入插件
  • 配置output elasticsearch输出插件

完整的配置如下

input {
  # 配置JDBC数据源
  jdbc {
    # mysql jdbc驱动路径
    jdbc_driver_library => "/Users/tizi365/.m2/repository/mysql/mysql-connector-java/8.0.18/mysql-connector-java-8.0.18.jar"
    # mysql jdbc驱动类
    jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
    # MYSQL连接地址,格式: jdbc:mysql://服务器地址:端口/数据库名
    jdbc_connection_string => "jdbc:mysql://localhost:3306/wordpress"
    # •MYSQL 账号
    jdbc_user => "root"
    # MYSQL 密码
    jdbc_password => "123456"
    # 定时任务配置,下面表示每分钟执行一次SQL
    # 具体语法请参考下一个章节内容
    schedule => "* * * * *"
    # 定时执行的SQL语句,Logstash会根据schedule配置,定时执行这里的SQL语句
    # 将SQL语句查询的结果,传给output插件
    statement => "SELECT * FROM `wp_posts`"
  }
}

output {
    stdout {
      # 配置将数据导入到ES中
      elasticsearch {
        # 索引名,logstash会将数据导入到这个索引中
        index => "wp_posts"
        # ES服务器地址,支持多个地址
        hosts => ["127.0.0.1:9200","127.0.0.2:9200"]
        # 设置ES文档的唯一Id值为SQL语句返回的id
        # 建议将document_id设置为MYSQL表的主键
        document_id => "%{id}"
      }
    }
}

3.定时任务配置

jdbc schedule的配置规则,类似linux的crontab的写法,具体语法规则如下:

语法格式,总共由5个字段组成,含义如下:

*    *   *   *  * 

  分   时  天   月 星期

各个字段取值范围:

  • 分 - 0-59
  • 时 - 0-23
  • 天 - 1-31
  • 月 - 1-12
  • 星期 - 0-7

特殊字符含义:

  • 星号() :代表所有值,例如:第一个字段是星号(),则代表每分钟。
  • 逗号(,):指定一个数值范围,例如:1,2,3,4
  • 横杠(-):另外一种表示一个整数范围的方法,例如:1-4 表示1,2,3,4
  • 斜线(/):可以用斜线指定时间的间隔频率,例如:*/5,如果用在分钟字段,表示每5分钟执行一次。

例子:

# 每分钟执行一次
* * * * *
# 每10分钟执行一次
*/10 * * * *
# 每小时执行一次
* */1 * * *
# 每天0点执行一次
0 0 * * *
# 每天凌晨2点1分执行一次
1 2 * * *

4.增量同步数据

前面的例子同步数据的SQL如下:

input {
  # 配置JDBC数据源
  jdbc {
    # 忽略其他配置
    statement => "SELECT * FROM `wp_posts`"
  }
}

同步数据的SQL语句,直接扫描全表的数据,如果数据量比较小,问题不大,如果数据量比较大,会直接卡死,logstash OOM挂了,因此需要实现增量同步,每次仅同步新增的数据。

Logstash提供了sql_last_value字段值,帮助我们实现增量同步;增量同步的核心思路就是,logstash每次执行SQL的时候,会将SQL查询结果的最后一条记录的某个值保存到sql_last_value字段中,下一次执行SQL的时候,以sql_last_value值作为参考,从这个值往后查询新数据。

例子:

input {
  jdbc {
    # 注意where条件id > :sql_last_value
    # 每次执行SQL的时候,id大于sql_last_value的值
    statement => "SELECT id, mycolumn1, mycolumn2 FROM my_table WHERE id > :sql_last_value"
    # 允许sql_last_value的值来自查询结果的某个字段值。
    use_column_value => true
    # sql_last_value的值来自查询结果中的最后一个id值
    tracking_column => "id"
    # ... 忽略其他配置
  }
}

说明:

sql_last_value的默认值是0或者1970-01-01,具体是什么值跟数据类型有关,上面的例子,定时任务执行SQL如下

# 第一次执行,sql_last_value=0
SELECT id, mycolumn1, mycolumn2 FROM my_table WHERE id > 0

# 第二次执行,sql_last_value=100,假设上面的SQL最后的id值是100
SELECT id, mycolumn1, mycolumn2 FROM my_table WHERE id > 100

# 第三次执行,sql_last_value=200,,假设上面的SQL最后的id值是200
SELECT id, mycolumn1, mycolumn2 FROM my_table WHERE id > 200

提示:

上面的例子,使用id作为增量同步数据的依据,不一定适合所有的业务场景,例如:同步文章数据,文章更新了,但是文章的id没有更新,这个时候使用id作为增量同步的依据,会导致更新的文章没有同步到ES,这种场景适合使用更新时间作为增量同步的依据,用法一样,sql_last_value换一个字段值即可。

5.分页

前面的章节在实现增量同步的时候,也存在一个问题,如果增量同步的数据太多的时候,logstash也会卡死,尤其是首次增量同步,例如:一个MYSQL表的数据有100万,首次增量同步数据,会扫描全表的数据。

logstash jdbc插件执行分页查询,避免一次查询太多数据,配置如下:

input {
  jdbc {
    # 激活分页处理
    jdbc_paging_enabled => true
    # 分页大小,每次查询1000条数据
    jdbc_page_size => 1000
    # sql语句
    statement => "SELECT * FROM my_table"
    # ... 忽略其他配置
  }
}

6.大表同步

在实际业务场景中,有些数据表的数据会有几百万,甚至上亿的数据,那么在使用logstash同步这些大表数据的时候,结合前面两个章节的增量同步和分页处理就可以解决,不过需要注意深度分页的性能问题。

例如:

# 每次查询1000条数据,但是翻页从第500万条数据偏移开始
SELECT * FROM my_table limit 5000000, 1000

这条SQL会非常慢,可以借助索引覆盖优化性能。

例子:

SELECT * FROM my_table WHERE id in (SELECT id FROM my_table limit 5000000, 1000)

因为id是主键,在主键索引中已经包含id的值,不需要回表扫描磁盘的数据,所以性能比较好,上面的SQL首先借助索引覆盖将id值查询出来,然后根据id查询具体的数据。

Filebeat 教程

logstash虽然也支持从磁盘文件中收集数据,但是logstash自己本身还是比较重,对资源的消耗也比较大,尤其是在容器化环境,每个容器都部署logstash也太浪费资源,因此出现了轻量级的日志文件数据收集方案Filebeat,Filebeat将收集到的文件数据传给Logstatsh处理即可。

Filebeat部署架构

logstash部署架构 logstash教程_logstash部署架构_04

可以在每一台服务器或者每一个容器中安装Filebeat,Filebeat负责收集日志数据,然后将日志数据交给Logstash处理,Logstash在将数据导入ES。

安装Filebeat

下载安装包,然后解压即可。

官网下载地址:

https://www.elastic.co/cn/downloads/beats/filebeat

下面以7.7.1版本为例

mac

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.7.1-darwin-x86_64.tar.gz

tar xzvf filebeat-7.7.1-darwin-x86_64.tar.gz

linux

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.7.1-linux-x86_64.tar.gz

tar xzvf filebeat-7.7.1-linux-x86_64.tar.gz

Filebeat配置

Filebeat的配置结构类似Logstash,也需要配置input和output,分别配置输入和输出,Filebeat使用yaml格式编写配置文件。

默认配置文件路径:

${安装目录}/filebeat.yml
/etc/filebeat/filebeat.yml
/usr/share/filebeat/filebeat.yml

因为我们使用的是tar安装包安装,所以选择${安装目录}/filebeat.yml 路径。

配置例子:

# 配置采集数据源
filebeat.inputs:
- type: log
  paths:
    - /var/log/messages
    - /var/log/*.log
# 配置输出目标,这里将数据投递给logstash
output.logstash:
  # logstash地址
  hosts: ["127.0.0.1:5044"]

说明:

type为log类型,表示收集日志文件数据,paths是一个文件路径数组,这里扫描/var/log/messages文件和/var/log/目录下所有以log为扩展名的日志文件。

Logstash beat配置

配置Logstash的input,让Logstash可以接收Filebeat投递过来的数据。

input {
  # 配置接收Filebeat数据源,监听端口为5044
  # Filebeat的output.logstash地址保持跟这里一致
  beats {
    port => 5044
  }
}

output {
  # 将数据导入到ES中
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "tizi365" 
  }
}

启动Filebeat

进入filebeat安装目录

./filebeat -c filebeat.yml

如果配置PATH,直接启动即可。

input插件

Logstash Beats插件

Beats input插件让Logstash可以接收来自Elastic Beats framework发送过来的数据,Elastic Beats framework用的比较多的就是Filebeat.

例子

input {
  # 在5044端口监听来自beats框架的数据
  beats {
    port => 5044
  }
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "%{[@metadata][beat]}-%{[@metadata][version]}" 
  }
}

接收来自beats的数据,并且将数据导入到ES中。

Beats Input插件参数

参数名

类型

默认值

说明

host

string

0.0.0.0

监听地址

port

number


监听端口

Logstash File input插件

Logstash的file input插件可以实现从磁盘文件中采集数据,通常用于收集日志文件数据,file input插件一行行的从文件中读取数据,然后交给logstash。

提示: file input插件的作用跟linux命令tail -f 的作用类似,可以实时收集文件的最新数据。

例子

input {
  # 扫描指定文件日志数据
  file {
    # 指定需要扫描的日志文件,支持多个文件,也支持星号(*)通配符
    # 含义:扫描/var/log/messages文件和/var/log/目录下的所有以log为扩展名的日志文件。
    path => [ "/var/log/messages", "/var/log/*.log" ]
  }
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "tizi365" 
  }
}

file Input插件参数

参数名

类型

默认值

说明

path

array


需要扫描的文件路径,数组格式:[ "/var/log/messages", "/var/log/tizi.log" ]

delimiter

string

\n

指定文件换行符

exclude

string


指定需要排除的文件,例如排除压缩包:*.gz , 这个参数通常在path参数包含通配符的时候,一起配合使用

Logstash Exec input插件

Exec input插件可以定时的执行一个命令,然后采集命令输出的结果,通过exec插件,我们可以轻松的采集linux系统状态,例如:定时的采集linux服务的内存使用情况。

例子:

input {
  # 通过exec插件,定时的通过命令
  exec {
    # 需要执行的命令
    command => "free -m"
    # 30秒执行一次
    interval => 30
  }
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "tizi365" 
  }
}

说明:

30秒执行一次free -m命令,命令输出的结果,会被Logstash同步到ES中。

exec Input插件参数

参数名

类型

默认值

说明

command

string


设置需要执行的命令

interval

number


单位是秒,多长时间执行一次命令

schedule

string


使用类型linux crontab的语法,设置定时任务,例如:/10 * * * 代表每10分钟跑一次,interval和schedule参数二选一即可

Logstash jdbc input插件

jdbc插件用于解决Logstash采集数据库数据问题,基本上所有的关系数据库都支持jdbc接口,例如: MYSQL、Oracle等。

jdbc插件通过定时任务,定时的执行SQL语句,从数据库中读取数据,定时任务语法类似linux的crontab的写法。

例子

input {
  # 配置jdbc数据源
  jdbc {
    # 指定jdbc驱动路径
    jdbc_driver_library => "mysql-connector-java-5.1.36-bin.jar"
    # jdbc驱动类
    jdbc_driver_class => "com.mysql.jdbc.Driver"
    # 数据库连接配置
    jdbc_connection_string => "jdbc:mysql://localhost:3306/mydb"
    # 数据库账号
    jdbc_user => "mysql"
    # 数据库密码
    jdbc_password => "123456"
    # SQL绑定的参数
    parameters => { "favorite_artist" => "Beethoven" }
    # 定时任务配置
    schedule => "* * * * *"
    # SQL语句
    statement => "SELECT * from songs where artist = :favorite_artist"
  }
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "tizi365" 
  }
}

详细的例子可以参考:同步MYSQL数据到Elasticsearch

jdbc Input插件参数

参数名

类型

默认值

说明

jdbc_driver_library

string

 

指定jdbc驱动路径, 不同数据库jdbc驱动不一样

jdbc_driver_class

string

 

jdbc驱动类,新版的MYSQL驱动类为:com.mysql.cj.jdbc.Driver

jdbc_connection_string

string

 

数据库连接配置, 格式: jdbc:数据库类型://地址:端口/数据库,例子:jdbc:mysql://localhost:3306/mydb

jdbc_user

string

 

数据库账号

jdbc_password

string

 

数据库密码

schedule

string

 

定时任务配置,语法可以参考linux的cron

statement

string

 

需要执行的SQL语句

parameters

hash

 

SQL绑定参数,例子:{ "target_id" => "321" }

use_column_value

boolean

false

当设置为true时,使用tracking_column定义的列作为:sql_last_value的值。当设置为false时,:sql_last_value等于上次执行查询的时间。

tracking_column

string

 

定义使用SQL查询结果中的哪一个字段值作为sql_last_value的值

jdbc_paging_enabled

boolean

false

激活分页处理

jdbc_page_size

number

100000

分页大小

Logstash kafka input插件

kafka input插件 支持Logstash从kafka消息队列中的topic读取数据。

例子

input {
  # 配置kafka数据源
  kafka {
    # kafka服务器地址,多个地址使用逗号分隔
    bootstrap_servers => "localhost:9092"
    # 订阅的主题,支持订阅多个主题
    topics => ["logstash", "tizi365"]
    # 消费者线程数
    consumer_threads => 5
    # 消费组Id
    group_id => "logstash"
  }
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "tizi365" 
  }
}

kafka Input插件参数

参数名

类型

默认值

说明

bootstrap_servers

string

localhost:9092

kafka服务器地址,多个地址使用逗号分隔

topics

array

["logstash"]

订阅的主题,支持订阅多个主题

consumer_threads

number

1

消费者线程数

group_id

string

logstash

消费组Id

fetch_min_bytes

number

 

一次最少从服务器读取多少字节数据

fetch_max_bytes

number

 

一次最多从服务器读取多少字节数据

Logstash RabbitMQ input插件

RabbitMQ input插件,支持Logstash通过RabbitMQ消息队列读取数据。

例子:

input {
  # 配置rabbitmq数据源
  rabbitmq {
    # rabbitmq服务器地址
    host => "localhost"
    # 端口  
    port => 5672
    # RabbitMQ 账号
    user => "guest"
    # RabbitMQ 密码
    password => "guest"
    # 队列名
    queue => "tizi365"
  }
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "tizi365" 
  }
}

RabbitMQ Input插件参数

参数名

类型

默认值

说明

host

string

 

rabbitmq服务器地址

port

number

5672

端口

user

string

guest

RabbitMQ 账号

password

string

guest

RabbitMQ 密码

queue

string

 

队列名

auto_delete

boolean

false

最后一个消费组退出后是否删除消息

prefetch_count

number

256

预加载多少条消息到本地

Logstash redis input插件

redis input插件支持Logstash从redis中读取数据,目前仅支持从redis的list和channels两种数据结构中读取数据。

例子

input {
  # 配置redis数据源
  redis {
    # redis服务器地址
    host => "127.0.0.1"
    # 端口  
    port => 6379
    # redis 密码, 没有设置密码可以不填
    password => "123456"
    # 从哪个key读取数据
    key => "tizi365_list"
    # 设置Key的redis的数据类型
    data_type => "list"
  }
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "tizi365" 
  }
}

redis Input插件参数

参数名

类型

默认值

说明

host

string

127.0.0.1

redis服务器地址

port

number

6379

redis服务器端口号

password

string

 

redis服务密码

key

string

 

配置logstash从哪个key读取数据

data_type

string

 

设置Key的redis的数据类型,支持list, channel

db

number

0

redis数据库

threads

number

1

并发线程数

timeout

number

5

redis连接超时时间,单位秒

ssl

boolean

false

是否打开ssl支持

batch_count

number

125

一次批量从redis加载多少条数据

output插件

Logstash Elasticsearch output插件

通过Elasticsearch output插件Logstash可以将采集到的数据导入到Elasticsearh中。

例子:

input {
  # 扫描指定文件日志数据
  file {
    path => [ "/var/log/messages" ]
  }
}

output {
  # 将数据导入到ES中
  elasticsearch {
    # ES服务地址
    hosts => ["http://localhost:9200"]
    # 索引名
    index => "tizi365" 
  }
}

Elasticsearch output插件参数

参数名

类型

默认值

说明

hosts

uri

[//127.0.0.1]

ES服务地址

index

string

logstash-%{+yyyy.MM.dd}

索引名

document_id

string

 

设置document的id值,通常使用logstash采集数据的某个字段值作为id值,例如:%{id}

user

string

 

账号

password

string

 

密码

routing

string

 

设置ES的路由参数

Logstash Stdout output插件

在调试Logstash调试的时候,可以将Logstash收集到的数据在命令窗口直接打印出来,通过Stdout output插件可以实现将数据打印到标准输出。

简单例子:

input {
  # 扫描指定文件日志数据
  file {
    path => [ "/var/log/messages" ]
  }
}

output {
  # 将数据直接打印出来
  stdout {}
}

指定输出格式:

output {
  # 以Json格式将数据直接打印出来
  stdout { codec => json }
}

以rubydebug的格式打印数据:

output {
  # 以Json格式将数据直接打印出来
  stdout { codec => rubydebug }
}

filter插件

Logstash grok filter插件

通过grok filter插件我们可以对文本内容进行格式化处理,提取文本中的内容,并将其转换成json格式,在处理日志内容的时候非常有用。

例子:

例如日志内容如下:

55.3.244.1 GET /index.html 15824 0.043

这条日志内容包含了ip、http请求方法、请求路径、响应内容大小、响应时间,这条日志是一行字符串,我们可以通过grok将其格式化为:client、method、request、bytes、duration这几个字段,然后在保存到elasticsearch中。

logstash配置:

input {
  # 扫描指定文件日志数据
  file {
    path => [ "/var/log/http.log" ]
  }
}
# 配置过滤器插件,对Input收集到的数据进行格式化处理
filter {
   # 通过grok插件,格式化文本内容
   grok {
      # grok参数,这里决定如何对每一行日志进行参数提取
      # message 字段的内容就是格式化日志的表达式
      match => { "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}" }
   }
}

output {
  # 将数据导入到ES中
  elasticsearch {
    # ES服务地址
    hosts => ["http://localhost:9200"]
    # 索引名
    index => "tizi365" 
  }
}

通过grok提取的结果如下:

  • client: 55.3.244.1
  • method: GET
  • request: /index.html
  • bytes: 15824
  • duration: 0.043

grok模式语法

grok的提取字符串内容的语法其实就是在正则表达式基础之上进行封装,Logstash grok内置了120种默认表达式,解决很多日常需求,不需要重头编写复杂的正则表达式。

grok表达式语法:

%{模式名:自定义字段名}

说明:

  • 模式名 - 指的就是预先定义好的正则表达式的别名,例如:IP 可以匹配ip内容。
  • 自定义字段名 - 通过模式匹配到内容后,将内容保存到这个自定义的字段中

例子:

%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}

这是上面例子的grok表达式,下面是对表达式的解读:

  • %{IP:client} - 匹配IP内容,结果保存到client字段
  • %{WORD:method} - 匹配非空字符串内容,结果保存到method字段
  • %{URIPATHPARAM:request} - 匹配url路径,结果保存到request字段
  • %{NUMBER:bytes} - 匹配数字,结果保存到bytes字段

grok filter插件参数

参数名

类型

默认值

说明

match

hash

{}

定义grok的表达式,格式: message => "表达式"

patterns_dir

array

[]

自定义模式配置文件的路径,支持多个路径,例子:["/opt/logstash/patterns", "/opt/logstash/extra_patterns"]

grok内置模式

常用模式

表达式标识

名称

详情

匹配例子

USERNAME 或 USER

用户名

由数字、大小写及特殊字符(._-)组成的字符串

1234、Bob、Alex.Wong

EMAILLOCALPART

用户名

首位由大小写字母组成,其他位由数字、大小写及特殊字符(_.+-=:)组成的字符串。注意,国内的QQ纯数字邮箱账号是无法匹配的,需要修改正则

windcoder、windcoder_com、abc-123

EMAILADDRESS

电子邮件

 

windcoder@abc.com、windcoder_com@gmail.com、abc-123@163.com

HTTPDUSER

Apache服务器的用户

可以是EMAILADDRESS或USERNAME

 

INT

整数

包括0和正负整数

0、-123、43987

BASE10NUM 或 NUMBER

十进制数字

包括整数和小数

0、18、5.23

BASE16NUM

十六进制数字

整数

0x0045fa2d、-0x3F8709

WORD

字符串

包括数字和大小写字母

String、3529345、ILoveYou

NOTSPACE

不带任何空格的字符串

 

 

SPACE

空格字符串

 

 

QUOTEDSTRING 或 QS

带引号的字符串

 

"This is an apple"、'What is your name?'

UUID

标准UUID

 

550E8400-E29B-11D4-A716-446655440000

MAC

MAC地址

可以是Cisco设备里的MAC地址,也可以是通用或者Windows系统的MAC地址

 

IP

IP地址

IPv4或IPv6地址

127.0.0.1、FE80:0000:0000:0000:AAAA:0000:00C2:0002

HOSTNAME

IP或者主机名称

 

 

HOSTPORT

主机名(IP)+端口

 

127.0.0.1:3306、api.windcoder.com:8000

PATH

路径

Unix系统或者Windows系统里的路径格式

/usr/local/nginx/sbin/nginx、c:\windows\system32\clr.exe

URIPROTO

URI协议

 

http、ftp

URIHOST

URI主机

 

windcoder.com、10.0.0.1:22

URIPATH

URI路径

 

//windcoder.com/abc/、/api.php

URIPARAM

URI里的GET参数

 

?a=1&b=2&c=3

URIPATHPARAM

URI路径+GET参数

/windcoder.com/abc/api.php?a=1&b=2&c=3

 

URI

完整的URI

 

https://windcoder.com/abc/api.php?a=1&b=2&c=3

LOGLEVEL

Log表达式

Log表达式

Alert、alert、ALERT、Error

日期时间模式

表达式标识

名称

匹配例子

MONTH

月份名称

Jan、January

MONTHNUM

月份数字

03、9、12

MONTHDAY

日期数字

03、9、31

DAY

星期几名称

Mon、Monday

YEAR

年份数字

 

HOUR

小时数字

 

MINUTE

分钟数字

 

SECOND

秒数字

 

TIME

时间

00:01:23

DATE_US

美国时间

10-01-1892、10/01/1892/

DATE_EU

欧洲日期格式

01-10-1892、01/10/1882、01.10.1892

ISO8601_TIMEZONE

ISO8601时间格式

+10:23、-1023

TIMESTAMP_ISO8601

ISO8601时间戳格式

2016-07-03T00:34:06+08:00

DATE

日期

美国日期%{DATE_US}或者欧洲日期%{DATE_EU} |

DATESTAMP

完整日期+时间

07-03-2016 00:34:06

HTTPDATE

http默认日期格式

03/Jul/2016:00:36:53 +0800

Grok自带的模式,具体的规则可以参考下面链接

https://github.com/logstash-plugins/logstash-patterns-core/blob/master/patterns/grok-patterns

自定义模式

如果grok内置的模式无法满足需求,也可以自定义模式。

模式定义语法:

NAME PATTERN

说明:

  • NAME - 模式名
  • PATTERN - 表达式,包括正则表达式和logstash变量。

例子:

步骤1:

配置文件路径:/opt/logstash/tizi_patterns ,文件内容如下

TIZI_NUMBER \d+

提示:自定义模式配置文件路径,可以根据项目情况自定义即可

步骤2:

在logstash配置文件中引用自定义表达式

filter {
   grok {
      # 指定自定义模式路径
      patterns_dir => ["/opt/logstash/tizi_patterns"]
      # 使用自定义模式
      match => { "message" => "%{TIZI_NUMBER:tizi_data}" }
   }
}

调试grok模式

Kibana支持在线调试grok,如下截图:

logstash部署架构 logstash教程_bc_05

Logstash java_uuid filter插件

如果我们想给logstash收集到的每一条数据增加一个唯一id,可以通过java_uuid和uuid两个filter插件实现,他们的区别只是底层实现不同,效果类似。

java_uuid

filter {
      # java版的uuid生成插件
      java_uuid {
        # 生成的唯一id,保存到target指定的字段
        target    => "uuid"
        # 如果target指定的字段已经存在,是否覆盖
        overwrite => true
      }
   }

uuid

filter {
      # 定义uuid插件
      uuid {
        # 生成的唯一id,保存到target指定的字段
        target    => "uuid"
        # 如果target指定的字段已经存在,是否覆盖
        overwrite => true
      }
   }

Logstash json filter插件

通常情况,Logstash收集到的数据都会转成json格式,但是默认logstash只是对收集到的格式化数据转成json,如果收到的数据仅仅是一个字符串是不会转换成Json.

例如:

{
    "id":20,
    "domain": "https://www.tizi365.com",
    "data": "{\"type\":1, \"msg\":\"message ok\"}"
}

data字段的内容是一个json字符串,不是格式化的Json格式,如果数据导入到Elasticsearch,data字段也是一个字符串,不是一个Json对象;json filter插件可以解决这种问题。

例子:

filter {
    # 定义json插件
    json {
        # 指定需要转换成json格式的字段
        source => "data"
        # 指定转换成json的数据,保存到那个字段,如果字段存在会覆盖
        target => "data"
        # 如果遇到错误的json,是否跳过json filter过滤器
        skip_on_invalid_json => true
    }
}

json filter格式化数据后,输出如下:

{
    "id":20,
    "domain": "https://www.tizi365.com",
    "data": {
        "type":1,
        "msg":"message ok"
    }
}

Logstash kv filter插件

如果logstash收集到的日志格式是key=value键值对,可以通过kv filter插件对其进行格式化。

例子:

日志内容:

ip=1.2.3.4 error=REFUSED

logstash配置

input {
  # 扫描指定文件日志数据
  file {
    path => [ "/var/log/http.log" ]
  }
}

filter {
   # 使用kv filter格式化键值对日志内容
   kv { }
}

output {
  # 将数据直接打印出来
  stdout {}
}

logstash输出的内容如下:

{
    "ip": "1.2.3.4",
    "error": "REFUSED"
}

kv filter插件参数

参数名

类型

默认值

说明

prefix

string

 

指定key的前缀,例如:arg_

field_split

string

" "

指定两个kv值直接的分隔符,默认是空格,例:field_split => "&" , 通过&分隔键值对

default_keys

hash

 

设置key的默认值,例:default_keys => [ "from", "logstash@example.com", "to", "default@dev.null" ]

Logstash drop filter插件

drop filter插件主要用于删除logstash收集到的数据,通常配合条件语句一起使用。

提示:logstash是一条一条数据发给filter处理,所以drop filter也是一条数据,一条数据的删除。

例子:

input {
  # 扫描指定文件日志数据
  file {
    path => [ "/var/log/http.log" ]
  }
}

filter {
    # 如果loglevel字段值等于debug,则删除整条消息
    if [loglevel] == "debug" {
        # 通过drop过滤器删除消息
        drop { }
    }
}

output {
  # 将数据直接打印出来
  stdout {}
}