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/ 在索引栏目中应该可以看到写入的日志数据


Shawn
56 声望3 粉丝