有清除日志的正确方法吗?


64

我想知道总体上是否存在清除日志的正确方法?

我是Ubuntu的新手,正在尝试设置Postfix。有问题的日志是/var/log/mail.log。我想知道是否有清除它的正确方法,而不是我进入它并删除所有行并保存它。我发现有时清除日志并保存后,不会立即将错误写入其中。

旁注:我在设置Postfix时遇到麻烦,并且试图使我更容易阅读日志,希望它可以对我有所帮助,而不必一直向下滚动。


2
如果您只想看文件的结尾,那么tail是您的朋友。tail /var/log/mail.log显示最后5行。tail -f /var/log/mail.log查看写入文件末尾的所有行。
2011年

Answers:


79

您可以使用:

> /var/log/mail.log

这将截断日志,而无需您编辑文件。这也是收回空间的可靠方法。有时人们会在日志上使用rm,然后重新创建文件名,这是一个错误,如果另一个进程打开了文件,那么直到该进程关闭它的句柄并且您可能弄乱了它的权限后,您才获得空间。

另外,如果您正在查看日志的内容,则可能要使用以下tail命令:

tail -f /var/log/mail.log

Ctrl-C将断开拖尾。


2
/bin/csh(对于FreeBSD来说是常见的)将使用“无效的null命令”来解决此问题,同时zsh(通常是的替代bash)将等待EOF。参见serverfault.com/a/381380/67675
poige'4

我该如何安排时间?将>语法放入crontab中未运行,因为它可能无法将其识别为语法
ishandutta2007

26

是的,有一种适当的方法:您根本不清除日志。您旋转它们。轮换涉及将日志输出切换到同名的新文件,而之前的N个日志文件保留在一组N个相关的文件名下。

日志如何旋转取决于一开始如何编写日志。 这是一个经常被忽视的问题。这里的一些答案至少涉及到它,提到某些日志记录程序会为日志文件保留一个打开的文件描述符,因此仅删除该文件不会释放空间,甚至实际上不会将输出切换到新的日志文件。

例如,如果编写日志文件的程序multilog来自daemontools软件包,那么您根本不会做任何旋转日志的操作-无需手动脚本,也无需cron作业。简单地说multilog,日志输出是到目录的,它本身将在该目录中维护一组自动轮换且大小受限制的N个日志文件。

另一个示例,如果编写日志文件的程序svlogd来自runitpackage,则同样适用。除了将工具指向目录之外,您什么也不需要做。它本身将在该目录中维护一组自动轮换且大小受限制的N个日志文件。

如果您正在使用rsyslog日志文件,则可以在日志文件达到一定大小并运行脚本后告诉日志记录程序停止。您必须编写脚本的内容,才能根据总大小限制来实际重命名日志文件并删除旧的日志文件,但是至少日志记录程序已关闭该文件,并在发生这种情况时暂停了日志写入。

syslogd日志记录程序(例如syslog-ng)仍然期望这种旧的轮换日志方式,并且这种工具在另一个答案中logrotate提到了这种工具,这种旧方式djangofan有些偶然。一个运行一项cron作业,该作业会定期重命名日志文件,然后重新启动日志记录守护程序(使用运行该守护程序的守护程序)。当然,这样做的问题是它没有强制执行总体大小上限。在较慢的几周中,每天可以获取N个非常小的日志文件,而在繁忙的日子中,则可以获取1个非常大的日志文件,这些文件的大小超出限制。

这就是为什么像后来和更好的工具multilogsvlogd具有文件大小配置选项和实际检查日志文件大小本身,当然。世界已经了解到,按照cron作业,甚至是logrotate守护程序的时间表轮询日志会留下错误的大小窗口,并在适当的位置进行这些检查,因此严格执行管理员定义的大小上限,以便日志文件永远不会吞噬它们所在的分区,而是位于实际上首先将文件写出的程序中。


对于rsyslog,可以轻松配置它,使其依赖于由“模式”描述的文件名,例如,YEAR,MONTH和DAY。就像有一个template(name="DYNmail" type="string" string="/var/log/%$YEAR%/%$MONTH%/%$DAY%/mail.log")指令然后跟一个指令一样容易if ($syslogfacility-text == 'mail') then -?DYNmail;TraditionalFormat。这样,至少在每天可以单个文件的情况下,日志轮转仅仅是一个问题。对于大量日志(每天需要多次轮换),也有$HOUR
Damiano Verzulli 2015年

13

您也可以使用它。

truncate /opt/package/logs/*.log --size 0

此处,/ opt / package / logs中的所有日志文件都将为空。


我看不出有什么比以前的答案更好的了。
kasperd

4
这实际上是一个很好的答案,并且实际上是唯一直接回答是否存在截断日志文件的正确方法的问题。与其他答案相比,如何更好地是未删除日志文件,而是将内容正确归零,因此在这种情况下,不会发生权限错误和缺少日志文件,这些日志文件会导致某些守护程序出现紧急情况。
hmedia1

11

是的,有一个用于Linux的名为LogRotate的工具。


9
只是一个小小的修正:这不是服务,而是工具,通常从cron服务运行。
rvs

10

如果清除日志的原因是要释放空间,则可以将/ dev / null分配给它们,而不会中断写入其中的程序。永远不要删除它们!某些软件可能会抱怨停止工作或完全忽略日志直到下次重启

cat /dev/null > /path/to/logfile

# to empty all the logs in a directory
for i in /var/log/*; do cat /dev/null > $i; done

3
要递归清除日志文件:for i in $(find /var/log -type f); do cat /dev/null > $i; done
Iurie Malai'2

4

简短而兼容的内容覆盖: : > /dest/file

但是truncate在许多* NIX上也有truncate(2)系统调用和相应的用户空间工具。


1

如果要在清理之前保留文件,可以执行以下操作:

cp /var/log/mail.log /var/log/mail.log.1 && echo -n "" > /var/log/mail.log

如果要在日志中搜索特定的文本或电子邮件,可以使用grep。如果要保留一些有关邮件使用情况的图形,则可以使用AWStats。


1

这是我的操作方法,这仅适用于NGINX,您可以删除它以使其适用于所有日志文件。

# Clear nginx logs.
# @usage delnginxlogs
function delnginxlogs() {
  echo "--------------- ⏲  Clearing logs... ---------------"

  # Clear logs.
  for i in /var/log/nginx/*; do cat /dev/null > $i; done

  echo "--------------- ⏲  Deleting .gz log files... ---------------"

  # Delete .gz files.
  find /var/log/nginx -type f -regex ".*\.gz$" -delete

  echo "--------------- 💯 DONE: NGINX logs cleared ... ---------------"
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.