ELK入门02—Logstash+Log4j2+ES

1. 安装Logstash

先到官方下载地址选择对应版本的Logstash安装包,由于我们Elasticsearch是2.4.6版本,这里我们Logstash选择2.4.1版本。
下载完成后,直接解压
tar zxvf logstash-2.4.1.tar.gz
进入目录,创建一个配置文件夹,在其中新建一个配置文件

cd logstash-2.4.1
mkdir config
vim config/log4j2-tcp.conf

输入以下内容

input {
    tcp {
        mode => "server"
        host => "127.0.0.1"
        port => 4567
    }
}
filter {
    json {
        source => "message"
    }
}
output {
    stdout {
        codec => rubydebug
    }
}
Logstash处理数据的流程就像它的配置文件一样简单:input -> filter -> output
input配置数据来源,然后经过filter对数据进行过滤,最后输出到output配置的目的地
tcp、json、stdout是插件的名称,可以根据需要选择插件,甚至开发自己的插件,相当的灵活
执行命令 ./bin/logstash-plugin list 可以查看Logstash的插件列表
执行命令 ./bin/logstash-plugin install plugin-name 可以安装插件

配置好了,就可以直接运行了
./bin/logstash agent -f ./config/log4j2-tcp.conf

-f参数指定配置文件

当你看到输出 Pipeline main has been shutdown,表示logstash启动成功

2. log4j2

新建一个Log4j2的工程(请自行准备,简单的demo即可),配置文件log4j2.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Properties>
        <Property name="LOG_PATTERN">{"logger": "%logger", "level": "%level", "msg": "%message"}%n</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>
        <Socket name="logstash-tcp" host="127.0.0.1" port="4567" protocol="TCP">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Socket>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="logstash-tcp" />
        </Root>
    </Loggers>
</Configuration>
如果你的使用的是log4j,那么可以直接使用logstash的log4j插件,这里就不展示了。

由于我们使用的是log4j2,而logstash-input-log4j2插件不支持logstash2.0.0以上的版本,所以这里采用TCP的方式传输日志
为了展示logstash的filter的功能,这里特意把log4j2的pattern设置成json格式的

运行log4j2的工程,然后到logstash运行的控制台,正常的话就可以看到输出

{                                                                                                                                              
    "message" => "{\"logger\": \"ELK\", \"level\": \"INFO\", \"msg\": \"log4j2 to logstash, uuid c944e68c-0247-43c7-ba53-6154eeec7357\"}\r",
    "@version" => "1",
    "@timestamp" => "2018-08-22T06:32:00.963Z",
    "host" => "127.0.0.1",
    "port" => 19766,
    "logger" => "ELK",
    "level" => "INFO",
    "msg" => "log4j2 to logstash, uuid c944e68c-0247-43c7-ba53-6154eeec7357"
}                                                                                                                                              

可以看到Logstash自动添加了几个字段:@version、@timestamp、host、port
logger、level、msg就是filter配置的json插件解析message得到的

3. Logstash-gelf

上面是用的socket方式将日志传输给logstash,如果你恰好遇到了,会发现一个问题,如果把logstash停掉然后再启动,日志就无法继续传输了,也就是说socket无法自动重连,这在生产环境中,当然是个隐患。所以我们用gelf的方式
首先修改log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Properties>
        <Property name="LOG_PATTERN">{"logger": "%logger", "level": "%level", "msg": "%message"}%n</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>
        <Gelf name="logstash-gelf" host="udp:127.0.0.1" port="4567" version="1.1" ignoreExceptions="true">
            <Field name="timestamp" pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}" />
            <Field name="logger" pattern="%logger" />
            <Field name="level" pattern="%level" />
            <Field name="simpleClassName" pattern="%C{1}" />
            <Field name="className" pattern="%C" />
            <Field name="server" pattern="%host" />
        </Gelf>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="logstash-gelf" />
        </Root>
    </Loggers>
</Configuration>

接下来在logstash/config目录下新建一个配置文件
vim ./config/log4j2-gelf.conf
输入以下内容:

input {
    gelf {
        host => "127.0.0.1"
        port => 4567
    }
}
filter {
}
output {
    stdout {
        codec => rubydebug
    }
}
注意input的插件换成了gelf
如果你使用的是高版本的Logstash,执行 ./bin/logstash-plugin list --verbose | grep input-gelf 后,发现你的logstash-input-gelf版本大于等于3.1.0,那么你可以通过增加 use_tcp => true 配置项开启TCP支持,同时记得要把log4j2.xml中 host="udp:127.0.0.1" 改成 host="tcp:127.0.0.1"

启动logstash ./bin/logstash agent -f ./config/log4j2-gelf.conf
然后重新运行log4j2的工程,正常情况下你会看到如下输出:

{
    "host" => "hostname",
    "level" => "INFO",
    "facility" => "logstash-gelf",
    "@version" => "1",
    "@timestamp" => "2018-08-22T08:38:13.053Z",
    "source_host" => "127.0.0.1",
    "message" => "log4j2 to logstash, uuid c5b53dcc-7653-4f3e-bd6a-3164ec8f2dad",
    "server" => "server name",
    "logger" => "ELK",
    "className" => "com.demo.elk.log4j.Log",
    "simpleClassName" => "Log",
    "timestamp" => "2018-08-22 16:38:13.053"
}

可以发现,使用gelf,可以灵活的配置日志的字段。同时如果你关闭后再打开Logstash,会发现已经可以自动重新连接了。

4. 输出到ES

上面我们只是把日志简单的输出到stdout,现在我们要做的是通过logstash把数据保存到Elasticsearch中
其实到了这一步就很简单了,只需要更改logstash的配置文件中output部分,将输出的目的地指向Elasticsearch即可
这里我们在 log4j2-gelf.conf 的基础上新建一个 log4j2-es.conf 配置文件,内容如下:

input {
    gelf {
        host => "127.0.0.1"
        port => 4567
    }
}
filter {
  mutate {
    lowercase => [ "logger", "level" ]
  }
}
output {
    stdout {
        codec => rubydebug
    }
    elasticsearch {
        hosts => ["127.0.0.1:9200"]
        index => "%{logger}"
        document_type => "%{level}"
    }
}

主要是output部分增加了elasticsearch插件的配置
hosts: elasticsearch的地址,数组类型,说明支持输出到多个elasticsearch节点
index: 指定es中index的名称
document_type: 指定index的type名称

  1. %{logger} 和 %{level} 是引用了上面gelf插件得到的字段,同时因为这两个字段原本的值是大写的,而index和document_type必须是小写,所以增加了filter来把这两个字段的值转成小写,所以filter里的内容不是必须的
  2. 由于Elasticsearch以后将不再支持一个index下面多个type,所以document_type这个配置即将过时(官方文档有介绍)

开启elasticsearch,然后执行 ./bin/logstash agent -f ./config/log4j2-es.conf 启动logstash,运行log4j2项目
会看到logstash控制台依然正常输出日志内容,同时访问 http://127.0.0.1:9200/_plugin/head/ 在索引栏目中应该可以看到写入的日志数据

53 声望
3 粉丝
0 条评论
推荐阅读
Git常见错误及解决办法收集
git clone 错误error: RPC 失败。curl 18 transfer closed with outstanding read data remaining错误截图可能原因1:缓存溢出解决办法: {代码...} 可能原因2:下载速度太慢解决办法 {代码...} 如果依然失败,可...

Shawn阅读 899

美团外卖搜索基于Elasticsearch的优化实践
美团外卖搜索工程团队在Elasticsearch的优化实践中,基于Location-Based Service(LBS)业务场景对Elasticsearch的查询性能进行优化。该优化基于Run-Length Encoding(RLE)设计了一款高效的倒排索引结构,使检索...

美团技术团队1阅读 786

封面图
Elasticsearch 按照标签匹配个数优先排序查询
首先最外层的数组就是我们通常写的query语句,放在body中进行请求的,主要看query里面的结构,这种需要自定义脚本处理评分的,query中只放了一个script_score:

kumfo2阅读 711

elasticsearch的开发应用(2)
Query DSL:ElasticSearch提供了一个可以执行的JSON风格的DSL(domain-specific language 领域特定语言),这个被称为Query DSL。

KerryWu1阅读 661

Elasticsearch 7.x 保留字符(qbit)
前言本文对 Elasticsearch 7.x 有效query_string 保留字符官方文档: [链接] {代码...} 在 query_string 里面做通配符匹配时,空格需要转义regex 保留字符官方文档:[链接] {代码...} query_string 与 regex 保留...

qbit阅读 1.6k

ElasticSearch必知必会-基础篇
定义: 相同文档结构(Mapping)文档的结合 由唯一索引名称标定 一个集群中有多个索引 不同的索引代表不同的业务类型数据 注意事项: 索引名称不支持大写 索引名称最大支持255个字符长度 字段的名称,支持大写,...

京东云开发者2阅读 343

封面图
跨机房ES同步实战
众所周知单个机房在出现不可抗拒的问题(如断电、断网等因素)时,会导致无法正常提供服务,会对业务造成潜在的损失。所以在协同办公领域,一种可以基于同城或异地多活机制的高可用设计,在保障数据一致性的同时...

京东云开发者1阅读 689

封面图
53 声望
3 粉丝
宣传栏