nohup gunicorn 日志不能实时打印print问题解决

问题描述

由于不用配置过多配置信息,想通过nohup打印django项目的console控制台的日志,最后调试的时候发现nohup.out始终不能实时看到console的print信息,但又有部分日志能看到,比如错误日志

原因查找

原来python解释器中,print是stdout输出, stdout输出流默认是行缓存的 ( line-buffered ),重定向和输出到控制台的内容会先被存在缓冲区中暂存,遇到换行符“\n”,或者缓存区的数据满 4k,才会将内容写到重定向的文件或者控制台中去。stderr不会先输出到缓冲区,所以才看到nohup 没有及时日志的原因而错误日志能实时输出。(但3.9版本后也变成了行缓存,可以见https://github.com/python/cpython/commit/d17f3d8315a3a775ab0807fc80acf92b1bd682f8)

可以通过按ctrl+c的方式试验,不过不要用kill,kill的时候日志信息就丢了

解决

方法一:直接加个环境变量,永久生效需要加到环境变量配置里

export PYTHONUNBUFFERED=1
nohup  xxx

方法二:加个-u参数

nohup python -u xxxx

方法三:加代码,在print后加上


print ("print")
import sys
sys.stdout.flush()

方法四:print后加上flush参数,默认为参数


print ("print",flush=true)

由于本人使用的是nohup gunicorn,则使用第一种方式最为合适。配置好后,既可以看到实时日志

深入思考

官网的资料说明来看,交互模式下,stdout是行输出,也就是为什么python3中,我们输入print后能直接打印显示,而python2却不行。因为print在python3中是函数,默认带换行符。换行符也就会将缓冲区的数据打印出来,这样也就说的通了。
脚本验证如下:python3是一行行输出,而python2是跑完,全部输出

import time
import sys  
for i in range(5):
   print(i)
   #sys.stdout.flush()
   time.sleep(20)

但官网只说明python3中只有交互模式下是行缓冲,而其他模式是块缓冲(就是一次性输出)

When interactive, the stdout stream is line-buffered. Otherwise, it is block-buffered like regular text files. The stderr stream is line-buffered in both cases. You can make both streams unbuffered by passing the -u command-line option or setting the PYTHONUNBUFFERED environment variable

但问题是python3中怎样算交互模式?望有大佬解释

python3 ss.py 一行行输出
python3 ss.py >> 22.txt 一次性输出。重定向输出
nohup python3 ss.py 一次性输出。重定向输出

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值