如何使用 Corretto 8/Amazon Linux 2 平台限制 Elastic beanstalk 上的日志大小?

如何使用 Corretto 8/Amazon Linux 2 平台限制 Elastic beanstalk 上的日志大小?

我们最近将我们的一个应用程序迁移到“在 64 位 Amazon Linux 2/3.2.12 上运行的 Corretto 8”平台。现在我们发现一个问题,即日志文件在一周多的时间内填满了我们的磁盘卷。我们以前没有遇到过这个问题。

令人恼火的是,我们正在将这些日志流式传输到 CloudWatch,因此我们实际上不需要在实例本身上使用它们。更令人恼火的是,我能找到的所有文档、博客文章等显然都不是为这个平台编写的。查看文件结构时,似乎它采用了一种我还没有完全弄清楚的不同方法。

首先,没有 /var/log/httpd ... 文件夹或其他用于特定日志的文件夹。到目前为止,我已经弄清楚发送到 web.stdout.log 日志流(在旧平台上,它曾经被命名为不同的名称,但我不记得具体名称了。无论如何,它是 spring-boot 应用程序记录日志的地方)的内容存储在文件 /var/log/messages 中。

我知道这一点,是因为在分析磁盘空间不足的原因时,这个文件始终是整个磁盘上最大的文件。除了在实例启动后,它的大小还算合理。3 天后,它的大小可以达到 2 GB,并且会一直增长,直到什么都没有了。毫无疑问,这就是我们麻烦的根源。

问题是,我能做什么关于它?日志轮换处于默认配置中,我可以在 /var/log/rotated 中看到一些文件(也是一个与轮换日志所在的文件夹不同的文件夹),但那些文件很小(其中最大的文件大小为 1.3 MB...),并且 /var/log/messages 的大小永远不会减小,只会增长。

我读过许多关于如何使用 ebextensions 配置 logrotate 来解决类似问题的文章,有 AWS 自己写的,也有博主写的,但我很快就发现,这些文章都是建立在非常不同的结构之上的,所以似乎不太适用。此外,我们在迁移过程中已经发现,一些使用 ebextensions 完成的事情现在不再使用 ebextensions 完成了,但文档相当缺乏。

有谁足够了解这个平台,能给我一些关于如何配置它的线索吗?我甚至不需要旋转严格来说,日志一旦超过一小时左右,我只想尽快删除它们。毕竟,我们在 CloudWatch 上拥有它们……

附加信息 我对此研究得越深,就越感到困惑。有一个 /var/log/web.stdout.log 文件,它接收与 /var/log/messages 相同的消息。查看 logrotate.elasticbeanstalk.hourly 的内容,这是实际上处于日志轮换中的文件,并且似乎运行良好。

执行 lsof 时,使用该文件的进程是 rsyslogd。根据以下 shern89s 的评论,显然这是新的 syslog,记录到 stdout 的所有内容都会记录在那里。

意识到该文件不属于任何类型的轮换,我正尝试进行设置。目前只在实例上直接设置,稍后我将弄清楚如何在实际环境配置中执行此操作。

我在 /etc/logrotate/elasticbeanstalk.hourly 中创建了一个新的配置文件,其内容如下:

/var/log/messages {
 su root root
 size 10M
 rotate 5
 missingok
 compress
 notifempty
 copytruncate
 dateext
 dateformat %s
 olddir /var/log/rotated
}

运行后sudo /usr/sbin/logrotate /etc/logrotate.elasticbeanstalk.hourly/logrotate.elasticbeanstalk.messages.conf --debug,我得到以下输出:

rotating pattern: /var/log/messages  10485760 bytes (5 rotations)
olddir is /var/log/rotated, empty log files are not rotated, old logs are removed
considering log /var/log/messages
  log needs rotating
rotating log /var/log/messages, log->rotateCount is 5
Converted ' %s' -> '%s'
dateext suffix '1646905905'
glob pattern '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
glob finding old rotated logs failed
copying /var/log/messages to /var/log/rotated/messages1646905905
truncating /var/log/messages
compressing log with: /bin/gzip

这看起来很有希望,但冷酷的事实是似乎什么都没有改变。文件仍然具有相同的大小,并且旋转文件夹中没有创建任何文件。它似乎根本没有效果。我更改了配置,以便它移动并创建而不是就地截断,我尝试了 -f,结果都相同。logrotate 没有错误,但也没有效果。该文件似乎完全无懈可击。

答案1

如果您查看/etc/logrotate.d/syslog,您会发现已经有一个轮换文件的规定/var/log/messages。但配置不会压缩轮换的文件,并且会保留最多 4 周的轮换日志。这对于轻度使用来说没问题,但在每次访问都会流式传输日志的服务器应用程序上,这会很快耗尽磁盘空间。

AWS 现在建议使用.platform/hooks文件而不是.ebextensions。此外,如果被覆盖,.ebextensions还会创建带有扩展名的文件副本。这可能会导致重复的 logrotate 文件,从而导致错误。.bak

我在路径中添加了以下配置文件.platform/hooks/predeploy/modify-logrotate.sh

确保此文件是可执行的并且以正确的 shebang 开始。

#!/bin/sh

fileName=/etc/logrotate.d/syslog
lineCount=($(wc -l "$fileName"))
lineToInsert="$((${lineCount[0]}))"
echo $lineToInsert
sed -i "${lineToInsert}i    compress\n    rotate 1\n    daily" "$fileName"

原始配置文件以}作为最后一行结束。上述代码在结束行上方插入了额外的配置行,以使最终的代码有效。

我不确定这种更改在某些情况下是否会导致无效语法,但我发现没有更好的方法以更安全的方式修改此文件。

答案2

我将其保存在 .ebextensions/liblogrotate.config 中:

files:
   /etc/remove_old_logs.sh:
     owner: root
     group: root
     mode: "000644"
     content: |
       #!/bin/sh
       find /var/log -type f -mtime +7 -exec rm {} +

container_commands:
  01_crontab:
    command: "( crontab -l | grep -v -F \". /etc/remove_old_logs.sh\" ; echo \"0 0 * * * . /etc/remove_old_logs.sh\" ) | crontab -"

它创建一个 crontab,用于删除 /var/log 文件夹中超过 7 天的文件。我知道这不是最佳选择,但我不太关心这些日志。

答案3

最简单的方法是停止将 web stdout 发送到。它只需要在 中相应的 rsyslog 配置中添加/var/log/messages以下行:stop/etc/rsyslog.d/web.conf

# This rsyslog file redirects Elastic Beanstalk platform logs.
# Logs are initially sent to syslog, but we also want to divide
# stdout and stderr into separate log files.

if $programname  == 'web' then {
  *.=warning;*.=err;*.=crit;*.=alert;*.=emerg /var/log/web.stderr.log
  *.=info;*.=notice /var/log/web.stdout.log
  # THE LINE BELOW STOPS SENDING OUTPUT TO ANY OTHER LOG FILES
  stop
}

在目录中创建一个可执行文件(带有chmod +x.platform/hooks/predeploy,其中包含以下内容,以便在部署新版本时应用此配置更改:

#!/bin/sh

FILE="/etc/rsyslog.d/web.conf"

CONTENTS=$(cat <<-END
# This rsyslog file redirects Elastic Beanstalk platform logs.
# Logs are initially sent to syslog, but we also want to divide
# stdout and stderr into separate log files.

if $programname  == 'web' then {
  *.=warning;*.=err;*.=crit;*.=alert;*.=emerg /var/log/web.stderr.log
  *.=info;*.=notice /var/log/web.stdout.log
  stop
}
END
)

echo "$CONTENTS" > "$FILE"
service rsyslog restart

相关内容