2012-01-24 36 views
8

Tôi muốn đăng nhập mọi lỗi nghiêm trọng, thậm chí hết thời gian chờ và những lỗi khác E_ERRORS. Tôi sử dụng hàm set_error_handler và shutdown, nhưng với cái cuối cùng tôi không thể có stacktrace. Có cách nào để có nó?PHP: nhật ký ngăn xếp dấu vết cho lỗi FATAL trong sản xuất

Tôi muốn ghi nhật ký lỗi trên máy chủ sản xuất để giúp giải quyết các lỗi xảy ra chỉ trong quá trình sản xuất. Tôi biết, xdebug trên máy chủ dev phải là đủ, nhưng nó không phải là. Có lẽ chúng ta có thể sử dụng xdebug với tối thiểu các tùy chọn được kích hoạt, hoặc một phiên bản đã tước của nó để thêm dấu vết ngăn xếp vào nhật ký lỗi?

Thông tin lỗi in mã này nếu xảy ra một lỗi, thậm chí là hết thời gian chờ.

<?php 
function shutdown() 
{ 
    $a=error_get_last(); 
    if($a!==null) print_r($a); 
} 
register_shutdown_function('shutdown'); 

Trả lời

7

Bạn sẽ không nhận được một vết đống trên lỗi nghiêm trọng vì "Fatal" có nghĩa là thực hiện kịch bản dừng ngay, ví dụ: các dấu vết không thể được tạo ra thông qua các kênh thông thường. Vì vậy, nếu bạn đã thiết lập một lỗi xử lý tùy chỉnh để ném ngoại lệ, nó sẽ không được áp dụng cho các lỗi gây tử vong theo PHP manual:

Các loại lỗi sau đây không thể được xử lý với một người dùng định nghĩa chức năng: E_ERROR , E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING và hầu hết E_STRICT được nêu trong tệp nơi set_error_handler() được gọi.

Cách dễ nhất để nhận thông tin về lỗi xảy ra trong lỗi sản phẩm. Ngoài ra, tôi sẽ không sử dụng xdebug trên một máy chủ sản xuất ... nó để gỡ lỗi môi trường phát triển của bạn và sẽ bổ sung thêm chi phí không cần thiết trong môi trường sản xuất.

Vì vậy, sửa đổi điều khiển tắt máy của bạn, bạn có thể làm một cái gì đó như thế này:

function shutdown() 
{ 
    if (! $err = error_get_last()) { 
    return; 
    } 

    $fatals = array(
    E_USER_ERROR  => 'Fatal Error', 
    E_ERROR   => 'Fatal Error', 
    E_PARSE   => 'Parse Error', 
    E_CORE_ERROR  => 'Core Error', 
    E_CORE_WARNING => 'Core Warning', 
    E_COMPILE_ERROR => 'Compile Error', 
    E_COMPILE_WARNING => 'Compile Warning' 
); 

    if (isset($fatals[$err['type']])) { 
    $msg = $fatals[$err['type']] . ': ' . $err['message'] . ' in '; 
    $msg.= $err['file'] . ' on line ' . $err['line']; 
    error_log($msg); 
    } 
} 
+0

Lưu ý rằng tôi đã ném trong ** E_USER_ERROR ** trong '' fatals' mảng, nhưng nó thực sự có thể được xử lý thành công bởi một trình xử lý lỗi tùy chỉnh. – rdlowrey

+0

Ok, tôi đã nghĩ đến một mô-đun PHP mà chỉ cần bắt stacktrace cho các lỗi nghiêm trọng, như xdebug nhưng nhẹ hơn. Nhiệm vụ của tôi là làm thế nào để có thêm thông tin về các lỗi nghiêm trọng trong sản xuất để giúp sửa chúng. –

+0

@ CédricGirard Ah tôi hiểu rồi.Tôi nghĩ rằng phần lớn các lỗi nghiêm trọng là loại có thể được loại bỏ trong giai đoạn phát triển ... phần còn lại là những điều kiện bất thường (như hết bộ nhớ, đập máy chủ của bạn với một cái cudgel ở giữa yêu cầu, vv). Trong những trường hợp này, tôi luôn tìm thấy phương pháp trên cung cấp đầy đủ thông tin để đăng nhập. Tôi đã không thử nghiệm để xem nếu nó hoạt động với các lỗi FATAL (tôi nghĩ rằng nó nên), nhưng bạn có thể thử thêm một cuộc gọi đến ['debug_print_backtrace'] (http://www.php.net/manual/en/function. debug-print-backtrace.php) bên trong trình xử lý tắt của bạn để tìm thông tin theo dõi – rdlowrey

1

Đối với đánh bắt thực hiện tối đa timeouts bạn có thể sử dụng php-fpm và thiết lập slowlog + request_slowlog_timeout đó sẽ đăng nhập đống dấu vết đầy đủ.

3

Nếu bạn sử dụng HHVM bạn có thể đặt

hhvm.error_handling.call_user_handler_on_fatals = 1 

trong php.ini của bạn để có nó gọi xử lý lỗi (với một stack trace) về lỗi gây tử vong. (more info)

Sử dụng hồ sơ cũng có thể là một tùy chọn - ví dụ: sử dụng XHProf và gọi xhprof_disable() trong trình xử lý tử vong có thể giúp bạn điều gì đó từ xa giống như theo dõi ngăn xếp. (Không có ý tưởng nếu điều này thực sự hoạt động.)

+0

Tùy chọn và liên kết HHVM chính xác là những gì tôi đang tìm kiếm. –

0

này làm việc cho tôi (bên trong một điều kiện vì vậy nó chỉ chạy trong một môi trường phát triển):

if (function_exists('xdebug_break')) { 
    register_shutdown_function(function() { 
     if ($last_error = error_get_last()) { 
      xdebug_break(); 
     } 
    }); 
} 
Các vấn đề liên quan