ปิดใช้งานข้อความคอนโซลในเซิร์ฟเวอร์ Flask


91

ฉันมีเซิร์ฟเวอร์ Flask ที่ทำงานในโหมดสแตนด์อโลน (โดยใช้app.run()) แต่ฉันไม่ต้องการข้อความใด ๆ ในคอนโซลเช่น

127.0.0.1 - - [15/Feb/2013 10:52:22] "GET /index.html HTTP/1.1" 200 -
...

ฉันจะปิดโหมด verbose ได้อย่างไร?


ตอนนี้คุณมีแอปที่เริ่มต้นเธรด (ซึ่งยากพอที่จะแก้ไขข้อบกพร่องได้เอง) และตอนนี้คุณจะระงับการบันทึกที่ด้านบนหรือไม่? Eesh ดูเหมือนจะตรงกันข้ามกับสิ่งที่ฉันทำ .. ยิ่งการบันทึกของคุณละเอียดมากเท่าไหร่ก็ยิ่งดีขึ้นเท่านั้น (เห็นได้ชัดตราบเท่าที่มันเกี่ยวข้อง;))
Demian Brecht

7
@DemianBrecht สิ่งนี้คือบันทึกจะถูกส่งไปstderrแต่พวกเขากำลังบันทึกธุรกรรม HTTP แต่ละรายการซึ่งไม่เกี่ยวข้องกับฉัน ...
ATOzTOA

คำตอบ:


133

คุณสามารถตั้งค่าระดับของตัวบันทึก Werkzeug เป็น ERROR ได้ในกรณีนี้จะบันทึกเฉพาะข้อผิดพลาดเท่านั้น:

import logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)

นี่คือตัวอย่างการทำงานอย่างสมบูรณ์ที่ทดสอบบน OSX, Python 2.7.5, Flask 0.10.0:

from flask import Flask
app = Flask(__name__)

import logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

9
ดูเหมือนจะไม่หยุดบันทึก HTTP ไปที่ stderr มันหยุดข้อความ "เริ่มต้น" (ซึ่งมีชื่อโมดูล "werkzeug" อย่างชัดเจนในรูปแบบบันทึก "
rsb

2
ใช้ได้ผลสำหรับฉัน ข้อความการดีบักคำขอถูกบีบอัด ใช้ Python 3.5.2, Flask 0.12 และ Werkzeug 0.11.11
JackLeEmmerdeur

3
ใช้งานได้กับ Python 3.6, Flask 0.12 และ Werkzeug 0.11.15
vallentin

8
น่าเสียดายที่ไม่สามารถใช้งานได้อย่างสมบูรณ์อีกต่อไปเนื่องจากใช้ขวดclick.secho
ปีเตอร์

1
การเปลี่ยนระดับการบันทึกไม่ควรเป็นวิธีแก้ปัญหาเพื่อหลีกเลี่ยงการบันทึกคำขอเฉพาะรายการเดียวเท่านั้น
gented

13

โซลูชันนี้ช่วยให้คุณได้รับงานพิมพ์และสแต็กเทรซของคุณเอง แต่ไม่มีบันทึกระดับข้อมูลจากการดูดขวด 127.0.0.1 - - [15/Feb/2013 10:52:22] "GET /index.html HTTP/1.1" 200

from flask import Flask
import logging

app = Flask(__name__)
log = logging.getLogger('werkzeug')
log.disabled = True

สิ่งนี้ใช้ได้ผลเมื่อเรียกใช้เซิร์ฟเวอร์ของฉันในเครื่อง แต่แปลกที่ Heroku มันไม่ได้
Garrett

10

โซลูชัน @Drewes ใช้งานได้เกือบตลอดเวลา แต่ในบางกรณีฉันมักจะได้รับบันทึก werkzeug หากคุณไม่ต้องการเห็นสิ่งเหล่านี้จริงๆฉันขอแนะนำให้คุณปิดการใช้งานแบบนั้น

from flask import Flask
import logging

app = Flask(__name__)
log = logging.getLogger('werkzeug')
log.disabled = True
app.logger.disabled = True

สำหรับฉันมันล้มเหลวเมื่อabort(500)ถูกเลี้ยงดู


9

ในกรณีที่คุณใช้เซิร์ฟเวอร์ WSGI โปรดตั้งค่าบันทึกเป็นไม่มี

gevent_server = gevent.pywsgi.WSGIServer(("0.0.0.0", 8080), app,log = None)

นี่เป็นวิธีเดียวที่ใช้ได้ผลสำหรับฉันและฉันใช้ Flask กับ WSGIServer
Woody

8

ไม่มีคำตอบอื่น ๆ ทำงานอย่างถูกต้องสำหรับผม แต่ผมพบว่าวิธีการแก้ปัญหาตามออกความคิดเห็นของปีเตอร์ เห็นได้ชัดว่า Flask ไม่ใช้loggingสำหรับการบันทึกอีกต่อไปและได้เปลี่ยนไปใช้แพ็คเกจคลิก โดยเอาชนะclick.echoและฉันกำจัดข้อความเริ่มต้นจากขวดclick.sechoapp.run()

import logging

import click
from flask import Flask

app = Flask(__name__)

log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)

def secho(text, file=None, nl=None, err=None, color=None, **styles):
    pass

def echo(text, file=None, nl=None, err=None, color=None, **styles):
    pass

click.echo = echo
click.secho = secho

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

ระหว่างการตั้งค่าระดับการบันทึกเป็นERRORและการแทนที่วิธีการคลิกด้วยฟังก์ชันว่างควรป้องกันเอาต์พุตบันทึกที่ไม่ใช่ข้อผิดพลาดทั้งหมด


7

อีกเหตุผลหนึ่งที่คุณอาจต้องการเปลี่ยนเอาต์พุตการบันทึกคือสำหรับการทดสอบและเปลี่ยนเส้นทางบันทึกของเซิร์ฟเวอร์ไปยังไฟล์บันทึก

ฉันไม่สามารถรับคำแนะนำข้างต้นเพื่อใช้งานได้ดูเหมือนว่ามีการตั้งค่าคนตัดไม้เป็นส่วนหนึ่งของแอปเริ่มต้น ฉันสามารถทำให้มันใช้งานได้โดยเปลี่ยนระดับการบันทึกหลังจากเริ่มแอพ:

... (in setUpClass)
server = Thread(target=lambda: app.run(host=hostname, port=port, threaded=True))
server.daemon = True
server.start()
wait_for_boot(hostname, port)  # curls a health check endpoint

log_names = ['werkzeug']
app_logs = map(lambda logname: logging.getLogger(logname), log_names)
file_handler = logging.FileHandler('log/app.test.log', 'w')

for app_log in app_logs:
    for hdlr in app_log.handlers[:]:  # remove all old handlers
        app_log.removeHandler(hdlr)

    app_log.addHandler(file_handler)

น่าเสียดายที่* Running on localhost:9151การตรวจสุขภาพครั้งแรกและการตรวจสุขภาพครั้งแรกยังคงถูกพิมพ์ออกมาเป็นมาตรฐาน แต่เมื่อทำการทดสอบจำนวนมากจะทำความสะอาดผลลัพธ์เป็นตัน

"แล้วทำไมlog_names" คุณถาม ในกรณีของฉันมีบันทึกพิเศษบางอย่างที่ฉันต้องกำจัด ฉันสามารถค้นหาคนตัดไม้ที่จะเพิ่มใน log_names ผ่านทาง:

from flask import Flask
app = Flask(__name__)

import logging
print(logging.Logger.manager.loggerDict)

หมายเหตุด้านข้าง: คงจะดีถ้ามี flaskapp.getLogger () หรืออะไรสักอย่างเพื่อให้มีประสิทธิภาพมากขึ้นในทุกเวอร์ชัน ความคิดใด ๆ ?

คำสำคัญเพิ่มเติม: บันทึกการทดสอบขวดจะลบเอาต์พุต stdout

ขอบคุณ:


6

ในการปราบปรามServing Flask app ...:

os.environ['WERKZEUG_RUN_MAIN'] = 'true'
app.run()

1
สิ่งนี้ใช้ได้ผลสำหรับฉันฉันใช้เมื่อทดสอบแอปพลิเคชันขวด (โดยใช้จมูก 2) สิ่งนี้จะขจัดความยุ่งเหยิงในเครื่องปลายทาง ขอบคุณ
CpK

6

คำตอบที่ล่าช้า แต่ฉันพบวิธีระงับแต่ละข้อความและทุกคอนโซล (รวมถึงข้อความที่แสดงระหว่างabort(...)ข้อผิดพลาด)

import os
import logging

logging.getLogger('werkzeug').disabled = True
os.environ['WERKZEUG_RUN_MAIN'] = 'true'

นี่คือการรวมกันของคำตอบที่Slava VและTom Wojcik ให้ไว้


-1

กำลังดุร้ายวิธีที่จะทำจริงๆถ้าคุณไม่ต้องการอะไรในการเข้าสู่คอนโซลข้างพิมพ์ () logging.basicConfig(level=logging.FATAL)งบคือการ การดำเนินการนี้จะปิดใช้งานบันทึกทั้งหมดที่มีสถานะเป็นอันตรายถึงชีวิต มันจะไม่ปิดการใช้งานการพิมพ์ แต่ใช่เป็นเพียงความคิด: /

แก้ไข: ฉันรู้ว่าฉันคงเห็นแก่ตัวที่จะไม่ใส่ลิงค์ไปยังเอกสารที่ฉันใช้ :) https://docs.python.org/3/howto/logging.html#logging-basic-tutorial


-3

จุดแรก: ตามเอกสารของ Flask อย่างเป็นทางการคุณไม่ควรเรียกใช้แอปพลิเคชัน Flask โดยใช้ app.run () ทางออกที่ดีที่สุดคือการใช้ uwsgi ดังนั้นคุณสามารถปิดใช้งานบันทึกของขวดเริ่มต้นโดยใช้คำสั่ง "--disable-logging"

ตัวอย่างเช่น:

uwsgi --socket 0.0.0.0:8001 --disable-logging --protocol=http -w app:app

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.