Получить уникальный идентификатор employee/thread/process/request в PHP

В многопоточных средах (например, в большинстве веб-платформ) я часто включаю какой-то идентификатор потока в журналы моих приложений. Это позволяет мне точно указать, какая запись журнала была получена из запроса/потока, когда сразу несколько запросов, которые одновременно записываются в один и тот же журнал.

В .NET/С# это можно сделать с помощью форматировщиков log4net, которые по умолчанию включают текущий поток ManagedThreadId (число) или Name (данное имя). Эти свойства однозначно идентифицируют поток (см., Например: Как правильно установить контекст с потоками Threadpool с помощью log4net?

В PHP я не нашел ничего подобного (я спросил Google, PHP docs и SO). Он существует?

Ответ 1

zend_thread_id():

int zend_thread_id ( void ) 

Эта функция возвращает уникальный идентификатор текущего потока.

Хотя:

Эта функция доступна только в том случае, если PHP был создан с поддержкой и отключением режима ZTS (Zend Thread Safety) (--enable-debug).


Вы также можете попробовать yo call mysql_thread_id(), когда вы используете этот API для доступа к базе данных (или mysqli::$thread_id при использовании mysqli).

Ответ 2

До недавнего времени я использовал apache_getenv ( "UNIQUE_ID" ), и он отлично работал с crc32 или другой хэш-функцией.

В настоящее время я просто использую следующее, чтобы удалить зависимость от Apache и этого мода.

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

Он достаточно уникален, чтобы понять, какие журналы принадлежат к какому запросу. Если вам нужна более высокая точность, вы можете использовать другие хэш-функции.

Надеюсь, что это поможет.

Ответ 3

Я видел getmypid(), используемый для этой цели, но, похоже, он ведет себя по-разному в разных системах. В некоторых случаях идентификатор уникален для каждого запроса, но и для других, которые он разделяет.

Итак, вам, вероятно, лучше пойти с одним из других ответов, чтобы обеспечить переносимость.

Ответ 4

PHP, похоже, не имеет функции для этого, но ваш веб-сервер может передавать идентификатор через переменные среды. Например, модуль Apache, называемый "mod_unique_id" [1], который генерирует уникальный идентификатор для каждого запроса и сохраняет его в качестве переменных среды. Если переменная присутствует, она должна быть видна через $_SERVER ['unique_id'] [2]

"Pure PHP" может состоять в том, чтобы написать script, который генерирует подходящий случайный идентификатор, сохраняет его через define ( "unique_id", val), а затем использует параметр auto_prepend_file [3] в php.ini, чтобы включить это в каждый script, который выполняется. Таким образом, уникальный идентификатор будет создан, когда запрос начнет обработку, и он будет доступен во время обработки запроса.

Ответ 5

Назначение идентификатора для идентификации зарегистрированных данных от обслуживания запроса, вероятно, так же просто, как создание UUID версии 4 (случайный) и запись его в каждую строку журнала.

Даже программное обеспечение помогает с этим: ramsey/uuid, php-middleware/request-id

Добавление его в каждую строку ведения журнала легко при использовании log4php путем помещения UUID в данные LoggerMDC и использования соответствующего LogFormatter. С регистраторами PSR-3 это может быть немного сложнее, YMMV.

Случайно созданный UUID будет подходящим для идентификации одного единственного запроса, и с использованием этого UUID в заголовках HTTP-запросов sub и в ответе даже будет возможно отслеживать один запрос на нескольких системах и платформах внутри сервера фермы. Тем не менее, размещение его в качестве заголовка не является задачей любого из пакетов, о которых я упоминал.