Logstash安装
下载并解压安装包
wget https://artifacts.elastic.co/downloads/logstash/logstash-5.4.1.tar.gz
tar -zxf logstash-6.2.2.tar.gz
测试安装是否成功
在logstash文件的bin目录下执行如下命令(参数-e:立即执行,使用命令行里的配置参数启动实例)
./logstash -e 'input { stdin {} } output { stdout {} }'
测试结果
格式化输出测试
./logstash -e 'input { stdin {} } output { stdout { codec => rubydebug} }'
测试结果
实际使用
创建配置文件,用命令解析配置文件
./logstash -f /opt/config/mylog.conf (配置文件所在的绝对路径)
数据过滤
#单一文件解析:
1.Json格式字符串
配置文件信息
input { //输入流
file { //输入为文件
path => "/opt/aa.txt" //待解析的文件绝对路径
start_position => "beginning" //从头开始读取(解析)文件
sincedb_path => "/dev/null" //利用linux黑洞达到每次重头读取日志文件,每次重新读取时,检查之前的读取都为空。
codec => json //目标文件的数据格式(导入ES数据库时,json的键即为字段名)
}
}
output { //输出流
stdout { //输出到控制台
codec => rubydebug //以 rubydebug 的编码格式输出
}
}
2.Json格式中带Json对象的字符串(禁止套娃)
配置文件信息
input {
file {
path => "/opt/aa.txt"
start_position => "beginning"
sincedb_path => "/dev/null"
codec => json
}
}
filter { //过滤器
mutate { //数据修改插件,丰富的基础类型数据处理能力。可以重命名,删除,替换和修改事件中的字段。
add_field => { "adv" => "%{cm}" } //新增字段,将cm对象内容载入新字段adv作为字符串,否则会解析错误
}
json { //JSON插件用于解码JSON格式的字符串,一般是一堆日志信息中,部分是JSON格式,部分不是的情况下
source => "adv" //解码Json格式的adv字段
remove_field => [ "adv","cm" ] //删除两个新旧字段
}
}
output {
stdout {
codec => rubydebug
}
}
直接解析里层json对象(inner就是cm)与mutate提取后的字段(adv)解析对比
3.纯文本字符串(正则捕获)
配置文件信息
input {
file {
path => "/opt/aa.txt"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
grok {
match => { "message" => "(?<userid>[0-9]+)\|(?<event_name>[a-zA-Z_]+)\|(?<times>[0-9]+)\|(?<clientip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})" } //自定义表达式语法,在message字段中匹配正则
remove_field => ["message"] //删除message字段未被正则匹配的部分
}
}
output {
stdout {
codec => rubydebug
}
}
注:自定义表达式语法:(?<field_name>regex),调用字段名即可调用字段内容
4.纯文本+json格式混合的字符串
input{
file{
path => "/opt/exam/exam.log"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter{
grok{
match => { "message" => "(?<userid>[0-9]+)\|(?<event_name>[a-zA-Z_]+)\|(?<events>\{.*\})\|(?<times>[a-zA-Z]+)" } //先正则分割每个部分(同时也会分出json格式数据,以便后续调用json类型字段)
remove_field => [ "message" ]
}
json{ //取出json格式部分,正常作为json格式的字符串处理
source => "adv"
remove_field => [ "adv","events" ]
}
}
output{ //输出到ES数据库
elasticsearch{
hosts => "http://192.168.56.100:9200"
index => "mmm"
document_type => "yyy"
}
}
#多个文件解析
input {
file {
path => "/opt/aa.txt"
start_position => "beginning"
sincedb_path => "/dev/null"
type => "system" //为每个文件增加type类型作为条件
}
file {
path => "/opt/bb.txt"
start_position => "beginning"
sincedb_path => "/dev/null"
codec => json
type => "action"
}
}
filter {
if [type] == "system" { //过滤时根据type类型转为对单一文件的解析
grok {
match => { "message" => "(?<userid>[0-9]+)\|(?<event_name>[a-zA-Z_]+)\|(?<times>[0-9]+)\|(?<clientip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})" }
remove_field => ["message"]
}
}else {
mutate {
add_field => { "adv" => "%{cm}" }
}
json {
source => "adv"
remove_field => [ "adv","cm" ]
}
}
}
output { //根据type类型输出到不同位置(索引)
if [type] == "system" {
elasticsearch {
hosts => "http://192.168.56.100:9200"
index => "systems"
document_type => "sys"
}
} else{
elasticsearch {
hosts => "http://192.168.56.100:9200"
index => "customs"
document_type => "actions"
}
}
}
导入到ES数据库
output{ //输出流
elasticsearch{ //输出类型:ES数据库
hosts => "http://192.168.56.100:9200" //数据库地址
index => "mmm" //数据库索引(数据库名)
document_type => "yyy" //数据库类型(表名)
}
}