Docker应用程序使用Filebeat和Logstash进行日志记录

Gia*_*uca 22 logstash docker logstash-forwarder elastic-stack

我有一组分散在多个服务器上的dockerized应用程序,并尝试使用ELK设置生产级集中式日志记录.我对ELK部件本身没问题,但我对如何将日志转发到我的logstashes有点困惑.我正在尝试使用Filebeat,因为它具有loadbalance功能.我还想避免将Filebeat(或其他任何东西)打包到我的所有码头工人中,并保持它分离,对接或不用.

我该怎么办?

我一直在尝试以下方面.我的Docker登录stdout所以配置了非dockerized Filebeat从stdin读取我做:

docker logs -f mycontainer | ./filebeat -e -c filebeat.yml

这似乎在开始时起作用.第一个日志将转发到我的logstash.我想是缓存的.但在某些时候它会卡住并继续发送相同的事件

这只是一个错误还是我朝错误的方向前进?你设置了什么解决方案?

Pet*_*ete 19

这是转发docker logs到ELK堆栈的一种方法(对于gelf日志驱动程序,需要docker> = 1.8):

  1. 使用gelf输入插件启动Logstash容器,从gelf读取并输出到Elasticsearch主机(ES_HOST:port):

    docker run --rm -p 12201:12201/udp logstash \
        logstash -e 'input { gelf { } } output { elasticsearch { hosts => ["ES_HOST:PORT"] } }'
    
    Run Code Online (Sandbox Code Playgroud)
  2. 现在启动一个Docker容器并使用gelf Docker日志记录驱动程序.这是一个愚蠢的例子:

    docker run --log-driver=gelf --log-opt gelf-address=udp://localhost:12201 busybox \
        /bin/sh -c 'while true; do echo "Hello $(date)"; sleep 1; done'
    
    Run Code Online (Sandbox Code Playgroud)
  3. 加载Kibana,docker logs现在可以看到已经登陆的东西.该GELF源代码表明,一些方便的字段为您生成(帽尖:克里斯托夫拉布伊斯): ,_container_id,_container_name,_image_id,_image_name,_command,._tag_created

如果您使用docker-compose(确保使用docker-compose> = 1.5)并docker-compose.yml在启动logstash容器后添加适当的设置:

log_driver: "gelf"
log_opt:
  gelf-address: "udp://localhost:12201"
Run Code Online (Sandbox Code Playgroud)

  • 我认为gelf的问题是它使用的是udp并且可能会静默地丢弃日志事件. (3认同)
  • 好点,@urso.可以通过类似的方式使用`syslog`日志记录驱动程序通过TCP [这是一个示例](https://github.com/edefaria/docker-logstash)传递日志.[Graylog扩展格式(GELF)文档](https://www.graylog.org/resources/gelf/)提到了使用TCP与UDP静默丢弃日志记录事件形成对比的潜在问题. (3认同)

mic*_*ahr 9

Docker允许您指定正在使用的logDriver.这个答案不关心Filebeat或负载平衡.

在演示文稿中,我使用syslog将日志转发到侦听端口5000的Logstash(ELK)实例.以下命令不断通过syslog将消息发送到Logstash:

docker run -t -d --log-driver=syslog --log-opt syslog-address=tcp://127.0.0.1:5000 ubuntu /bin/bash -c 'while true; do echo "Hello $(date)"; sleep 1; done'
Run Code Online (Sandbox Code Playgroud)


urs*_*rso 8

使用filebeat,你可以docker logs像你所描述的那样管道输出.你看到的行为肯定听起来像一个bug,但也可能是部分行读取配置击中你(重新发送部分行直到找到换行符号).

如果没有可用的logstash,我在管道上看到的问题可能是背压.如果filebeat无法发送任何事件,它将在内部缓冲事件,并在某些时候停止从stdin读取.不知道如何/如果docker防止stdout变得反应迟钝.如果您使用docker-compose,管道的另一个问题可能是filebeat + docker的重启行为.docker-compose默认重用图像+图像状态.因此,当您重新启动时,您将再次发送所有旧日志(假设基础日志文件尚未轮换).

您可以尝试将docker写入的日志文件读取到主机系统,而不是管道.默认的docker日志驱动程序是json日志驱动程序.你可以而且应该配置json日志驱动程序来执行log-rotation +保留一些旧文件(用于在磁盘上缓冲).请参阅max-size和max-file选项.json驱动程序为每行记录一行'json'数据.在docker主机系统上,日志文件将写入/var/lib/docker/containers/container_id/container_id-json.log.这些文件将通过filebeat转发到logstash.如果logstash或网络变得不可用或重新启动filebeat,它将继续转发它所在的日志行(由于日志轮换,给定的文件未被删除).不会丢失任何事件.在logstash中,您可以使用json_lines编解码器或过滤器来解析json行和grok过滤器,以从日志中获取更多信息.

一些关于使用libbeat(由filebeat用于发送日志文件)向docker添加新日志驱动程序的讨论.也许有可能通过docker logs api在未来通过dockerbeat收集日志(我不知道有关利用logs api的任何计划).

使用syslog也是一种选择.也许您可以在docker主机负载平衡日志事件上获得一些syslog中继.或者让syslog写入日志文件并使用filebeat转发它们.我认为rsyslog至少有一些故障转移模式.如果活动logstash实例变得不可用,您可以使用logstash syslog输入插件和rsyslog将日志转发到具有故障转移支持的logstash.


Bri*_*son 7

我使用Docker API创建了自己的docker镜像,以收集机器上运行的容器的日志,并通过Filebeat将它们运送到Logstash.无需在主机上安装或配置任何内容.

检查出来并告诉我它是否符合您的需求:https://hub.docker.com/r/bargenson/filebeat/.

代码可在此处获得:https://github.com/bargenson/docker-filebeat