Получить уникальный идентификатор 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 и в ответе даже будет возможно отслеживать один запрос на нескольких системах и платформах внутри сервера фермы. Тем не менее, размещение его в качестве заголовка не является задачей любого из пакетов, о которых я упоминал.