2009-03-27 10 views
13

Làm cách nào để tôi có được Django 1.0 để viết tất cả lỗi vào bảng điều khiển hoặc tệp nhật ký khi chạy máy chủ chạy trong chế độ gỡ lỗi?Đăng nhập tất cả lỗi vào bảng điều khiển hoặc tệp trên trang Django

Tôi đã cố gắng sử dụng một lớp trung gian với chức năng process_exception như mô tả trong câu trả lời chấp nhận cho câu hỏi này:

How do you log server errors on django sites

Chức năng process_exception được gọi là đối với một số trường hợp ngoại lệ (ví dụ: assert (False) trong views.py) nhưng process_exception không nhận được các lỗi khác như ImportErrors (ví dụ: import thisclassdoesnotexist trong urs.py). Tôi mới dùng Django/Python. Đây có phải là do sự khác biệt giữa các lỗi thời gian chạy và biên dịch không? Nhưng sau đó tôi sẽ mong đợi máy chủ để khiếu nại nếu nó là một lỗi thời gian biên dịch và nó không.

Tôi đã xem bản trình bày tuyệt vời của Simon Willison về gỡ lỗi Django (http://simonwillison.net/2008/May/22/debugging/) nhưng tôi không thấy tùy chọn nào có hiệu quả đối với tôi.

Trong trường hợp nó có liên quan, tôi đang viết một ứng dụng Facebook và Facebook mặt nạ HTTP 500 lỗi với thông điệp riêng của họ chứ không hiển thị trang 500 thông tin awesomely của Django. Vì vậy, tôi cần một cách cho tất cả các loại lỗi được ghi vào bảng điều khiển hoặc tệp.

Chỉnh sửa: Tôi đoán kỳ vọng của tôi là nếu Django có thể trả lại trang lỗi 500 với nhiều chi tiết khi tôi nhập không hợp lệ (ImportError) trong urls.py, nó sẽ có thể viết cùng một chi tiết bảng điều khiển hoặc tệp mà không phải thêm bất kỳ xử lý ngoại lệ bổ sung nào vào mã. Tôi chưa bao giờ thấy xử lý ngoại lệ xung quanh các câu lệnh nhập khẩu.

Cảm ơn, Jeff

Trả lời

13

Đó là một chút cực đoan, nhưng vì mục đích gỡ lỗi, bạn có thể bật cài đặt DEBUG_PROPAGATE_EXCEPTIONS. Điều này sẽ cho phép bạn thiết lập xử lý lỗi của riêng bạn. Cách dễ nhất để thiết lập xử lý lỗi nói là ghi đè sys.excepthook. Điều này sẽ chấm dứt ứng dụng của bạn, nhưng nó sẽ hoạt động. Có thể có những điều bạn có thể làm để làm điều này không giết ứng dụng của bạn, nhưng điều này sẽ phụ thuộc vào nền tảng bạn đang triển khai điều này. Ở mức nào, không bao giờ sử dụng điều này trong sản xuất!

Để sản xuất, bạn sẽ phải xử lý lỗi rộng rãi tại chỗ. Một kỹ thuật tôi đã sử dụng là một cái gì đó như thế này:

>>> def log_error(func): 
...  def _call_func(*args, **argd): 
...   try: 
...    func(*args, **argd) 
...   except: 
...    print "error" #substitute your own error handling 
...  return _call_func 
... 
>>> @log_error 
... def foo(a): 
...  raise AttributeError 
... 
>>> foo(1) 
error 

Nếu bạn sử dụng log_error làm trang trí theo quan điểm của mình, nó sẽ tự động xử lý mọi lỗi xảy ra trong đó.

Quá trình _ chức năng ngoại lệ được gọi là đối với một số trường hợp ngoại lệ (ví dụ: assert (False) trong views.py) nhưng quá trình _ ngoại lệ là không nhận được gọi cho các lỗi khác như ImportErrors (ví dụ: nhập khẩu thisclassdoesnotexist trong urs.py). Tôi mới dùng Django/Python. Đây có phải là do sự khác biệt giữa các lỗi thời gian chạy và biên dịch không?

Trong Python, tất cả các lỗi đều là lỗi thời gian chạy. Lý do tại sao điều này gây ra sự cố là do các lỗi này xảy ra ngay lập tức khi mô-đun được nhập trước khi chế độ xem của bạn được gọi. Phương pháp đầu tiên tôi đăng sẽ bắt lỗi như thế này để gỡ lỗi. Bạn có thể tìm ra thứ gì đó để sản xuất, nhưng tôi cho rằng bạn có vấn đề tồi tệ hơn nếu bạn nhận được ImportErrors trong một ứng dụng sản xuất (và bạn không thực hiện bất kỳ nhập động nào).

Một công cụ như pylint có thể giúp bạn loại bỏ các loại vấn đề này.

+0

DEBUG_PROPOGATE_EXCEPTIONS = True hoạt động chính xác như tôi cần - nó đổ ngăn xếp vào giao diện điều khiển máy chủ. Và nó thậm chí không chấm dứt ứng dụng! – jlpp

+0

Nó được viết là 'DEBUG_PROPAGATE_EXCEPTIONS'. – akaihola

2

Thứ nhất, có rất ít lỗi biên dịch-thời gian mà bạn sẽ thấy thông qua một bản ghi ngoại lệ. Nếu mã Python của bạn không có cú pháp hợp lệ, nó sẽ chết lâu trước khi các bản ghi được mở để ghi.

Trong chế độ máy chủ lưu trữ Django, một câu lệnh "in" được viết để xuất dữ liệu mà bạn có thể thấy. Tuy nhiên, đây không phải là giải pháp dài hạn tốt, do đó, đừng dựa vào nó.

Khi Django đang chạy dưới Apache, tuy nhiên, nó phụ thuộc vào trình cắm bạn đang sử dụng. mod_python không dễ giải quyết. mod_wsgi có thể bị ép buộc gửi stdout và stderr vào một tệp nhật ký.

Đặt cược tốt nhất của bạn, tuy nhiên, là mô-đun logging. Đặt một khởi tạo vào cấp cao nhất của bạn urls.py để định cấu hình ghi nhật ký. (Hoặc, có thể, settings.py)

Hãy chắc chắn rằng mọi mô-đun đều có sẵn trình ghi nhật ký để ghi nhật ký.

Đảm bảo mọi dịch vụ web gọi bạn thực hiện đều có khối thử/loại trừ xung quanh nó và bạn viết ngoại lệ cho nhật ký của mình.

+0

Điều này hữu ích nhưng không chính xác những gì tôi mong đợi. Xem "Chỉnh sửa" được đề cập. – jlpp

-1

Nếu bạn đang ở trên một hệ thống * nix bạn có thể

ghi vào một khúc gỗ (ví dụ. Mylog.txt) trong python sau đó chạy "tail -f mylog.txt" trong giao diện điều khiển

này là một cách tiện dụng để xem bất kỳ loại log trong thời gian thực gần

6

chức năng process_exception được gọi cho một số trường hợp ngoại lệ (ví dụ: assert (False) trong views.py) nhưng process_exception không nhận được gọi cho các lỗi khác như Nhập khẩu (ví dụ: nhập thisclassdoesnotexist trong urs.py). Tôi là mới đối với Django/Python. Đây có phải là vì một số khác biệt giữa thời gian chạy và lỗi thời gian biên dịch không?

Không, chỉ vì process_exception middleware is only called if an exception is raised in the view.

Tôi nghĩ DEBUG_PROPAGATE_EXCEPTIONS (như đã đề cập đầu tiên bởi Jason Baker) là những gì bạn cần ở đây, nhưng tôi không nghĩ bạn không cần phải làm gì thêm (tức là sys.excepthook, v.v.) nếu bạn chỉ muốn truy nguyên bán cho console.

Nếu bạn muốn làm bất cứ điều gì phức tạp hơn với lỗi (tức là đổ nó vào tệp hoặc DB), cách tiếp cận đơn giản nhất sẽ là got_request_exception signal, mà Django gửi cho bất kỳ ngoại lệ nào liên quan đến yêu cầu. hay không.

Phương thức get_responsehandle_uncaught_exception của django.core.handlers.BaseHandler là đọc hiểu (và ngắn gọn) trong lĩnh vực này.

mà không phải thêm bất kỳ bổ sung nào xử lý ngoại lệ cho mã.Tôi đã không bao giờ xem xử lý ngoại lệ xung quanh báo cáo nhập.

Nhìn xung quanh nhiều hơn một chút, bạn sẽ thấy nó được thực hiện (thường trong trường hợp bạn muốn xử lý sự vắng mặt của phụ thuộc theo một số cách cụ thể). Điều đó nói rằng, nó sẽ tất nhiên là khá xấu xí nếu bạn phải đi sprinkling bổ sung thử-ngoại trừ khối trên tất cả các mã của bạn để thực hiện một thay đổi toàn cầu như thế nào trường hợp ngoại lệ được xử lý!

+0

Cảm ơn các chi tiết bổ sung, Carl. Tôi ước tôi có thể đánh dấu của bạn như một câu trả lời được chấp nhận. – jlpp