2009-07-09 17 views

Respuesta

24

No creo que hay alguna manera mágica para hacerlo. Solo tiene que sondear continuamente el tamaño del archivo y generar cualquier dato nuevo. Esto es realmente bastante fácil, y lo único importante a tener en cuenta es que el tamaño de los archivos y otros datos estadísticos se almacenan en caché en php. La solución a esto es llamar al clearstatcache() antes de enviar cualquier dato.

Aquí hay una muestra rápida, que no incluye ningún control de errores:

function follow($file) 
{ 
    $size = 0; 
    while (true) { 
     clearstatcache(); 
     $currentSize = filesize($file); 
     if ($size == $currentSize) { 
      usleep(100); 
      continue; 
     } 

     $fh = fopen($file, "r"); 
     fseek($fh, $size); 

     while ($d = fgets($fh)) { 
      echo $d; 
     } 

     fclose($fh); 
     $size = $currentSize; 
    } 
} 

follow("file.txt"); 
+0

Hola, Su solución parece ser la quema de una gran cantidad de CPU (+ -40% en mi configuración de prueba). ¿Hay algún indicador de una forma más eficiente de mirar carpetas? – Coyote

+1

'usleep (100)' está durmiendo durante 100 millonésimas de segundo o durante 0,0001 segundos. Aumente esto a 'usleep (10000)' (0.01s) para reducir el uso de CPU a menos que necesite una latencia extremadamente baja. 'usleep (2000000)' o 'sleep (2)' (2s) para algo que solo quieres razonablemente fresco cuando lo miras. – ReactiveRaven

+0

Probé este código, pero no tuve éxito ... el navegador sigue cargando ... y no hace eco ... – ihtus

2
$handler = fopen('somefile.txt', 'r'); 

// move you at the end of file 
fseek($handler, filesize()); 
// move you at the begining of file 
fseek($handler, 0); 

Y probablemente tendrá que considerar un uso de stream_get_line

2

En lugar de sondeo tamaño del archivo que regular de verificar el archivo de tiempo de modificación: filemtime

+3

Ambos requieren una llamada stat() debajo de la superficie, por lo que realmente no importa. –

5

Pedido php-tail on Google code. Es una implementación de 2 archivos con PHP y Javascript y tiene muy poca carga en mi prueba.

Incluso es compatible con el filtrado con una palabra clave grep (útil para ffmpeg que escupe velocidad de cuadros, etc. cada segundo).

11
$handle = popen("tail -f /var/log/your_file.log 2>&1", 'r'); 
while(!feof($handle)) { 
    $buffer = fgets($handle); 
    echo "$buffer\n"; 
    flush(); 
} 
pclose($handle); 
+0

Se bloquea el servidor de Apache .. ¿Hacer esto solo a mí? – dctremblay

+0

Revise los registros de errores en busca de pistas, pero esto no debería estar bloqueando su proceso de apache. –

0

A continuación se muestra lo que he adaptado desde arriba. Llámalo periódicamente con una llamada ajax y añádelo a tu 'titular' (textarea) ... Espero que esto ayude ... ¡gracias a todos los que contribuyen a stackoverflow y otros foros similares!

/* Used by the programming module to output debug.txt */ 
session_start(); 
$_SESSION['tailSize'] = filesize("./debugLog.txt"); 
if($_SESSION['tailPrevSize'] == '' || $_SESSION['tailPrevSize'] > $_SESSION['tailSize']) 
{ 
     $_SESSION['tailPrevSize'] = $_SESSION['tailSize']; 
} 
$tailDiff = $_SESSION['tailSize'] - $_SESSION['tailPrevSize']; 
$_SESSION['tailPrevSize'] = $_SESSION['tailSize']; 

/* Include your own security checks (valid user, etc) if required here */ 

if(!$valid_user) { 
    echo "Invalid system mode for this page."; 
} 
$handle = popen("tail -c ".$tailDiff." ./debugLog.txt 2>&1", 'r'); 
while(!feof($handle)) { 
    $buffer = fgets($handle); 
    echo "$buffer"; 
    flush(); 
} 
pclose($handle); 
Cuestiones relacionadas