logback发送日志到filebeat
干掉logstash
传统ELK模式在收集日志方面使用logstash,在应用端创建一个java进程读取应用日志传送出去。
这种方式其实是比较臃肿和消耗资源的,假设有50个服务器就最少需要50个logstash进程,如果每个服务器有多个需要收集的log文件(不同的java进程),也要考虑每个文件的日志格式,特别是前期没有考虑ELK的情况,可能需要做很多工作让这些文件格式一致,若不能达成一致则可能要多个logstash解析。
针对这种情况,我们最好能有一个解决方案,把logstash去除掉,无缝衔接应用,解决log格式差异,而且对业务本身透明。
直接用logback发送日志
要干掉logstash,必须改变日志收集方式,我们找到了开源项目logstash-logback-encoder。
logstash-logback-encoder是logback的扩展,它的主要工作是帮我们把日志格式化成ELK标准的json格式,并且通过它发送到ELK。
通过maven把它构建进你的项目,要注意logback版本需要1.2.0或以上。
然后在你的logback.xml配置加上如下appender:
1 | <appender name="stash" class="net.logstash.logback.appender.LogstashSocketAppender"> |
- customFields 自定义的字段,推荐加上HOSTNAME,便于在负载均衡的情况下分辨具体的服务器。
- Prefix/Suffix 在行首/行末增加点东西,这里表示在行末增加换行符,否则所有json格式日志写在一行,filebeat不认。
上面的配置使用udp方式把日志发送到filebeat server,udp相对于tcp来说对程序和业务基本无影响,就算接收端不能访问也不会阻塞网络或者进程,在内网传输推荐使用udp。
filebeat接收udp数据
新版filebeat 7.6.0 可以接收udp数据包,直接创建配置文件
1 | filebeat.inputs: |
filebeat + socat(内容太老废弃)
filebeat 我们之前在做nginx access log传输的时候使用过,对他的处理能力比较认可,最新5.2版和5.0版配置有点差别。
实现logback直接发送日志后,我们需要在远端搭建filebeat接收udp数据并且转发给Elasticsearch。
其实也可以使用logstash,但是logstash是java开发的,对比filebeat使用go开发,并发性能理论上差点,我们做多个服务器日志转发所以选择并发性和处理能力较好的。
filebeat本身不支持监听udp端口,我们需要一个辅助工具:socat
socat负责监听udp并把数据转到标准输出,filebeat使用stdin输入数据:
1 | socat -u -lf/var/log/socat.log udp-listen:5111,fork - | filebeat.sh -c /etc/filebeat/filebeat-dev.yml |
-u 表示单向传输数据,从udp 5111端口到标准输出,默认双向传输-lf 可以把日志写到文件,方便保存排错fork 创建子进程处理实际数据
ps:测试过nc,在接收长日志,比如带stack trace的java ERROR日志,会接收不完整。
ilebeat5.2配置:
1 | filebeat.prospectors: |
json.message_key 接收json格式数据json.keys_under_root 把接收到的json字段放在顶端json.overwrite_keys 字段相同则覆盖output.kafka 输出到kafka,还有其他选择,比如logstash,redis,Elasticsearch等,具体参考文档- ~~output.console 输出到console,调试用 ~~
ok,现在应该可以在kibana看到你传输的java日志了。