我正在尝试将来自一个非常简单的 flask 应用程序的应用程序日志消息保存在日志文件中。虽然当我使用嵌入式 Flask 服务器运行应用程序时这可以完美运行,但在 gUnicorn 中运行时它根本不工作,基本上,无论是日志文件(我的 Flask 应用程序中指定的文件)还是重定向,都不会重定向应用程序输出运行 gunicorn 时的 STDOUT。
也就是说,这是我的 Flask 应用:
@app.route('/')
def index():
app.logger.debug('Into /!!!!')
print 'Will this print?'
return 'Flask is running!'
if __name__ == '__main__':
#Setup the logger
file_handler = FileHandler('test.log')
handler = logging.StreamHandler()
file_handler.setLevel(logging.DEBUG)
handler.setLevel(logging.DEBUG)
file_handler.setFormatter(Formatter(
'%(asctime)s %(levelname)s: %(message)s '
'[in %(pathname)s:%(lineno)d]'))
handler.setFormatter(Formatter(
'%(asctime)s %(levelname)s: %(message)s '
'[in %(pathname)s:%(lineno)d]'))
app.logger.addHandler(handler)
app.logger.addHandler(file_handler)
app.run(debug=True)
现在,如果我以以下方式启动应用程序:
python app.py
我得到了预期的输出:
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
--------------------------------------------------------------------------------
DEBUG in app [app.py:23]:
Into /!!!!
--------------------------------------------------------------------------------
2015-03-11 09:36:18,375 DEBUG: Into /!!!! [in app.py:23]
Will this print?
127.0.0.1 - - [11/Mar/2015 09:36:18] "GET / HTTP/1.1" 200 -
拖尾test.log,我明白了:
2015-03-11 09:36:18,375 DEBUG: Into /!!!! [in app.py:23]
到目前为止一切看起来都很棒,然后当我尝试使用 nginx + gunicorn 运行应用程序时,首先我尝试像这样运行 gunicorn:
gunicorn app:app -b localhost:8000 --debug --log-level debug
如果我转到 http://localhost,应用程序正在运行:
curl http://localhost
Flask is running!
但是查看日志文件,是空的,没有写入任何内容。我添加了 777 权限只是为了检查它是否是权限问题无济于事。然后查看 gunicorn 标准输出,除了 print 语句之外什么都没有写:
2015-03-11 09:42:06 [25641] [DEBUG] GET /
Will this print?
Looking around ,我尝试将所有输出重定向到 gunicorn 日志,然后像这样启动 gunicorn:
gunicorn app:app -b localhost:8000 --debug --log-file /tmp/test.log --log-level debug --error-logfile /tmp/error.log
但现在我什至没有在 gunicorn 文件中获得打印语句,这是 test.log 和 error.log 的输出(它们是相同的):
2015-03-11 09:46:17 [26257] [DEBUG] tmp_upload_dir: None
2015-03-11 09:46:17 [26257] [DEBUG] keyfile: None
2015-03-11 09:46:17 [26257] [DEBUG] backlog: 2048
2015-03-11 09:46:17 [26257] [DEBUG] logger_class: simple
2015-03-11 09:46:17 [26257] [INFO] Starting gunicorn 17.5
2015-03-11 09:46:17 [26257] [DEBUG] Arbiter booted
2015-03-11 09:46:17 [26257] [INFO] Listening at: http://127.0.0.1:8000 (26257)
2015-03-11 09:46:17 [26257] [INFO] Using worker: sync
2015-03-11 09:46:17 [26262] [INFO] Booting worker with pid: 26262
2015-03-11 09:48:15 [26262] [DEBUG] GET /
有一个非常相似的问题here ,其中一个答案似乎表明在 gunicorn 中运行时没有可用的应用程序记录器???这听起来,至少,很奇怪......那我应该如何登录?
另一个 proposed solution似乎建议不要使用 Flask 记录器,但与 gunicorn 无关(我认为)......
我错过了什么?我应该放弃 gunicorn 并选择 Apache-mod wsgi 吗? Nginx-uWSGI?快速CGI?有什么想法吗?
谢谢! 亚历杭德罗
编辑:
我已经尝试使用 uWGSI 而不是 gunicorn 和相同的行为进行相同的设置,但没有获得任何应用程序日志记录。
现在基于 this response这个other one ,我想出了这个(在 gUnicorn 和 uWSGI 上,两者都有效)
from flask import Flask
import logging
from logging import Formatter, FileHandler
app = Flask(__name__)
LOGGER = logging.getLogger('whatever')
file_handler = FileHandler('test.log')
handler = logging.StreamHandler()
file_handler.setFormatter(Formatter(
'%(asctime)s %(levelname)s: %(message)s '
'[in %(pathname)s:%(lineno)d]'
))
handler.setFormatter(Formatter(
'%(asctime)s %(levelname)s: %(message)s '
'[in %(pathname)s:%(lineno)d]'
))
LOGGER.addHandler(file_handler)
LOGGER.addHandler(handler)
LOGGER.setLevel(logging.INFO)
@app.route('/')
def hello():
LOGGER.info('info log')
LOGGER.debug('debug log')
return 'Hello!'
if __name__ == '__main__':
app.run()
gunicorn 的输出:
2015-03-11 12:25:01 [11540] [INFO] Starting gunicorn 17.5
2015-03-11 12:25:01 [11540] [INFO] Listening at: http://127.0.0.1:8000 (11540)
2015-03-11 12:25:01 [11540] [INFO] Using worker: sync
2015-03-11 12:25:01 [11545] [INFO] Booting worker with pid: 11545
2015-03-11 12:26:20,765 INFO: info log [in /home/mosquito/www/flask-project/flask-project/app.py:24]
然后查看我的 test.log 文件:
2015-03-11 12:26:20,765 INFO: info log [in /home/mosquito/www/flask-project/flask-project/app.py:24]
所以是的,它有点工作,但原来的问题仍然存在......为什么 Flask 记录器在 wsgi 容器中运行时似乎不起作用 - gunicorn,uWSGI?
最佳答案
您自己在这里回答了您的问题。虽然我会添加我的答案,希望它可以帮助其他有类似问题的人。
由于您的问题有 2 个部分,其中第一部分已解决,因此请标记我对每个部分的回答:
第 1 部分:如果不是直接通过 python 运行应用程序,而是在 gunicorn 下运行它,则不会发生日志记录 这是因为,当直接运行时,name == 'main' 为 True,并且您的代码同时初始化了 FileHandler 和 StreamHandler,并且日志记录工作正常。 但是当通过 gunicorn 运行时,name == 'main' 会失败,因为 name 将包含您的模块的名称。这意味着不会初始化任何有效处理程序。因此看不到任何日志记录。
第 2 部分:为什么 Flask 记录器在 gunicorn/uWSGI 下默认不工作 最新的 flask 版本从头开始初始化 app.logger,并在默认情况下附加一些处理程序,如 DebugHandler、StreamHandler,具体取决于 app.debug==True。记录器仍然不够,只会记录到 STDERR。 在过去的几个版本中,gunicorn 发生了多次变化。 版本 19.4.1 不会将 STDOUT 和 STDERR 捕获到 gunicorn error.log。 但它确实提供了名称为“gunicorn”、“gunicorn.access”和“gunicorn.error”的记录器。最后一个有一个 FileHandler 写入配置的 error.log。 如果您希望 flask 应用程序中的日志转到 error.log,请使用以下方法之一: 方法1:
#only use gunicorn.error logger for all logging
LOGGER = logging.getLogger('gunicorn.error')
LOGGER.info('my info')
LOGGER.debug('debug message')
# this would write the log messages to error.log
方法2:
# Only use the FileHandler from gunicorn.error logger
gunicorn_error_handlers = logging.getLogger('gunicorn.error').handlers
app.logger.handlers.extend(gunicorn_error_handlers )
app.logger.addHandler(myhandler1)
app.logger.addHandler(myhandler2)
app.logger.info('my info')
app.logger.debug('debug message')
将推荐方法 2,因为除了 gunicorn.error 之外,您还可以保留任何您想要的处理程序。此外,您可以根据条件选择不添加 gunicorn.error 处理程序。
谢谢
关于python - 在 gunicorn 中运行时,Flask 应用程序记录器无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28982106/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request