2015-07-21 45 views
1

我有一段Python代碼,如果發生IOError異常,應該向我的Django日誌文件寫入錯誤消息和關聯的堆棧跟蹤。但我發現,錯誤和堆棧跟蹤寫入我的控制檯,但不是我的日誌文件。我檢查了我的Django日誌配置並沒有看到問題。我有LOG_LEVEL設置爲DEBUG,我有一個「日誌文件」處理程序。有沒有人看到我在做什麼錯了?爲什麼Python Python logging.exception不工作?

謝謝!

# photo.py 
import os 
import logging 
logger = logging.getLogger(__name__) 
import shutil 

pvt_photo_path = "/www/proj/pvt/photo1.jpg" 
pub_photo_path = "/www/proj/pub/photo1.jpg" 
try: 
    shutil.move(pvt_photo_path, pub_photo_path) 
except IOError as e: 
    logging.exception("Couldn't move photo %s" % pvt_photo_path) 


# settings.py 
LOG_LEVEL = 'DEBUG' 
LOGGING = { 
    'version': 1, 
    'disable_existing_loggers': True, 
    'formatters': { 
     'standard': { 
      'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s", 
      'datefmt' : "%d/%b/%Y %H:%M:%S" 
     }, 
    }, 
    'handlers': { 
     'null': { 
      'level':'DEBUG', 
      'class':'django.utils.log.NullHandler', 
     }, 
     'logfile': { 
      'level':LOG_LEVEL, 
      'class':'logging.handlers.RotatingFileHandler', 
      'filename': '/var/log/proj/proj.log', 
      'maxBytes': 50000, 
      'backupCount': 2, 
      'formatter': 'standard', 
     }, 
     'database_logfile': { 
      'level':LOG_LEVEL, 
      'class':'logging.handlers.RotatingFileHandler', 
      'filename': '/var/log/proj/database.log', 
      'maxBytes': 50000, 
      'backupCount': 2, 
      'formatter': 'standard', 
     }, 
     'console':{ 
      'level':LOG_LEVEL, 
      'class':'logging.StreamHandler', 
      'formatter': 'standard' 
     }, 
     'mail_admins': { 
      'level': 'ERROR', 
      'class': 'django.utils.log.AdminEmailHandler' 
     }, 
    }, 
    'loggers': { 
     'django': { 
      'handlers':['logfile', 'database_logfile', 'console', 'mail_admins'], 
      'propagate': True, 
      'level':'DEBUG', 
     }, 
     'django.request': { 
      'handlers': ['logfile', 'mail_admins'], 
      'level': 'ERROR', 
      'propagate': False, 
     }, 
     'django.db.backends': { 
      'handlers': ['database_logfile'], 
      'level': 'DEBUG', 
      # Logging messages are not passed to the handlers of ancestor loggers. 
      'propagate': False, 
     }, 
     '': { 
      'handlers': ['console'], 
      'level': 'DEBUG', 
     }, 
    } 
} 


root: ERROR: Couldn't move photo for user "test_user" 
Traceback (most recent call last): 
    File "/www/proj/classes/photo.py", line 1167, in make_photo_public 
    shutil.move(pvt_gall_photo_path, pub_gall_photo_path) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 301, in move 
    copy2(src, real_dst) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 130, in copy2 
    copyfile(src, dst) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 82, in copyfile 
    with open(src, 'rb') as fsrc: 
IOError: [Errno 2] No such file or directory: '/www/proj/pvt/photo1.jpg' 
--------------------- >> end captured logging << --------------------- 
+0

你可以顯示堆棧跟蹤嗎?哪個模塊是引發異常的代碼? –

+0

我已經添加了堆棧跟蹤。 – William

+0

從你顯示的內容來看,引發異常的代碼在* import time *處被調用 - 這可能會在* Django被初始化並且日誌被配置之前被調用。雖然你說它實際上是從一個方法中調用的,但錯誤消息不使用配置格式的事實告訴我,在* logging配置之前,異常正在被*命中。 –

回答

0

它看起來像您所訪問的logging模塊的exception方法。您確實需要訪問logging模塊的logger實例。所以,試試這個:

try: 
    shutil.move(pvt_photo_path, pub_photo_path) 
except IOError as e: 
    logger.exception("Couldn't move photo %s" % pvt_photo_path) 

這樣的事情在logging模塊的documentation描述。

但是,您設置問題的方式使我無法直接進行調試。您發佈的代碼不使用您提供的LOG_LEVELLOGGING變量,也不會導入Django,並且根本沒有設置日誌處理程序。

所以,我假設你沒有真正完成你在代碼中發佈的內容,只是你遺漏了你創建的部分並適當地使用了一個文件處理程序。這將幫助,如果你提供的斷碼的一個簡單的演示,所以我們可以重現你的錯誤:How do I ask a good question?

+0

這是一個很好的結果,但它沒有解決問題。 – William

+0

不幸的。你能做一個測試用例嗎?如果我運行你提供的代碼,我不希望它將日誌寫入文件。最好是,您可以在單個文件中製作能夠再現錯誤的最少量編碼的源代碼嗎? – Joel

1

您的問題是異常被提出的shutil模塊中,並且它沒有被記錄到django.xxx記錄器之一您已附加文件處理程序 - 它正在記錄到根記錄器,因爲您在photo.py中執行logging.exception(...)。 (見the docs for that function)。所以錯誤被傳遞給根記錄器的處理程序。您可以從以下事實看到這個異常消息開始

root: ERROR: 

此外,異常的顯然是被Django的機器被初始化之前就命中(例如,日誌記錄不使用你的日誌記錄配置設置的格式,而是當您撥打basicConfig()logging.XXX()而沒有配置記錄時使用的默認格式)。

我不知道photo.py中的代碼是如何被調用的,但是(除非你遺漏了東西),它看起來不像是在Django初始化並設置了日誌記錄之後從Django調用它你的配置 - 它看起來好像被調用得更早。

+0

Vinay,這是從Django調用的。我有一個Django視圖,它導入一個包含此代碼的照片類方法。該視圖調用該方法。是否還有更多需要添加到日誌記錄設置中的內容,以便根記錄器檢測到的任何錯誤都會寫入到我的日誌文件中?謝謝。 – William

相關問題