我使用龙卷风建立了一个网络服务,它可以日夜服务。我使用命令启动我的服务:
nohup python my_service.py &
服务日志可以写入nohup.out
。但是,随着时间的推移,文件会变大。我想知道如何更方便地管理它?要说,使用自动方法生成具有适当名称和大小的日志文件?如:
service_log_1.txt
service_log_2.txt
service_log_3.txt
...
感谢。
答案 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