记录在同一主机上运行的多个容器的解决方案

问题描述 投票:7回答:4

目前,我们将所有应用程序日志从多个容器重定向到stdout,并通过主机中的rsyslog将/ var / log / message收集到ELK堆栈。

所有docker容器日志显示为docker / xxxxxxxx,我们无法分辨这个日志是哪个应用程序,无论如何我们可以轻松地将应用程序与docker stdout中的多个容器日志区分开来?

logging docker
4个回答
19
投票

(OS X的说明,但应该在Linux中有效)

似乎没有办法使用docker命令执行此操作,但是在bash中,您可以同时运行多个命令,而使用sed,您可以使用容器名称作为前缀。

docker logs -f --tail=30 container1 | sed -e 's/^/[-- containerA1 --]/' &
docker logs -f --tail=30 container2 | sed -e 's/^/[-- containerM2 --]/' &

并且您将同时看到两个容器的输出。

[-- containerA1 --] :: logging line
[-- containerA1 --] :: logging line
[-- containerM2 --] :: logging line
[-- containerM2 --] :: logging line
[-- containerA1 --] :: logging line
[-- containerA1 --] :: logging line
[-- containerM2 --] :: logging line
[-- containerM2 --] :: logging line

要立即拖尾所有容器:

#!/bin/bash

names=$(docker ps --format "{{.Names}}")
echo "tailing $names"

while read -r name
do
  # eval to show container name in jobs list
  eval "docker logs -f --tail=5 \"$name\" | sed -e \"s/^/[-- $name --] /\" &"
  # For Ubuntu 16.04
  #eval "docker logs -f --tail=5 \"$name\" |& sed -e \"s/^/[-- $name --] /\" &"
done <<< "$names"

function _exit {
  echo
  echo "Stopping tails $(jobs -p | tr '\n' ' ')"
  echo "..."

  # Using `sh -c` so that if some have exited, that error will
  # not prevent further tails from being killed.
  jobs -p | tr '\n' ' ' | xargs -I % sh -c "kill % || true"

  echo "Done"
}

# On ctrl+c, kill all tails started by this script.
trap _exit EXIT

# For Ubuntu 16.04
#trap _exit INT

# Don't exit this script until ctrl+c or all tails exit.
wait

并阻止他们运行fg,然后按ctrl+c为每个容器。

更新:感谢@ Flo-Woo支持Ubuntu 16.04


1
投票

你看过fluentd吗?它可能是你需要的。


0
投票

为什么要依赖/ var / log / messages日志来获取应用程序日志?在我看来,您的应用程序日志应该是独立的。

假设您有一个java,ruby,python,node,golang app(Whatever),那么您可以将容器中的日志泵入/var/log/myapp/myapp.log。在您的容器中运行您的日志forwarder,以便在/var/log/myapp/myapp.log下运送到ELK的所有内容

通常,托运人将根据HOSTNAME env变量将主机名显示为您的container_id。例如:

[user@1dfab5ea15cd ~]# env | grep HOSTNAME
HOSTNAME=1dfab5ea15cd
[user@1dfab5ea15cd ~]#

您还可以使用Beaverlog-courier之类的东西运送您的日志。

如果担心磁盘空间,您可以旋转日志并删除旧日志。

因此,如果您想使用docker logs命令重定向到STDOUT和STDERR,您将让您的应用程序编写标识容器/应用程序的日志。 (容器可能是主机名)但您可以在主机上重定向到/var/log/app/application.log。就像是:

containerid/<hostname>-application: INFO: <message>

不要以为还有别的办法......

您也可以切换到Fluentd而不是Logstash作为另一种选择。


0
投票

这是一个拖尾所有docker容器的脚本。

基于answer by @nate,但有点短。在CentOS上测试。

#!/bin/bash

function _exit {
  kill $(jobs -p)
}

trap _exit EXIT

for name in $(docker ps --format "{{.Names}}"); do
  eval "docker logs -f --tail=5 \"$name\" | sed -e \"s/^/[-- $name --] /\" &";
done

wait
© www.soinside.com 2019 - 2024. All rights reserved.