15

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

在 .NET/C# 中,这可以通过 log4net 的格式化程序来完成,默认情况下包括当前线程的ManagedThreadId(数字)或Name(给定名称)。这些属性唯一地标识一个线程(参见例如:如何使用 log4net 使用 Threadpool 线程记录正确的上下文?

在 PHP 中,我没有找到任何类似的东西(我问过 Google、PHP 文档和 SO)。它存在吗?

4

5 回答 5

21

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

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

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

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

希望这可以帮助。

于 2014-03-19T14:16:33.693 回答
7

zend_thread_id()

int zend_thread_id ( void ) 

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

虽然:

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


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

于 2012-05-01T22:08:44.093 回答
1

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

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

于 2014-01-09T20:28:54.550 回答
1

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

因此,您最好选择其他答案之一来确保可移植性。

于 2016-06-09T01:49:02.433 回答
0

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

甚至还有软件可以帮助解决这个问题:ramsey/uuidphp-middleware/request-id

使用log4php通过将 UUID 放入 LoggerMDC 数据并使用适当的 LogFormatter 将其添加到每一行日志记录很容易。使用 PSR-3 记录器,它可能会更复杂一些,YMMV。

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

于 2016-06-13T12:35:24.443 回答