如何在Tornado中管理nohup.out文件?

时间:2013-05-16 09:38:06

标签: python web-services shell tornado nohup

我使用龙卷风建立了一个网络服务,它可以日夜服务。我使用命令启动我的服务:

nohup python my_service.py &

服务日志可以写入nohup.out。但是,随着时间的推移,文件会变大。我想知道如何更方便地管理它?要说,使用自动方法生成具有适当名称和大小的日志文件?如:

service_log_1.txt
service_log_2.txt
service_log_3.txt
...

感谢。

4 个答案:

答案 0 :(得分:3)

是的,有。将一个cron-job生效,它会截断文件(类似"cat /dev/null > nohup.out")。您需要多久运行一次这项工作取决于您的流程产生多少输出。

但是,如果您不需要完成作业的输出(可能是它的垃圾,只有你可以回答),你可以防止首先写入文件nohup.out。现在你以这样的方式开始这个过程:

nohup command &

将此替换为

nohup command 2>/dev/null 1>/dev/null &

并且甚至不会创建nohup.out文件。

将进程的输出定向到文件的原因是:

通常所有进程(即:从命令行输入的命令,有例外,但在此处无关紧要)都附加到终端。默认情况下(这是Unix处理这个问题的方式)这可以显示文本并通过串行线连接到主机。如果你输入一个命令并关闭你从进程中输入它的终端也会终止 - 因为它丢失了它的终端。因为在串行通信中,技术人员传统上使用来自电话通信的单词(来自它),通信的终止不被称为“中断”或“终止”而是“挂断”。所以程序在“挂断”时被终止并且编程以防止这是“nohup”,即“no-termination-on-hangup”程序。

但是很可能这样一个孤立的进程没有终端写入它nohup使用文件nohup.out作为“屏幕替换”,将输出重定向到那里,通常会进入屏幕。如果命令没有任何输出,虽然nohp.out将不会被创建。

答案 1 :(得分:1)

简单:

nohup python my_service.py >service_log_1.txt 2>&1 &

答案 2 :(得分:1)

如果输出是由您正在使用的某个库生成的,并且您无法控制它,则可以在程序启动时将标准输出重定向到文件。然后,您可以定期关闭并重新打开该文件,以防止文件永远增长。您可以使用时间戳作为文件名,因此它总是不同的。类似的东西:

import sys
import datetime
current_stdout = None
def reset_stdout():
    global current_stdout
    if current_stdout:
        current_stdout.close()
    sys.stdout = open(
        "{}.log".format(
            datetime.datetime.now().strftime('%Y%m%d%H%M%S')
            ),
        "w")
    current_stdout = sys.stdout
reset_stdout()

# Then call this every day.. week ..
reset_stdout()

如果您希望根据文件大小重置文件,可以使用以下内容定期监控文件大小:

if current_stdout.tell() > 1000000:
    reset_stdout()

但如果您确实可以控制要发送的输出,我强烈建议您使用logging库。它对输出的功能有很大的灵活性。发送到日志的消息可以由名为handlers的对象处理。库中包含的其中一个处理程序可以执行您想要的操作,称为RotatingFileHandler。来自文档:

class logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0)
  

“您可以使用maxBytes和backupCount值来允许文件   以预定尺寸翻转。当大小即将来临时   超出,文件关闭,并以静默方式打开一个新文件   输出。只要当前日志文件差不多就会发生翻转   maxBytes的长度;如果maxBytes为零,则不会发生翻转。“

因此,您可以使用以下内容执行所有日志记录:

import logging
import logging.handlers
# Create a logger
log = logging.getLogger('example')
# Set the level of the logger. By doing this all the messages with a "level" of INFO or higher will be 
# sent to the log
log.setLevel(logging.INFO)
# Create the handler and set 20 files to rotate and a maximum size of 1MB
handler = logging.handlers.RotatingFileHandler('log',maxBytes = 1000000,backupCount=20)
# Now attach the handler to the logger object
log.addHandler(handler)

# Now you can send your output like:
log.info('text text text text text text text text text')
log.info(....

答案 3 :(得分:0)

@jujaro的回答非常有用,我在我的网络服务中尝试了logging模块。但是,在Tornado中使用日志记录仍有一些限制。查看其他question问。

结果,我在linux中尝试crontab在午夜创建一个cron作业(在linux shell中使用crontab -e):

59 23 * * * source /home/zfz/cleanlog.sh

这个cron作业每天23:59启动我的脚本cleanlog.sh

clean.sh的内容:

fn=$(date +%F_service_log.out)
cat /home/zfz/nohup.out >> "/home/zfz/log/$fn"
echo '' > /home/zfz/nohup.out

此脚本创建一个包含当天日期的日志文件,echo ''清除nohup.out以防万一它变大。以下是我现在从nohup.out拆分的日志文件:

-rw-r--r-- 1 zfz zfz  54474342 May 22 23:59 2013-05-22_service_log.out
-rw-r--r-- 1 zfz zfz  23481121 May 23 23:59 2013-05-23_service_log.out