在PHP中获取唯一的工作者/线程/进程/请求ID

在PHP中获取唯一的工作者/线程/进程/请求ID,php,multithreading,logging,webrequest,Php,Multithreading,Logging,Webrequest,在多线程环境中(像大多数web平台),我经常在我的应用程序日志中包含某种线程ID。当同时有多个请求同时写入同一个日志时,这使我能够准确地判断哪个日志条目来自哪个请求/线程 在.NET/C#中,这可以由log4net的格式化程序完成,默认情况下,它包括当前线程的ManagedThreadId(一个数字)或Name(一个给定的名称)。这些属性唯一地标识线程(例如,请参见: 在PHP中,我没有发现任何类似的东西(我问过谷歌、PHP文档等等)。它存在吗?: 此函数返回当前线程的唯一标识符 尽管: 此函数

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

在.NET/C#中,这可以由log4net的格式化程序完成,默认情况下,它包括当前线程的
ManagedThreadId
(一个数字)或
Name
(一个给定的名称)。这些属性唯一地标识线程(例如,请参见:

在PHP中,我没有发现任何类似的东西(我问过谷歌、PHP文档等等)。它存在吗?

:

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

尽管:

此函数仅在PHP使用ZTS(Zend线程安全)支持和调试模式(--enable debug)构建时可用



当您使用该API访问数据库(或使用mysqli)时,您也可以尝试yo调用。

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

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

  • [1]
  • [2]
  • [3]

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

现在,为了消除对Apache和这个mod的依赖,我只使用下面的代码

$uniqueid=sprintf(“%08x”,abs)(crc32($\u服务器['REMOTE\u ADDR']。$\u服务器['REQUEST\u TIME']。$\u服务器['REMOTE\u PORT']));

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

希望这能有所帮助。

我见过有人将其用于此目的,但它在不同系统上的行为似乎有所不同。在某些情况下,每个请求的ID都是唯一的,但在其他情况下,它是共享的


因此,为了确保可移植性,您最好选择其他答案。

分配一个ID,以便从服务请求中识别记录的数据,这可能与创建UUID版本4(随机)并将其写入日志的每一行一样简单

甚至有软件可以帮助做到这一点:

通过将UUID放入LoggerMDC数据并使用适当的LogFormatter,将其添加到日志记录的每一行中是很容易的


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

这可能很有用:谢谢,但不幸的是,我不能使用
zend\u thread\u id()
,尽管我在Linux上运行,
exec('getId')
mysql\u thread\u id()
不返回任何内容。可能这是因为我在共享环境中运行。还有其他选项吗?gettid不只是用于从C源调用它,而不是从终端调用它吗?只是提醒一下,如果两个请求同时出现,此方法将产生两个相同的ID。在这种情况下,REMOTE\u ADDR和REQUEST\u time将类似,但REMOTE\u time_端口会有所不同。在keepalive请求的情况下,远程\u端口可以类似于前一个请求,但随后的请求\u时间将不同。
request\u TIME\u FLOAT
从PHP 5.4开始就可用,精确到微秒。
hash('crc32b',$value)
看起来更可读
sprintf(%08x),abs(crc32($value)))
,我认为它实现了相同的结果。当然,这对于问题的目的来说是足够的-区分来自不同线程的日志条目。但是,我确实在PHP日志中得到了通知-
未定义索引:REMOTE\u ADDR
REMOTE\u PORT
-从Windows Task Scheduler.getmypid retu调用PHP CLI运行php实例的rns进程id。由于在某些系统(如CGI)中,php保持运行和处理请求,因此它总是返回相同的id
int zend_thread_id ( void )