2012-05-01 29 views
10

Trong môi trường đa luồng (như hầu hết các nền tảng web), tôi thường bao gồm một số loại ID luồng vào nhật ký ứng dụng của mình. Điều này cho phép tôi biết chính xác mục nhập nhật ký nào đến từ yêu cầu/chuỗi nào, khi có nhiều yêu cầu cùng một lúc được ghi đồng thời vào cùng một nhật ký.Nhận ID công việc/chuỗi/quy trình/yêu cầu duy nhất trong PHP

Trong .NET/C#, điều này có thể được thực hiện bởi các trình định dạng của log4net, theo mặc định bao gồm ManagedThreadId (số) hoặc Name (tên đã cho) hiện tại. Những đặc tính duy nhất xác định một chủ đề (xem ví dụ: How to log correct context with Threadpool threads using log4net?

Trong PHP, tôi đã không tìm thấy bất cứ điều gì tương tự (Tôi đã yêu cầu Google, tài liệu PHP và SO) Liệu nó tồn tại

+3

Điều này có thể hữu ích: http://php.net/manual/en/function.zend-thread-id.php – Daan

Trả lời

4

zend_thread_id():.?

int zend_thread_id (void) 

hàm này trả về một định danh duy nhất cho thread hiện hành

Mặc dù:.

Chức năng này chỉ khả dụng nếu PHP được xây dựng với hỗ trợ ZTS (Zend Thread Safety) và chế độ gỡ lỗi (--enable-debug).


Bạn cũng có thể thử yo gọi mysql_thread_id(), khi bạn sử dụng API để truy cập cơ sở dữ liệu của bạn (hoặc mysqli::$thread_id khi sử dụng mysqli).

+0

Cảm ơn bạn, nhưng rất tiếc, tôi không thể sử dụng 'zend_thread_id()' và mặc dù tôi chạy trên Linux, cả 'exec ('gettid')' và 'mysql_thread_id()' không trả về gì cả. Có lẽ điều này là bởi vì tôi đang chạy trong một môi trường chia sẻ. Có sự lựa chọn nào khác không? – cheeesus

+0

Không phải là chỉ để gọi nó từ nguồn C, không phải từ thiết bị đầu cuối? –

+0

@Lukas bạn có thể đúng ... Không biết tại sao tôi đặt nó ở đó. – CodeCaster

0

PHP dường như không có chức năng cho tính năng này, nhưng máy chủ web của bạn có thể chuyển số nhận dạng qua biến môi trường. Ví dụ, có một mô-đun Apache được gọi là "mod_unique_id" [1] tạo ra một mã định danh duy nhất cho mỗi yêu cầu và lưu trữ nó như là một biến môi trường. Nếu có biến, nó sẽ được hiển thị thông qua $ _SERVER ['unique_id'] [2]

"Pure PHP" giải pháp có thể là viết một kịch bản tạo ra định danh ngẫu nhiên phù hợp, lưu trữ nó thông qua xác định ("unique_id" , val) và sau đó sử dụng tùy chọn auto_prepend_file [3] trong php.ini để bao gồm điều này trong mọi tập lệnh thực thi. Bằng cách này, id duy nhất sẽ được tạo khi yêu cầu bắt đầu xử lý và nó sẽ có sẵn trong quá trình xử lý yêu cầu.

15

Cho đến gần đây, tôi đã sử dụng apache_getenv ("UNIQUE_ID"), và nó làm việc hoàn hảo với một crc32 hoặc hàm băm khác.

Hiện tại tôi chỉ đang sử dụng phần sau đây, để loại bỏ sự phụ thuộc vào Apache và mod này.

$uniqueid = sprintf("%08x", abs(crc32($_SERVER['REMOTE_ADDR'] . $_SERVER['REQUEST_TIME'] . $_SERVER['REMOTE_PORT'])));

Đủ độc đáo để hiểu nhật ký nào thuộc về yêu cầu nào. Nếu bạn cần độ chính xác cao hơn, bạn có thể sử dụng các hàm băm khác.

Hy vọng điều này sẽ hữu ích.

+0

Chỉ cần nhắc nhở rằng nếu hai yêu cầu đến cùng một lúc, phương pháp này sẽ dẫn đến hai ID giống hệt nhau. –

+2

REMOTE_ADDR và ​​REQUEST_TIME sẽ tương tự như ở trường hợp đó, nhưng REMOTE_PORT sẽ khác nhau. REMOTE_PORT có thể tương tự với yêu cầu trước đó, trong trường hợp yêu cầu keepalive, nhưng sau đó REQUEST_TIME sẽ không giống nhau. – gilm

+1

'REQUEST_TIME_FLOAT' có sẵn từ PHP 5.4, và chính xác xuống micro giây. –

1

Tôi đã nhìn thấy getmypid() sử dụng cho mục đích này, nhưng có vẻ như cư xử khác nhau trên hệ thống khác nhau. Trong một số trường hợp, ID là duy nhất cho mỗi yêu cầu, nhưng trên các ID khác, nó được chia sẻ.

Vì vậy, bạn có lẽ tốt hơn đi với một trong những câu trả lời khác để đảm bảo tính di động.

0

Gán một ID để xác định dữ liệu đăng nhập từ phục vụ một yêu cầu có lẽ cũng đơn giản như việc tạo ra một phiên bản UUID 4 (ngẫu nhiên) và ghi nó vào mỗi dòng nhật ký.

Có thậm chí là phần mềm giúp với điều đó: ramsey/uuid, php-middleware/request-id

Thêm nó vào mỗi dòng của khai thác gỗ rất dễ dàng khi sử dụng log4php bằng cách đặt UUID để các dữ liệu LoggerMDC và sử dụng một LogFormatter thích hợp. Với các logger PSR-3, nó có thể phức tạp hơn một chút, YMMV. Một UUID được tạo ngẫu nhiên sẽ phù hợp để xác định một yêu cầu duy nhất và bằng cách sử dụng UUID đó trong tiêu đề HTTP của các yêu cầu phụ và trong phản hồi, thậm chí có thể theo dõi một yêu cầu trên nhiều hệ thống và nền tảng bên trong cụm máy chủ. Tuy nhiên, đặt nó như là một tiêu đề không phải là nhiệm vụ của bất kỳ của các gói tôi đã đề cập.

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