web-dev-qa-db-fra.com

Comment ajouter un horodatage au journal de script bash?

J'ai un script en cours d'exécution que je génère dans un fichier journal:

script.sh >> /var/log/logfile

Je voudrais ajouter un horodatage avant chaque ligne ajoutée au journal. Comme:

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

Y a-t-il un jujitsu que je peux utiliser?

101
Antonius Bloch

Vous pouvez diriger la sortie du script via une boucle qui préfixe la date et l'heure actuelles:

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

Si vous l'utilisez beaucoup, il est facile de créer une fonction bash pour gérer la boucle:

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

Voir ts du paquet Ubuntu moreutils:

command | ts

Ou si $command effectue une mise en mémoire tampon automatique (nécessite expect-dev paquet):

unbuffer command | ts
63
Willem

La commande ( date fournira ces informations

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

afin que vous puissiez

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

c'est ce que tu voulais?

20
user9517

Vous pouvez simplement echo les sorties de commande dans le fichier journal. c'est à dire,

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

Ça marche vraiment :)

Exemple:

[[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

Faire un config.sh fichier

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

Lorsque vous devez envoyer au fichier journal, utilisez

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

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

do_what_you_want >> $LOGFILE

Le fichier journal ressemblera à

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

Il sera donc facile de trier par date

9
scls

La réponse acceptée https://serverfault.com/a/310104 peut être un peu lente, si beaucoup de lignes doivent être traitées, avec la surcharge de démarrage du processus date permettant environ 50 lignes par seconde dans Ubuntu, et seulement environ 10-20 dans Cygwin.

Lorsque bash peut être supposé, une alternative plus rapide serait le printf intégré avec son spécificateur de format %(...)T. Comparer

>> 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

Tu veux dire comme:

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

Essaye ça

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

Appelez cette fonction d'horodatage dans chaque commande d'écho:

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

Réponse courte formatée pour s'adapter à la question

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

Explication

awk s'exécute rapidement et est capable de fonctionner en tant que filtre de tuyau Unix et imprime la date de lui-même.

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

Essayons de le comparer:

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

Information additionnelle

Sed semble courir beaucoup plus vite,

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

Cependant, en y regardant de plus près, le jeu ne semble pas changer le temps,

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

Parce que date (qui est plus lent d'ailleurs) n'est appelé qu'une seule fois.

3
ChuckCottrill

Une autre option consiste à configurer une fonction à appeler chaque fois que vous souhaitez générer des données dans votre code:

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

Ensuite, chaque fois dans votre code, vous souhaitez l'envoyer à l'appel du fichier journal

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

Peasy facile....

1
Josh Williams

Voici le contenu de mon fichier journal

[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

une partie de mon contenu Shell est comme ci-dessous

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

Ce script imprime la sortie dans le terminal et enregistre également dans le fichier journal.

#!/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

Exemple de sortie:

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

Pipe un "sed":

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