2012-05-01 7 views
10

In ambienti multi-thread (come la maggior parte delle piattaforme Web) Spesso includo una sorta di ID filo nei registri delle mie app. Ciò mi consente di dire esattamente quale voce del registro proviene da quale richiesta/thread, quando ci sono più richieste contemporaneamente che scrivono simultaneamente sullo stesso log.Ottieni un ID lavoratore/thread/processo/richiesta univoco in PHP

In .NET/C#, questo può essere eseguito dai programmi di formattazione di log4net, che per impostazione predefinita includono ManagedThreadId del thread corrente (un numero) o Name (un nome specifico). Queste proprietà identificano in modo univoco un filo (vedi ad esempio: How to log correct context with Threadpool threads using log4net?

In PHP, non ho trovato nulla di simile (ho chiesto di Google, documenti PHP e SO) Esiste

+3

Questo può essere utile: http://php.net/manual/en/function.zend-thread-id.php – Daan

risposta

4

zend_thread_id():.?

int zend_thread_id (void) 

Questa funzione restituisce un identificatore univoco per il thread corrente

Anche se:.

Questa funzione è disponibile solo se PHP è stato creato con ZTS (Zend Thread Safety) modalità di supporto e debug (--enable-debug).


Si potrebbe anche provare yo chiamata mysql_thread_id(), quando si utilizza tale API per l'accesso database (o mysqli::$thread_id quando si utilizza mysqli).

+0

Grazie, ma sfortunatamente, non posso usare 'zend_thread_id()', e sebbene io sia funzionando su Linux, sia exec ('gettid') 'che' mysql_thread_id() 'non restituiscono nulla. Forse perché sono in esecuzione in un ambiente condiviso. Ci sono altre opzioni? – cheeesus

+0

Non è disponibile solo per chiamarlo dalla sorgente C, non dal terminale? –

+0

@Lukas potresti avere ragione ... Non so perché l'ho messo lì. – CodeCaster

0

PHP non sembra avere una funzione per questo disponibile, ma il server Web potrebbe essere in grado di passare l'identificatore tramite variabili di ambiente. Esiste ad esempio un modulo Apache chiamato "mod_unique_id" [1] che genera un identificativo univoco per ogni richiesta e lo memorizza come una variabile di ambiente. Se la variabile è presente, dovrebbe essere visibile attraverso $ _SERVER [ 'Unique_ID'] [2]

soluzione "Pure PHP" potrebbe essere quello di scrivere uno script che genera adatto identificatore casuale, lo memorizza via define ("unique_id" , val) e quindi utilizzare l'opzione auto_prepend_file [3] in php.ini per includerlo in ogni script che viene eseguito. In questo modo l'ID univoco verrebbe creato quando la richiesta viene avviata e sarà disponibile durante l'elaborazione della richiesta.

15

Fino a poco tempo, ho usato apache_getenv ("UNIQUE_ID"), e ha funzionato perfettamente con un CRC32 o un'altra funzione di hash.

Al giorno d'oggi sto usando solo quanto segue, al fine di rimuovere la dipendenza da Apache e questa mod.

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

E 'abbastanza unica per comprendere che i registri che appartengono a richiesta. Se hai bisogno di maggiore precisione, puoi usare altre funzioni hash.

Spero che questo aiuti.

+0

Solo un promemoria che se due richieste arrivano allo stesso tempo, questo metodo produrrà due ID identici. –

+2

REMOTE_ADDR e REQUEST_TIME saranno simili in questo caso, ma REMOTE_PORT sarà diverso. REMOTE_PORT può essere simile a una richiesta precedente, in caso di richiesta keepalive, ma REQUEST_TIME non sarà lo stesso. – gilm

+1

'REQUEST_TIME_FLOAT' è disponibile da PHP 5.4 e preciso fino al microsecondo. –

1

Ho visto getmypid() utilizzato per questo scopo, ma sembra comportarsi in modo diverso su sistemi diversi. In alcuni casi l'ID è unico per ogni richiesta, ma su altri è condiviso.

Quindi, probabilmente è meglio andare con una delle altre risposte per garantire la portabilità.

0

Assegnare un ID per identificare i dati registrati da una richiesta probabilmente è semplice come creare un UUID versione 4 (casuale) e scriverlo su ogni riga del registro.

anche V'è un software che aiuta con: ramsey/uuid, php-middleware/request-id

aggiunta ad ogni linea di registrazione è facile quando si utilizza log4php mettendo l'UUID ai dati LoggerMDC e usando un LogFormatter appropriato. Con i logger PSR-3, potrebbe essere un po 'più complicato, YMMV.

Un UUID creato in modo casuale sarà adatto per identificare una singola richiesta e utilizzando tale UUID nelle intestazioni HTTP delle richieste secondarie e nella risposta, sarà anche possibile tracciare una richiesta su più sistemi e piattaforme all'interno del server farm. Tuttavia, metterlo come intestazione non è il compito di nessuno dei pacchetti che ho menzionato.