2013-07-23 27 views
10

Tôi đang sử dụng giám sát để quản lý chương trình php cần chạy trong nền. Chương trình đó ghi lại các sự kiện vào một tệp worker_log. Nó đơn giản là đủ để cấu hình này trong supervisord.conf Tôi đang sử dụng:Nhật ký thời gian của các chương trình được quản lý bởi người giám sát

stderr_logfile=/var/log/supervisord/worker_log; 

Tuy nhiên, tôi muốn cho các sự kiện được ghi vào nhật ký để đánh dấu thời gian mình. Tôi không có quyền kiểm soát chương trình php, do đó, trang trí nhật ký của nó không phải là một lựa chọn. Tôi thấy rằng những gì tôi sẽ làm là nhận xét cấu hình đăng nhập ở trên và trang trí chương trình thông qua các đường ống lệnh trong cấu hình lệnh của người giám sát:

command=php /www/myapp/worker.php 2>&1 | sed "s/^/`date` /" > /var/log/supervisord/worker_log; 

Khi chạy lệnh này theo cách thủ công, nó có vẻ hoạt động tốt. Tuy nhiên, giám sát dường như bằng cách nào đó ngăn chặn nó hoạt động đúng cách, và tôi không thể nói như thế nào. worker.php hoạt động tốt, nhưng báo cáo là, trong cấu hình này, bị chặn. Và, do đó, tất nhiên là không thêm dấu thời gian.

Có ai biết đủ về điều này để cung cấp hướng dẫn về cách đạt được mục tiêu của việc đánh dấu thời gian đầu ra của nhân viên không?

+0

Is có khả năng thông số lệnh không hỗ trợ đường ống? Hoặc có thể là lệnh khi chạy là phát hành các thiết bị đầu cuối, mà supervisord không hỗ trợ? –

Trả lời

7

Bạn có thể viết một kịch bản wrapper chuyên dụng sẽ đính kèm một bộ lọc cho stderr trước khi gọi đang lao động của bạn:

// filter to prepend date/time on all stderr output 
class eventdata_filter extends php_user_filter 
{ 
    function filter($in, $out, &$consumed, $closing) 
    { 
     while (($bucket = stream_bucket_make_writeable($in))) { 
      $bucket->data = date('c') . ' ' . $bucket->data; 
      $consumed += $bucket->datalen; 
      stream_bucket_append($out, $bucket); 
     } 
     return PSFS_PASS_ON; 
    } 
} 

// register our custom filter  
stream_filter_register('eventdata', 'eventdata_filter'); 

// keep a reference to the attached filter 
$filter = stream_filter_append(STDERR, 'eventdata', STREAM_FILTER_WRITE); 

// isolate the worker from any variables in this scope, such as $filter 
function run() 
{ 
    include 'worker.php'; 
} 

// run the worker 
run(); 

// remove the filter 
stream_filter_remove($filter); 

Btw, nếu bạn không loại bỏ bộ lọc nó gây ra một lỗi segmentation (ít nhất , được thử nghiệm trên 5.4).

+0

Tôi sẽ thử điều này ngay hôm nay! Đó là một gợi ý thực sự tốt, mặc dù phải thừa nhận một lớp mã không may. –

+0

Điều này sẽ không thêm dấu thời gian vào một thông báo lỗi nghiêm trọng, điều này bỏ qua tất cả mã người dùng và chuyển thẳng đến 'thông báo đầu ra tới STDERR và chết' – StampyCode

+0

@Stampy Yeah, thật không may là bản chất của các lỗi nghiêm trọng. handler = (mặc dù, có lẽ một trình xử lý tắt máy có thể hoạt động ... –

4

câu trả lời trước (từ Jack) là chính xác ở chỗ bạn cần một lớp mã khác để đánh dấu thời gian cho mỗi dòng. Một lớp lót này trong perl sẽ đạt được kết quả tương tự:

perl -ne '@timeparts=localtime(); printf("%04d/%02d/%02d %02d:%02d:%02d %s",$timeparts[5]+1900,$timeparts[4]+1,@timeparts[3,2,1,0], $_);' 

Sử dụng điều này thay cho tập lệnh sed.

Một vấn đề với cách tiếp cận bạn đã cố gắng không làm việc là ngày được tính toán và thay thế bằng vỏ tại thời điểm đó lệnh sed được gọi vì vậy tất cả các dòng sẽ có các dấu thời gian đăng nhập cùng

+0

Tại sao không chỉ «scalar in 'perl -ne' (localtime)." ". $ _ ''? Hoặc có thể 'perl -mPOSIX = strftime -ne' print strftime ("% F% T", giờ địa phương), $ _; '' – Otheus

+0

Điều đó cũng có thể hoạt động. Tôi thích định dạng mà tôi đưa ra nhưng đó là vấn đề của mỗi sở thích – Nick

Các vấn đề liên quan