it-swarm-es.com

¿Cómo agregar una marca de tiempo al registro de script bash?

Tengo un script en ejecución constante que envío a un archivo de registro:

script.sh >> /var/log/logfile

Me gustaría agregar una marca de tiempo antes de cada línea que se agrega al registro. Me gusta:

Sat Sep 10 21:33:06 UTC 2011 The server has booted up.  Hmmph.

¿Hay algún jujitsu que pueda usar?

101
Antonius Bloch

Puede canalizar la salida del script a través de un bucle que prefija la fecha y hora actuales:

./script.sh | while IFS= read -r line; do printf '%s %s\n' "$(date)" "$line"; done >>/var/log/logfile

Si va a usar esto mucho, es fácil hacer una función bash para manejar el ciclo:

adddate() {
    while IFS= read -r line; do
        printf '%s %s\n' "$(date)" "$line";
    done
}

./thisscript.sh | adddate >>/var/log/logfile
./thatscript.sh | adddate >>/var/log/logfile
./theotherscript.sh | adddate >>/var/log/logfile
92
Gordon Davisson

Ver ts del paquete Ubuntu moreutils:

command | ts

O si $command realiza almacenamiento en búfer automático (requiere expect-dev paquete):

unbuffer command | ts
63
Willem

El comando date proporcionará esa información

date -u
Sat Sep 10 22:39:24 UTC 2011

así que puedes

echo $(date -u) "Some message or other"

es eso lo que querías ?

20
user9517

Puede simplemente echo las salidas del comando al archivo de registro. es decir,

echo "`date -u` `./script.sh`" >> /var/log/logfile

Realmente funciona :)

Ejemplo:

[[email protected]]$ ./script.sh 
Hello Worldy
[[email protected]]$ echo "`date -u` `./script.sh`" >> logfile.txt
[[email protected]]$ cat logfile.txt 
Mon Sep 12 20:18:28 UTC 2011 Hello Worldy
[[email protected]]$ 
12
SparX

Hacer una config.sh archivo

#!/usr/bin/env bash
LOGFILE="/path/to/log.log"
TIMESTAMP=`date "+%Y-%m-%d %H:%M:%S"`

Cuando necesita enviar para usar el archivo de registro

#!/usr/bin/env bash
source /path/to/config.sh

echo "$TIMESTAMP Say what you are doing" >> $LOGFILE

do_what_you_want >> $LOGFILE

El archivo de registro se verá así

2013-02-03 18:22:30 Say what you are doing

Entonces será fácil ordenar por fecha

9
scls

La respuesta aceptada https://serverfault.com/a/310104 puede ser un poco lenta, si se deben procesar muchas líneas, con la sobrecarga de iniciar el proceso date permitiendo alrededor de 50 líneas por segundo en Ubuntu, y solo alrededor de 10-20 en Cygwin.

Cuando se puede suponer bash, una alternativa más rápida sería la printf incorporada con su especificador de formato %(...)T. Comparar

>> while true; do date; done | uniq -c
     47 Wed Nov  9 23:17:18 STD 2016
     56 Wed Nov  9 23:17:19 STD 2016
     55 Wed Nov  9 23:17:20 STD 2016
     51 Wed Nov  9 23:17:21 STD 2016
     50 Wed Nov  9 23:17:22 STD 2016

>> while true; do printf '%(%F %T)T\n'; done | uniq -c
  20300 2016-11-09 23:17:56
  31767 2016-11-09 23:17:57
  32109 2016-11-09 23:17:58
  31036 2016-11-09 23:17:59
  30714 2016-11-09 23:18:00
6
kdb

Te refieres a:

(date && script.sh) >> /var/log/logfile
5
cjc

Prueba esto

timestamp()
{
 date +"%Y-%m-%d %T"
}

Llame a esta función de marca de tiempo en cada comando echo:

echo "$(timestamp): write your log here" >> /var/log/<logfile>.log
4
Sanjay Yadav

Respuesta corta formateada para ajustarse a la pregunta

script.sh | gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }' >> /var/log/logfile

Explicación

awk se ejecuta rápidamente y puede funcionar como filtro de tubería Unix y fecha de impresión por sí mismo.

gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }'

Vamos a compararlo:

yes |head -5000000 |gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }' |uniq -c
 461592 [2017-02-28 19:46:44] y
 488555 [2017-02-28 19:46:45] y
 491205 [2017-02-28 19:46:46] y
 498568 [2017-02-28 19:46:47] y
 502605 [2017-02-28 19:46:48] y
 494048 [2017-02-28 19:46:49] y
 493299 [2017-02-28 19:46:50] y
 498005 [2017-02-28 19:46:51] y
 502916 [2017-02-28 19:46:52] y
 495550 [2017-02-28 19:46:53] y
  73657 [2017-02-28 19:46:54] y

Información Adicional

Sed parece correr mucho más rápido,

sed -e "s/^/$(date -R) /"

yes |head -5000000 |sed -e "s/^/$(date -R) /" |uniq -c
5000000 Tue, 28 Feb 2017 19:57:00 -0500 y

Sin embargo, en una inspección más cercana, el conjunto no parece cambiar el tiempo,

vmstat 1 | sed -e "s/^/$(date -R) /"

Porque date (que por cierto es más lento) se llama solo una vez.

3
ChuckCottrill

Otra opción es configurar una función para llamar cada vez que desee generar datos en su código:

PrintLog(){
  information=$1
  logFile=$2
  echo "$(date +'%Y-%m-%d %H:%M:%S" $information} >> $logFile
}

Luego, cada vez en su código, desea enviarlo a la llamada del archivo de registro

PrintLog "Stuff you want to add..." ${LogFileVariable}

Pan comido....

1
Josh Williams

El siguiente es el contenido de mi archivo de registro

[email protected]:~/search_start_sh$ tail restart_scrape.log 

2017-08-25 21:10:09 scrape_yy_news_main.py got down, now I will restart it

2017-08-25 21:10:09 check_yy_news_warn.py got down, now I will restart it

2017-08-25 21:14:53 scrape_yy_news_main.py got down, now I will restart it

algunos de mis contenidos de Shell son los siguientes

log_file="restart_scrape.log"
TIMESTAMP=`date "+%Y-%m-%d %H:%M:%S"`
echo "$TIMESTAMP $search_py_file got down, now I will restart it" | tee -a $log_file 
1
Jayhello

Este script imprime el resultado en la terminal y también lo guarda en el archivo de registro.

#!/bin/bash

MY_LOG=/var/log/output.log

echolog(){
    if [ $# -eq 0 ]
    then cat - | while read -r message
        do
                echo "$(date +"[%F %T %Z] -") $message" | tee -a $MY_LOG
            done
    else
        echo -n "$(date +'[%F %T %Z]') - " | tee -a $MY_LOG
        echo $* | tee -a $MY_LOG
    fi
}

echolog "My script is starting"
whoami | echolog

Salida de muestra:

[2017-10-29 19:46:36 UTC] - My script is starting
[2017-10-29 19:46:36 UTC] - root
1
Seff

Pipe a "sed":

script.sh | sed "s|^|$('date') :: |" >> /var/log/logfile
0
eubide