2011-01-11 6 views
8

Quiero archivo de registro de cola con grep y la envió por correo como:cola y registro de grep y correo (Linux)

tail -f /var/log/foo.log | grep error | mail -s subject [email protected] 

cómo puedo hacer esto?

+0

Esa pregunta es como "Tengo' print ('Foo'); 'y quiero que se imprima 'Foo'. ¿Cómo hago eso?" ¿Cuál es exactamente su pregunta? –

+1

Probablemente no desee 'tail' * -f * ya que esto seguirá continuamente en la parte inferior del archivo. 'grep' no ** rastrea ** registros, tampoco. ¿Cuál es el problema que estás tratando de resolver? – Johnsyweb

+0

'tail -f .. | grep ... 'es para generar datos agregados a medida que el archivo crece y con el uso de grep, solo imprime líneas adjuntas que coinciden solo con – ajreal

Respuesta

2

Voy a probarlo. Tal vez aprenda algo si mi código malicioso de bash es escudriñado. Existe la posibilidad de que ya haya un millón de soluciones para hacer esto, pero no voy a averiguarlo, ya que estoy seguro de que ha explorado las profundidades y el ancho del cyberocean. Parece que lo que desea puede separarse en dos bits: 1) a intervalos regulares obtenga la 'última cola' del archivo, 2) si la última cola realmente existe, envíela por correo electrónico. Para los intervalos regulares en 1), use cron. Para obtener la última cola en 2), tendrá que hacer un seguimiento del tamaño del archivo. El script bash a continuación lo hace: es una solución a 2) que puede invocarse cron. Utiliza el tamaño del archivo en caché para calcular el fragmento del archivo que necesita enviar. Tenga en cuenta que para un archivo myfile se crea otro archivo .offset.myfile. Además, la secuencia de comandos no permite componentes de ruta en el nombre del archivo. Reescribir o corregirlo en la invocación [p. (cd/foo/bar & & segtail.sh zut), suponiendo que se llame segtail.sh].

#!/usr/local/bin/bash 
file=$1 
size=0 
offset=0 
if [[ $file =~/]]; then 
    echo "$0 does not accept path components in the file name" 2>&1 
    exit 1 
fi 
if [[ -e .offset.$file ]]; then 
    offset=$(<".offset.$file") 
    fi 
if [[ -e $file ]]; then 
    size=$(stat -c "%s" "$file") # this assumes GNU stat, possibly present as gstat. CHECK! 
            # (gstat can also be Ganglias Status tool - careful). 
fi 
if (($size < $offset)); then  # file might have been reduced in size 
    echo "reset offset to zero" 2>&1 
    offset=0 
fi 
echo $size > ".offset.$file" 
if [[ -e $file && $size -gt $offset ]]; then 
    tail -c +$(($offset+1)) "$file" | head -c $(($size - $offset)) | mail -s "tail $file" [email protected] 
fi 
+0

La parte grep de su pregunta no fue respondida en esto. A la izquierda como ejercicio. – micans

+0

Necesita comillas completas para las expansiones de variables de nombre de archivo. El camino a bash no es correcto para todos los sistemas; tal vez invocar a través de 'env'. La salida de 'stat' es muy variable entre sistemas y versiones (!). Presumiendo la estadística reciente de GNU, intente -c para resolver esto y evite la necesidad de analizar. – Sorpigal

+0

No se necesita 'cat':' offset = $ (<. Offset. $ File) '. La segunda parte de 'if [[-e $ file && $ size> $ offset]]' es una comparación léxica por lo que no hará lo que esperas si, por ejemplo, '$ size' == 10 y' $ offset '== 2. Use esto en su lugar:' if [[-e $ file]] && (($ size> $ offset)) '. Puede omitir signos de dólar en la mayoría de los casos dentro de '(())' y '$ (())'. –

17

¿Desea enviar un correo electrónico cuando se produzcan errores de correo electrónico? Eso podría fallar;)

Sin embargo, puede intentar algo como esto:

tail -f $log | 
grep --line-buffered error | 
while read line 
do 
    echo "$line" | mail -s subject "$email" 
done 

Lo que para cada línea en la salida de grep envía un correo electrónico.

Run por encima de script de shell con

nohup ./monitor.sh & 

por lo que seguirá funcionando en el fondo.

+1

no necesita las barras diagonales inversas - la carcasa buscará la siguiente línea para una tubería posterior (y también '&', '&&' y '||') –

+0

Interesante ... una cosa que eché de menos. Gracias @glenn jackman –

+1

Supongamos que quiero imprimir 10 líneas después del error también (grep -A 10 error). En su enfoque, recibiré 10 correos electrónicos, ¿qué debo hacer para recibir un solo correo, incluidas las 10 líneas? – markus