Python / Django: เข้าสู่คอนโซลภายใต้รันเนอร์เข้าสู่ไฟล์ภายใต้ Apache


114

ฉันจะส่งข้อความติดตามไปยังคอนโซลได้อย่างไร (เช่นprint) เมื่อฉันเรียกใช้แอพ Django ของฉันภายใต้manage.py runserverแต่มีข้อความเหล่านั้นส่งไปยังไฟล์บันทึกเมื่อฉันเรียกใช้แอพภายใต้ Apache

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


1
วิธีแก้ไขที่ง่ายที่สุดคือการมีไฟล์ settings.py ที่แตกต่างกันสำหรับเซิร์ฟเวอร์หลักและสภาพแวดล้อมการพัฒนาโปรดดูที่deploydjango.com/django_project_structure
Alex

คำตอบ:


84

ข้อความที่พิมพ์ไปยัง stderr จะปรากฏในบันทึกข้อผิดพลาดของ httpd เมื่อทำงานภายใต้ mod_wsgi คุณสามารถใช้printโดยตรงหรือใช้loggingแทนก็ได้

print >>sys.stderr, 'Goodbye, cruel world!'

2
แม้ว่าในทางเทคนิคแล้ว WSGI จะไม่ถูกต้องและจะทำให้เกิดข้อผิดพลาดในสภาพแวดล้อมที่เข้มงวดมากขึ้น
Paul McMillan

13
ไม่มีอะไรผิดปกติกับการใช้ 'พิมพ์' กับ 'sys.stderr' เท่าที่ WSGI ไปและไม่ควรทำให้เกิดข้อผิดพลาด
Graham Dumpleton

ฉันนำเข้า sys แต่ดูเหมือนจะไม่ได้ผลสำหรับฉัน
Hack-R

17
นี้ไม่ได้ทำงานในหลาม 3 ได้ดูที่นี่ คุณต้องการprint("Goodbye cruel world!", file=sys.stderr)
กระวาน

103

นี่คือโซลูชันที่ใช้การบันทึก Django ใช้การตั้งค่าดีบักแทนที่จะตรวจสอบว่าคุณกำลังใช้งานเซิร์ฟเวอร์การพัฒนาหรือไม่ แต่ถ้าคุณพบวิธีที่ดีกว่าในการตรวจสอบว่าควรปรับเปลี่ยนได้ง่าย

LOGGING = {
    'version': 1,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': '/path/to/your/file.log',
            'formatter': 'simple'
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}

if DEBUG:
    # make all loggers use the console.
    for logger in LOGGING['loggers']:
        LOGGING['loggers'][logger]['handlers'] = ['console']

ดูรายละเอียดhttps://docs.djangoproject.com/en/dev/topics/logging/


8
ยังลองLOGGING['loggers'][logger]['handlers'] += ['console']
Nir Levy

@ m01: หลังจากกำหนดค่านี้ใน settings.py แล้วจะใช้สิ่งนี้เพื่อการพิมพ์ได้อย่างไร? ขอบคุณ
Niks Jain

ฉันใส่รหัสจากคำตอบของฉันลงsettings.pyไปที่ด้านล่างและตั้งค่าDEBUG = True(มองหาการตั้งค่านั้นใกล้ด้านบนในไฟล์เดียวกัน) จากนั้นฉันเรียกใช้python manage.py runserverจากเทอร์มินัล (ดูรายละเอียดใน django docs) และข้อความบันทึกจะปรากฏในหน้าต่างเทอร์มินัล ในการผลิตผมใช้ settings.py แตกต่างกันที่DEBUG = False- /path/to/your/file.logข้อความเข้าสู่ระบบไป
m01

การเยื้องของคุณทำให้ฉันปวดหัว ขอบคุณสำหรับข้อมูลที่ใช้งานได้!
ioan

ขอบคุณ! ฉันได้เปลี่ยนแปลงการเยื้องไปบ้างแล้วฉันหวังว่าตอนนี้จะดีขึ้น
m01

27

คุณสามารถกำหนดค่าการบันทึกในsettings.pyไฟล์ของคุณ

ตัวอย่างหนึ่ง:

if DEBUG:
    # will output to your console
    logging.basicConfig(
        level = logging.DEBUG,
        format = '%(asctime)s %(levelname)s %(message)s',
    )
else:
    # will output to logging file
    logging.basicConfig(
        level = logging.DEBUG,
        format = '%(asctime)s %(levelname)s %(message)s',
        filename = '/my_log_file.log',
        filemode = 'a'
    )

อย่างไรก็ตามขึ้นอยู่กับการตั้งค่า DEBUG และบางทีคุณอาจไม่ต้องกังวลเกี่ยวกับวิธีการตั้งค่า ดูคำตอบนี้ในฉันจะทราบได้อย่างไรว่าแอปพลิเคชัน Django ของฉันกำลังทำงานบนเซิร์ฟเวอร์การพัฒนาหรือไม่? เพื่อวิธีที่ดีกว่าในการเขียนเงื่อนไขนั้น แก้ไข: ตัวอย่างข้างต้นมาจากโครงการ Django 1.1 การกำหนดค่าการบันทึกใน Django มีการเปลี่ยนแปลงไปบ้างตั้งแต่เวอร์ชันนั้น


ฉันไม่ต้องการพึ่งการแก้ปัญหา ฉันควรจะขึ้นอยู่กับกลไกการตรวจจับเซิร์ฟเวอร์ที่เชื่อมโยงในโพสต์อื่นนั้น แต่กลไกการตรวจจับของโพสต์อื่นขึ้นอยู่กับการเข้าถึงอินสแตนซ์คำขอ ฉันจะรับอินสแตนซ์คำขอใน settings.py ได้อย่างไร
Justin Grant

4

ฉันใช้สิ่งนี้:

logging.conf:

[loggers]
keys=root,applog
[handlers]
keys=rotateFileHandler,rotateConsoleHandler

[formatters]
keys=applog_format,console_format

[formatter_applog_format]
format=%(asctime)s-[%(levelname)-8s]:%(message)s

[formatter_console_format]
format=%(asctime)s-%(filename)s%(lineno)d[%(levelname)s]:%(message)s

[logger_root]
level=DEBUG
handlers=rotateFileHandler,rotateConsoleHandler

[logger_applog]
level=DEBUG
handlers=rotateFileHandler
qualname=simple_example

[handler_rotateFileHandler]
class=handlers.RotatingFileHandler
level=DEBUG
formatter=applog_format
args=('applog.log', 'a', 10000, 9)

[handler_rotateConsoleHandler]
class=StreamHandler
level=DEBUG
formatter=console_format
args=(sys.stdout,)

testapp.py:

import logging
import logging.config

def main():
    logging.config.fileConfig('logging.conf')
    logger = logging.getLogger('applog')

    logger.debug('debug message')
    logger.info('info message')
    logger.warn('warn message')
    logger.error('error message')
    logger.critical('critical message')
    #logging.shutdown()

if __name__ == '__main__':
    main()

0

คุณสามารถทำได้อย่างง่ายดายด้วยtagalog(https://github.com/dorkitude/tagalog)

ยกตัวอย่างเช่นในขณะที่โมดูลหลามมาตรฐานเขียนไปยังวัตถุไฟล์ที่เปิดในโหมดผนวกที่ App Engine โมดูล (https://github.com/dorkitude/tagalog/blob/master/tagalog_appengine.py) logging.INFOแทนที่พฤติกรรมนี้และแทนที่จะใช้

หากต้องการรับพฤติกรรมนี้ในโปรเจ็กต์ App Engine คุณสามารถทำได้:

import tagalog.tagalog_appengine as tagalog
tagalog.log('whatever message', ['whatever','tags'])

คุณสามารถขยายโมดูลด้วยตัวเองและเขียนทับฟังก์ชันบันทึกได้โดยไม่ยาก


0

สิ่งนี้ใช้งานได้ดีใน local.py ของฉันช่วยให้ฉันไม่ยุ่งกับการบันทึกปกติ:

from .settings import *

LOGGING['handlers']['console'] = {
    'level': 'DEBUG',
    'class': 'logging.StreamHandler',
    'formatter': 'verbose'
}
LOGGING['loggers']['foo.bar'] = {
    'handlers': ['console'],
    'propagate': False,
    'level': 'DEBUG',
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.