我使用 Tornado 构建了一个 Web 服务,它日夜提供服务。我使用命令启动我的服务:
nohup python my_service.py &
服务日志能够写入nohup.out
. 但是,随着时间的推移,文件会变大。我想知道如何更方便地管理它?比如说,使用自动方法生成具有正确名称和大小的日志文件?如:
service_log_1.txt
service_log_2.txt
service_log_3.txt
...
谢谢。
我使用 Tornado 构建了一个 Web 服务,它日夜提供服务。我使用命令启动我的服务:
nohup python my_service.py &
服务日志能够写入nohup.out
. 但是,随着时间的推移,文件会变大。我想知道如何更方便地管理它?比如说,使用自动方法生成具有正确名称和大小的日志文件?如:
service_log_1.txt
service_log_2.txt
service_log_3.txt
...
谢谢。
就在这里。使 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-upon-hangup”程序。
但是很可能这样一个孤立的进程没有终端可以写入 nohup 使用文件 nohup.out 作为“屏幕替换”,将输出重定向到那里,通常会转到屏幕。如果一个命令没有任何输出,尽管 nohp.out 不会被创建。
简单的:
nohup python my_service.py >service_log_1.txt 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()
但是,如果您确实可以控制要发送的输出,我强烈建议您使用日志库。它对您可以对输出进行的操作具有很大的灵活性。发送到日志的消息可以由称为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(....
@jujaro 的回答很有帮助,我logging
在我的网络服务中尝试了模块。但是,使用登录仍然有一些限制Tornado
。请参阅提出的另一个问题。
结果,我尝试crontab
在 linux 中在午夜创建一个 cron 作业(crontab -e
在 linux shell 中使用):
59 23 * * * source /home/zfz/cleanlog.sh
这个 cron 作业cleanlog.sh
每天 23:59 启动我的脚本。
的内容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