Question Comment ajouter un horodatage au journal de script bash?


J'ai un script en cours d'exécution que je sortie dans un fichier journal:

script.sh >> /var/log/logfile

J'aimerais 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?


77
2017-09-10 21:35


origine


Voir cette question. serverfault.com/questions/80749/…. Une réponse de couple s'appliquerait ici. - Zoredache
Pour une solution awk / gawk, voir: stackoverflow.com/questions/21564/… - User


Réponses:


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 echo "$(date) $line"; done >>/var/log/logfile

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

adddate() {
    while IFS= read -r line; do
        echo "$(date) $line"
    done
}

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

78
2017-09-10 21:58



@Nils c'est un truc pour prévenir read de rognage des espaces au début et à la fin de la ligne. Il définit IFS (le séparateur de champs interne de bash, essentiellement une liste de caractères d’espace) à vider le read commander. - Gordon Davisson
... et -r ignore le caractère d'échappement "\". Cela devrait vraiment fonctionner dans tous les cas - une excellente pièce de script. - Nils
@Nils ce n’est pas complètement à l’épreuve des balles, car certaines implémentations de echo interpréter les séquences d'échappement. Si vous vraiment ne voulez pas gâcher le contenu (autre que l'ajout de dates), remplacez le echo commande avec printf "%s %s\n" "$(date)" "$line" - Gordon Davisson
Vous pourriez être intéressé par un Conforme à la norme ISO-8601 date / heure: date -u +"%Y-%m-%dT%H:%M:%SZ" ou peut-être plus jolie date +"%Y-%m-%d %T". - Pablo Bianchi
Bien que ce script fonctionne comme prévu, il génère un nouveau processus (exécuter date) pour chaque journal, ce qui peut être un inconvénient majeur en fonction de votre machine et du nombre de journaux. Je suggérerais plutôt d'utiliser ts si disponible, voir la réponse de @willem - Michael Schaefers


Voir "ts" dans le paquet "moreutils" de Ubuntu:

command | ts

Ou, si $ command utilise la mise en mémoire tampon automatique (requiert expect-dev pkg):

unbuffer command | ts

41
2017-10-29 15:20





Vous pouvez simplement écho la commande est sortie dans le fichier journal. c'est à dire,

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

Ça marche vraiment :)

Exemple:

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

11
2017-09-10 22:03



Hmm ne travaille pas pour moi. - Antonius Bloch
Qu'obtenez-vous lorsque vous exécutez la commande? - SparX
Cela met un horodatage avant la sortie entière de '' ./script.sh '', pas avant chaque ligne. - clacke


le rendez-vous amoureux commande fournira cette information

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?


10
2018-02-03 17:23



Utiliser la commande date était un peu ce que j'avais en tête, mais je ne peux pas vraiment l'ajouter au script lui-même. Ce que je recherche, c'est un moyen de changer cette ligne: "script.sh >> / var / log / logfile "pour ajouter la date. - Antonius Bloch
Dans ce cas, redirigez la sortie de votre script vers un canal nommé et demandez à un démon d'écouter la sortie qui prend la sortie du script et ajoute une date avant de l'écrire dans un fichier journal. Vous pouvez probablement modifier le script j'ai écrit ici pour faire ça. Je le ferais parce que cela m'intéresse, mais il est tard au Royaume-Uni et je commence tôt demain. - Iain


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 à utiliser le fichier journal

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


7
2017-09-12 20:34



Votre '' config.sh '' exécutera '' la date '' exactement une fois, sur '' source ... / config.sh ''. - clacke


Tu veux dire comme:

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

5
2018-04-27 16:45



Mon dieu, tout le monde, tout le monde est en train de remplacer les tiques, les pipes nommées, etc. Il suffit de placer la commande de date et le script entre parenthèses! Le type qui a la fonction a un cas légitime s'il existe une sortie multiligne et que le journal doit être joli avec la date sur chaque ligne, mais la plupart de ces solutions sont excessives et n'utilisent pas la sémantique du shell. - cjc
Cela ne fera qu'ajouter l'horodatage une fois par exécution de script.sh. Le PO nécessite un horodatage par ligne. - Dave Forgac
Bien que cela ne réponde pas à la question OP, je l’ai toujours trouvée utile. - User


Essaye ça

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

Appelez cette fonction d'horodatage dans chaque commande echo:

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

3
2017-11-09 22:24



@ shazbot: Merci pour l'édition, c'était une erreur de frappe, je n'ai pas remarqué. - Sanjay Yadav


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

Quand bash peut être supposé une alternative plus rapide serait la printf construit avec ses %(...)T spécificateur de format. 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

3
2017-08-26 01:51