使用Bash脚本旋转日志 [英] Log rotating with a Bash script

查看:38
本文介绍了使用Bash脚本旋转日志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到以下问题:

我有一个应用程序,该应用程序连续向stderr和stdout生成输出.该应用程序的输出捕获在一个日志文件中(该应用程序重定向为:&> log.txt ).我没有任何选择可以为此生成适当的日志记录.

I have an application, which continuously produces output to stderr and stdout. The output of this application is captured in a logfile (the app is redirected as: &> log.txt ). I don't have any options to produce a proper logging to file for this.

现在,我有一个cron作业,该作业每小时运行一次,除了执行其他操作外,它还尝试通过将此日志文件复制到log.txt.1来在上面旋转该日志文件,然后创建一个空文件并将其复制到log.txt

Now, I have a cron job, which runs every hour and beside of doing other things, it also tries to rotate this logfile above, by copying it to log.txt.1 and then creates an empty file and copies it to log.txt

它看起来像:

cp log.txt log.txt.1
touch /tmp/empty
cp /tmp/empty log.txt

问题是,应用程序仍在写入它,因此,我在log.txt.1中得到了一些非常奇怪的东西,它以很多垃圾字符开头,而实际的日志文件在某个地方最后.

The problem is, that the application is still writing to it, and because of this I get some very strange stuff in the log.txt.1, it starts with a lot of garbage characters, and the actual log file is somewhere at the end.

您有什么想法,如何针对这种特定情况旋转正确的日志(我也尝试过 cat log.txt> log.txt.1 ,不起作用)?对于该特定应用程序不使用 logrotate ,在幕后有一种我可能不会更改的完整机制.

Do you have any idea, how to make a correct log rotating for this specific situation (I also tried cat log.txt > log.txt.1, does not work)? Using logrotate for this specific application not an option, there is a whole mechanism behind the scenes that I may not change.

谢谢,f.

推荐答案

好的,这是一个灵感,灵感来自

Okay, here's an idea, inspired by http://en.wikibooks.org/wiki/Bourne_Shell_Scripting/Files_and_streams

  1. 创建一个命名管道:

  1. make a named pipe:

mkfifo /dev/mypipe

  • 将stdout和stderr重定向到命名管道:

  • redirect stdout and stderr to the named pipe:

    &> /dev/mypipe
    

  • 从mypipe读取到文件:

  • read from mypipe into a file:

    cat < /dev/mypipe > /var/log/log.txt &
    

  • 当您需要旋转日志,杀死猫,旋转日志并重新启动猫时.

  • when you need to log-rotate, kill the cat, rotate the log, and restart the cat.

    现在,我尚未对此进行测试.告诉我们进展如何.

    Now, I haven't tested this. Tell us how it goes.

    注意:您可以为命名管道指定任何名称,例如/var/tmp/pipe1,/var/log/pipe,/tmp/abracadabra等.只需确保在启动 您的日志记录脚本运行之后重新创建管道即可.

    Note: you can give the named pipe any name, like /var/tmp/pipe1 , /var/log/pipe , /tmp/abracadabra , and so on. Just make sure to re-create the pipe after booting before your logging-script runs.

    或者,不使用cat,而是使用一个简单的脚本文件:

    Alternatively, don't use cat, but use a simple script file:

    #!/bin/bash
    
    while : ; do
      read line
      printf "%s\n" "$line"
    done
    

    此脚本保证每个换行符读取的输出.(猫可能在缓冲区已满或遇到EOF时才开始输出)

    This script guarantees an output for every newline read. (cat might not start outputting until its buffer is full or it encounters an EOF)

    重要说明:请阅读下面 @andrew 的评论.您需要注意几种情况.

    IMPORTANT NOTE: Please read the comments from @andrew below. There are several situations which you need to be aware of.

    好的!终于可以访问我的Linux机器了.方法如下:

    Alright! Finally got access to my Linux box. Here's how:

    第1步:制作此记录器脚本:

    #!/bin/bash
    
    LOGFILE="/path/to/log/file"
    SEMAPHORE="/path/to/log/file.semaphore"
    
    while : ; do
      read line
      while [[ -f $SEMAPHORE ]]; do
        sleep 1s
      done
      printf "%s\n" "$line" >> $LOGFILE
    done
    

    第2步:将录音机投入使用:

    1. 创建命名管道:

    1. Make a named pipe:

    mkfifo $PIPENAME
    

  • 重定向应用程序的STDOUT&STDERR到命名管道:

  • Redirect your application's STDOUT & STDERR to the named pipe:

    ...things... &> $PIPENAME
    

  • 启动记录器:

  • Start the recorder:

    /path/to/recorder.sh < $PIPENAME &
    

    您可能希望对上面的代码进行 nohup 使其在注销后仍然有效.

    You might want to nohup the above to make it survive logouts.

    完成!

    第3步::如果需要logrotate,请暂停记录器:

    Step 3: If you need to logrotate, pause the recorder:

    touch /path/to/log/file.semaphore
    mv /path/to/log/file /path/to/archive/of/log/file
    rm /path/to/log/file.semaphore
    

    我建议将上述步骤放入自己的脚本中.随意将第二行更改为要使用的任何日志旋转方法.

    I suggest putting the above steps into its own script. Feel free to change the 2nd line to whatever log-rotating method you want to use.

    注意: :如果您方便使用C编程,则可能想编写一个简短的C程序来执行 recorder.sh 的功能.代码>.编译后的C程序肯定比nohup-ed分离的bash脚本要轻.

    Note : If you're handy with C programming, you might want to make a short C program to perform the function of recorder.sh. Compiled C programs will certainly be lighter than a nohup-ed detached bash script.

    注释2: David Newcomb在注释中提供了一个有用的警告:当记录器未运行时,对管道的写入将阻塞并可能会导致程序意外失败.确保录音机在尽可能短的时间内关闭(或旋转).

    Note 2: David Newcomb provided a helpful warning in the comments: While the recorder is not running then writes to the pipe will block and may cause the program to fail unpredictably. Make sure the recorder is down (or rotating) for as short time as possible.

    因此,如果您可以确保快速轮换确实发生,则可以将 sleep (仅接受整数值的内置命令)替换为/bin/sleep (接受浮点值的程序),并将睡眠时间设置为 0.5 或更短.

    So, if you can ensure that rotating happens really quickly, you can replace sleep (a built-in command which accepts only integer values) with /bin/sleep (a program that accepts float values) and set the sleep period to 0.5 or shorter.

    这篇关于使用Bash脚本旋转日志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆