33

我目前正在尝试制定一种整理由 Cron 创建的 Oracle Recover 日志文件的方法...

目前,Cron 使用以下命令每 15 分钟调用一次我们的 Oracle 备用恢复过程:

0,15,30,45 * * * * /data/tier2/scripts/recover_standby.sh SID >> /data/tier2/scripts/logs/recover_standby_SID_`date +\%d\%m\%y`.log 2>&1

这将创建如下所示的文件:

$ ls -l /data/tier2/scripts/logs/
total 0
-rw-r--r-- 1 oracle oinstall 0 Feb  1 23:45 recover_standby_SID_010213.log
-rw-r--r-- 1 oracle oinstall 0 Feb  2 23:45 recover_standby_SID_020213.log
-rw-r--r-- 1 oracle oinstall 0 Feb  3 23:45 recover_standby_SID_030213.log
-rw-r--r-- 1 oracle oinstall 0 Feb  4 23:45 recover_standby_SID_040213.log
-rw-r--r-- 1 oracle oinstall 0 Feb  5 23:45 recover_standby_SID_050213.log
-rw-r--r-- 1 oracle oinstall 0 Feb  6 23:45 recover_standby_SID_060213.log
-rw-r--r-- 1 oracle oinstall 0 Feb  7 23:45 recover_standby_SID_070213.log
-rw-r--r-- 1 oracle oinstall 0 Feb  8 23:45 recover_standby_SID_080213.log
-rw-r--r-- 1 oracle oinstall 0 Feb  9 23:45 recover_standby_SID_090213.log
-rw-r--r-- 1 oracle oinstall 0 Feb 10 23:45 recover_standby_SID_100213.log
-rw-r--r-- 1 oracle oinstall 0 Feb 11 23:45 recover_standby_SID_110213.log
-rw-r--r-- 1 oracle oinstall 0 Feb 12 23:45 recover_standby_SID_120213.log

我基本上想删除早于 x 天的文件,我认为 logrotate 非常适合......

我已经使用以下配置文件配置了 logrotate:

/data/tier2/scripts/logs/recover_standby_*.log {
    daily
    dateext
    dateformat %d%m%Y
    maxage 7
    missingok
}

为了获得理想的结果,我是否缺少某些东西?

我想我可以从 Crontab 日志文件中删除日期,然后让 logrotate 旋转该文件,但是日志文件中的日期不会反映日志生成的日期......即 010313 上的恢复将在文件中由于 logrotate 在 020313 上触发并旋转文件,因此日期为 020313...

还有其他想法吗?并提前感谢您的任何回复。

问候

加文

4

6 回答 6

42

Logrotate 根据词法排序的旋转日志文件名列表中的顺序以及文件年龄(使用文件的最后修改时间)删除文件

  • rotate是旋转文件的最大数量,您可能会发现。如果轮换日志文件的数量较多,则它们的名称将按词法排序,并删除词法上最小的文件。

  • maxage定义了删除循环日志文件的另一个标准。任何超过给定天数的旋转日志文件都将被删除。请注意,日期是从文件上次修改时间检测到的,而不是从文件名中检测到的。

  • dateformat允许对旋转文件中的日期进行特定格式设置。手册页说明,该格式应导致词法正确排序

  • dateyesterday允许在一天前的日志文件名中使用日期。

要在每日轮换文件中保留给定的天数(例如 7),您必须将rotate值设置为 7 并且您可以忽略maxage,如果您的文件是每天都创建和轮换的。

如果在几天内(例如 14 天)未创建日志,则轮换日志文件的数量仍将相同 (7)。

maxage将通过始终删除太旧的文件来改善“未生成日志”场景中的情况。在 7 天没有生成日志后,将不存在轮换的日志文件。

您不能dateformat用作 OP 节目,因为它不是词法可排序的。搞砸dateformat可能会导致删除其他轮换的日志文件,而不是您真正想要的。

提示:从命令行运行 logrotate 并带有-d执行空运行的选项:您将看到 logrotate 会做什么,但实际上并没有做任何事情。然后使用 (verbose) 执行手动运行-v,以便您可以确认所做的是您想要的。

解决方案:清理 cron 创建的日志

这个概念是:

让 cron 创建和更新日志文件,但对创建文件进行小修改,使用默认时遵循 logrotate 标准文件名dateext

/data/tier2/scripts/logs/recover_standby_SID.log-`date +\%Y\%m\%d`.log

仅使用 logrotate 删除太旧的日志文件

  • 针对不存在的日志文件/data/tier2/scripts/logs/recover_standby_SID.log
  • 用于missingok让 logrotate 清理发生
  • 设置rotate得足够高,以涵盖要保留的日志文件的数量(至少 7 个,如果每天会有一个“轮换”日志文件,但您可以安全地将其设置得非常高,例如 9999)
  • 设置maxage为 7。这将删除最后修改时间超过 7 天的文件。
  • dateext仅用于确保 logrotate 搜索看起来像已旋转的旧文件。

Logrotate 配置文件如下所示:

data/tier2/scripts/logs/recover_standby_SID.log {
    daily
    missingok
    rotate 9999
    maxage 7
    dateext
}

解决方法:直接通过 logrotate 每天旋转一次

我不确定,源恢复备用文件是如何创建的,但我会假设,Oracle 或您的某些脚本定期或持续附加到文件/data/tier2/scripts/logs/recover_standby_SID.log

这个概念是:

  • 每天将文件旋转一次logrotate
  • 直接使用包含恢复数据的日志文件/data/tier2/scripts/logs/recover_standby_SID.log
  • daily将导致每天一次轮换(就如何cron理解而言daily
  • rotate必须设置为 7(或任何更高的数字)。
  • maxage设置为 7(天)
  • dateext使用默认的 logrotate 日期后缀
  • dateyesterday用于导致旋转文件中的日期后缀在一天前。
  • missingok即使不存在要旋转的新内容,也可以清理旧文件。

Logrotate 配置看起来像:

data/tier2/scripts/logs/recover_standby_SID.log {
    daily
    missingok
    rotate 7
    maxage 7
    dateext
    dateyesterday
}

请注意,您可能需要使用copytruncate其他类似选项,这些选项与外部进程如何创建源日志文件以及它如何对轮换行为作出反应有关。

于 2014-12-19T12:56:26.763 回答
30

您可以使用find命令轻松完成该任务!它将删除所有7 Days旧文件。将其放入crontab并每晚运行:

$ cd /data/tier2/scripts/logs/    
$ /usr/bin/find . -mtime +7 -name "*.log" -print -delete

或者更好的方法

$ /usr/bin/find /data/tier2/scripts/logs/ -mtime +7 -name "*.log" -print -delete;
于 2013-02-13T18:42:35.597 回答
5

(更新)您的选择是:

  • 正如 Satish 回答的那样,放弃 logrotate 并在 cron 中放置一个查找脚本
  • 您甚至可以使用 logrotate 并将 find 脚本放在 postrotate 命令中

最初,我认为更改日期格式以匹配您的日志可能会起作用,但正如 Reid Nabinger 指出的那样,日期格式无论如何都与 logrotate 不兼容。最近,我尝试配置相同的东西,但对于我希望 logrotate 删除的 Java 旋转日志。我尝试了下面的配置,但它一直试图删除所有日志

/opt/jboss/log/server.log.* {
    missingok
    rotate 0
    daily
    maxage 30
}

我最终只是实现了 Satish 的建议——在 cron 中使用 rm 脚本进行简单查找。

于 2013-10-04T17:05:33.793 回答
3

(无法评论,因为没有足够的声誉)

我有一个类似的问题。众所周知,logrotate 对于带有内置日期戳的文件名是无用的。

如果其他一切都相同,我可能会find从事 cron 工作。

由于我自己的原因,我想使用 logrotate 并最终找到了一种方法:https ://stackoverflow.com/a/23108631

本质上,这是一种将 cron 作业封装在 logrotate 文件中的方法。也许不是最漂亮或最有效的,但就像我说的,我有我的理由。

于 2014-07-19T07:34:23.693 回答
2

根据@Jan Vlcinsky,您可以让 logrotate 添加日期 - 只需用于dateyesterday获取正确的日期。

或者,如果您想自己输入日期,则可以“瞄准”没有日期的名称,然后将清除带有日期的名称。

但是,我发现如果那里没有日志文件,logrotate 不会清理带有日期的文件。

但是如果你准备好有一个空的日志文件,那么它就可以工作了。

例如,清理 /var/log/mylogfile。yyyymmdd .log 7 天后, touch /var/log/mylogfile.log, 然后配置 logrotate 如下:

/var/log/mylogfile.log
{
        日常的
        旋转 7
        最大 7
        日期文本
        日期格式 .%Y%m%d
        扩展名 .log
        空的
        创造
}

此条目与 mylogfile.log 的存在相结合,触发 logrotate 清理旧文件,就好像它们是由 logrotate 创建的一样。

dailyrotate加上maxage导致旧日志文件在 7 天后被删除(或 7 个旧日志文件,以先到者为准)。

dateext, dateformatplusextension导致 logrotate 匹配我们的文件名。

还要ifempty确保create那里仍然有一个空文件,否则日志轮换将停止。

另一个测试提示,准备编辑 /var/lib/logrotate.status 以重置“最后轮换”日期,否则 logrotate 不会为您做任何事情。

于 2017-11-12T12:56:04.790 回答
1

仅供参考,我知道这是一个老问题,但它对你不起作用的原因是你的日期格式不是词法可排序的。从手册页:

   dateformat format_string
          Specify the extension for dateext using the notation similar to strftime(3)  function.  Only
          %Y  %m  %d  and %s specifiers are allowed.  The default value is -%Y%m%d. Note that also the
          character separating log name from the extension is part of the dateformat string. The  sys-
          tem  clock must be set past Sep 9th 2001 for %s to work correctly.  Note that the datestamps
          generated by this format must be lexically sortable (i.e., first the year,  then  the  month
          then  the  day.  e.g.,  2001/12/01 is ok, but 01/12/2001 is not, since 01/11/2002 would sort
          lower while it is later).  This is because when using the rotate option, logrotate sorts all
          rotated filenames to find out which logfiles are older and should be removed.

解决方案是更改为年月日,或调用外部进程来执行清理。

于 2015-04-29T18:41:34.847 回答