在PHP中获取唯一的worker / thread / process / request ID

时间:2012-05-01 21:59:09

标签: php multithreading logging webrequest

在多线程环境中(像大多数Web平台一样)我经常在我的应用程序的日志中包含某种线程ID。这使我能够在同时写入同一日志的多个请求时确切地告诉哪个日志条目来自哪个请求/线程。

在.NET / C#中,这可以通过log4net的格式化程序来完成,默认情况下包括当前线程的ManagedThreadId(数字)或Name(给定名称)。这些属性唯一标识一个线程(例如参见:How to log correct context with Threadpool threads using log4net?

在PHP中,我没有发现任何类似的内容(我问Google,PHP文档和SO)。它存在吗?

5 个答案:

答案 0 :(得分:16)

直到最近,我使用了apache_getenv(" UNIQUE_ID"),它与crc32或其他哈希函数完美配合。

现在我只是使用以下内容,以消除对Apache和此mod的依赖。

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

它的独特性足以了解哪些日志属于哪个请求。如果需要更高的精度,可以使用其他哈希函数。

希望这有帮助。

答案 1 :(得分:6)

zend_thread_id()

int zend_thread_id ( void ) 
     

此函数返回当前线程的唯一标识符。

虽然:

  

只有在使用ZTS(Zend线程安全)支持和调试模式(--enable-debug)构建PHP时,此功能才可用。


当您使用该API进行数据库访问时(或使用mysqli时mysql_thread_id()),您也可以尝试调用mysqli::$thread_id

答案 2 :(得分:1)

我已经看到getmypid()用于此目的,但它似乎在不同的系统上表现不同。在某些情况下,ID对于每个请求都是唯一的,但在其他情况下,它是共享的。

所以,你可能更愿意使用其中一个答案来确保可移植性。

答案 3 :(得分:0)

PHP似乎没有可用的功能,但您的Web服务器可能能够通过环境变量传递标识符。例如,一个名为“mod_unique_id”[1]的Apache模块为每个请求生成唯一标识符,并将其存储为环境变量。如果该变量存在,则应通过$ _SERVER ['unique_id'] [2]

显示该变量

“纯PHP”解决方案可能是编写一个生成合适的随机标识符的脚本,通过define(“unique_id”,val)存储它,然后在php.ini中使用auto_prepend_file [3]选项将其包含在每个脚本中执行。这样,当请求开始处理时,将创建唯一ID,并且在处理请求期间它将可用。

答案 4 :(得分:0)

分配ID以识别提供请求的记录数据可能就像创建UUID版本4(随机)并将其写入日志的每一行一样简单。

甚至还有软件帮助:ramsey/uuidphp-middleware/request-id

通过将UUID放入LoggerMDC数据并使用适当的LogFormatter来使用log4php时,将其添加到每个日志记录行都很容易。对于PSR-3记录器,它可能有点复杂,YMMV。

随机创建的UUID将适合于识别单个请求,并且通过在子请求的HTTP头中和响应中使用该UUID,甚至可以在服务器内的多个系统和平台上跟踪一个请求农场。但是,将它作为标题并不是我提到的任何软件包的任务。

相关问题