Existe-t-il un moyen de faire en sorte que journalctl affiche les journaux à partir de «la dernière exécution de foo.service»?

16

Je suis particulièrement intéressé par cela pour regarder la sortie des services oneshot qui s'exécutent sur une minuterie. Le --unitdrapeau est proche, mais il concatène toutes les exécutions du service ensemble. La manière la plus évidente à laquelle je peux penser serait de filtrer sur PID, mais cela me fait me soucier de la réutilisation / des services PID qui débouchent, et obtenir le dernier PID est assez gênant. Existe-t-il un autre identifiant qui correspond à une seule exécution d'un service, que je pourrais utiliser pour filtrer les journaux?

EDIT: Je serais heureux d'accepter un «non» faisant autorité si c'est la vraie réponse.

Jack O'Connor
la source

Réponses:

7

Depuis la systemdversion 232, nous avons le concept d'ID d'invocation. Chaque fois qu'une unité est exécutée, elle a un ID d'invocation 128 bits unique. Contrairement à MainPIDce qui peut être recyclé ou ActiveEnterTimestampqui peut avoir des problèmes de résolution, c'est un moyen infaillible d'obtenir tout le journal d'une invocation d'unité systemd particulière.

Pour obtenir le dernier ID d'appel d'une unité

$ systemctl show --value -p InvocationID openipmi
bd3eb84c3aa74169a3dcad2af183885b

Pour obtenir le journal de la dernière invocation, disons openipmi, qu'elle ait échoué ou non, vous pouvez utiliser le

$ journalctl _SYSTEMD_INVOCATION_ID=`systemctl show -p InvocationID --value openipmi.service`
-- Logs begin at Thu 2018-07-26 12:09:57 IDT, end at Mon 2019-07-08 01:32:50 IDT. --
Jun 21 13:03:13 build03.lbits openipmi[1552]:  * Starting ipmi drivers
Jun 21 13:03:13 build03.lbits openipmi[1552]:    ...fail!
Jun 21 13:03:13 build03.lbits openipmi[1552]:    ...done.

(Notez que le --valueest disponible depuis systemd 230, plus ancien que InvocationID)

Elazar Leibovich
la source
1
Si quelqu'un essaie d'enquêter sur cela: cela journalctl --user -u UNITFILE -f -o json-prettypourrait être utile; vous recherchez des MESSAGEdomaines en particulier. J'ai découvert que vous pourriez également avoir besoin USER_INVOCATION_ID, et que certains messages ne sont associés à aucun identifiant d'invocation, ils ne peuvent donc pas être filtrés via ce mécanisme. Je ne sais pas pourquoi, ma connexion est peut-être mal configurée ..
karlicoss
14

Je ne sais pas quel horodatage a le plus de sens, mais cela fonctionne pour moi. Espérons qu'il existe une meilleure façon de travailler avec les horodatages systemctl showque awk - ne pourrait pas comprendre comment contrôler le format des horodatages.

unit=foo.service

ts=$(systemctl show -p ActiveEnterTimestamp $unit)

echo $ts
ActiveEnterTimestamp=Fri 2016-11-11 12:30:01 MST

journalctl -u $unit --since "$(echo $ts | awk '{print $2 $3}')"
Erik Stephens
la source
Juste au cas où quelqu'un en aurait besoin comme doublure: journalctl --since " systemctl show -p ActiveEnterTimestamp thermo.service | awk '{print $2 \" \" $3}'" -fu thermo.service | moins
DimanNe
Vous pouvez également utiliser systemctl show -p ActiveEnterTimestamp --value $unit, donc il n'y a pas besoin de awk supplémentaire
karlicoss
4

Vous pouvez utiliser l'indicateur de démarrage pour extraire uniquement les journaux de ce démarrage. par exemple

journalctl _SYSTEMD_UNIT=avahi-daemon.service -b 5
Nikolaidis Fotis
la source
2
C'est similaire à ce que je veux, mais cela ne fonctionne pas dans des situations telles que: 1) si la machine a été redémarrée depuis la dernière exécution du service, ou 2) si le service a été exécuté plusieurs fois depuis le dernier démarrage.
Jack O'Connor
Je ne sais pas pourquoi cela ne fonctionne pas pour le 1er cas. S'il a été redémarré, le sera redémarré également. Il vous suffit d'aller à ce démarrage spécifique et de récupérer vos informations. Concernant le second ... vous avez raison. Les journaux de bruit dépendent du nombre de fois que le service a été redémarré. Mais une fois que vous avez repéré votre pid de service, vous pouvez le filtrer en utilisant l'argument _PID = XXX. Les chances de réutiliser le même pid pour le même service sur le même cycle de démarrage sont ..... aucune idée ... mais plutôt quasi impossible.
Nikolaidis Fotis
Je suis intéressé à gérer des services qui ne s'exécutent pas nécessairement au démarrage, soit parce qu'ils sont sur des temporisateurs, soit parce que ce sont des commandes uniques.
Jack O'Connor
4

Cela pourrait vous aider:

  • journalctl -u foo.service | queue -n 2

    ou remplacez 2 par le nombre de lignes prévu

  • journalctl -u foo.service --since = ' 2016-04-11 13:00:00 '

Vous pouvez également les combiner pour obtenir d'abord l'horodatage de la dernière exécution, puis utiliser cet horodatage avec le commutateur --since.

Breign
la source
Cela ressemble à une solution de contournement similaire à l'approche PID, mais c'est très manuel. Si mon service s'exécute pendant plusieurs secondes et crache de nombreuses lignes de journal, je dois rechercher la première ligne qui a l'horodatage de départ qui me tient à cœur. Cela ne fonctionnera pas très bien dans un script.
Jack O'Connor
3

Vous pouvez utiliser des filtres de champ avec Journalctl. Par exemple

journalctl _PID=1234

Obtenez une liste de tous les champs disponibles en utilisant:

journalctl --fields --unit kubelet

Un champ disponible est _PID.

Vous pouvez obtenir le PID d'un processus en cours en utilisant pidofousystemctl show --property MainPID <SERVICE_NAME>

Voici donc comment obtenir les journaux du processus de kubelet Kubernetes actuel:

# journalctl --unit kubelet _PID=$(systemctl show --property MainPID kubelet 2>/dev/null | cut -d= -f2) | head

Maintenant, dites-moi pourquoi je Kubernetes est si difficile à installer :-(

richardw
la source
0

journalctl -r | grep -m1 foo.service

nieman
la source
1
Bienvenue sur ServerFault. Pouvez-vous expliquer en quoi cela est meilleur ou différent des autres réponses qui étaient déjà là? serverfault.com/help/how-to-answer
poussins