Jouer avec jq, json, ndjson
Jouons avec un flux ndjson
qu'on parsera et filtrera avec l'outil jq
.
Prenons un fichier de log log.ndjson
ressemblant à ceci :
1{"ts":"2023-09-12T10:58:11+02:00","src":"hostname.example","app":"default-app","lvl":"INFO","msg":"DEBUT"}
2{"ts":"2023-09-12T11:58:11+02:00","src":"hostname.example","app":"default-app","lvl":"DEBUG","msg":{"obj":12,"prop":false,"items":[1,2,3,4]}}
3{"ts":"2023-09-12T11:58:11+02:00","src":"hostname.example","app":"default-app","lvl":"ERROR","msg":"Erreur !!"}
4{"ts":"2023-09-12T12:58:11+02:00","src":"hostname.example","app":"default-app","lvl":"INFO","msg":"FIN"}
Une ligne correspond à une chaine json. à l'intérieur du json les champs suivants sont obligatoires :
ts
= horodatage au format ISO 8601 (date + heure locale + offset du fuseau horaire)src
= hostname de la machine productrice du logapp
= identification de l'applicationlvl
= niveau de sévérité :SUCCESS
|INFO
|WARNING
|ERROR
|DEBUG
msg
= le message non structuré (dans le sens non indexable), qui peut être une chaîne de caractère, un type scalaire, un tableau ou objet json
Pour parser l'ensemble du fichier avec jq
on utilise --slurp
qui empaquête le ndjson
dans un tableau json
qu'il peut traiter / indenter / coloriser :
1$ jq --slurp . log.ndjson
2[
3 {
4 "ts": "2023-09-12T10:58:11+02:00",
5 "src": "hostname.example",
6 "app": "default-app",
7 "lvl": "INFO",
8 "msg": "DEBUT"
9 },
10 {
11 "ts": 0
12 },
13 {
14 "sss": 12
15 }
16]
Si on veut filtrer une clé, par exemple remonter uniquement les erreurs
1$ jq --slurp 'map(select(.lvl == "ERROR"))' log.ndjson
2[
3 {
4 "ts": "2023-09-12T11:58:11+02:00",
5 "src": "hostname.example",
6 "app": "default-app",
7 "lvl": "ERROR",
8 "msg": "Erreur !!"
9 }
10]
Ou un filtre sur une date
1$ jq --arg tsStart '2023-09-12T11:00:00' --arg tsEnd '2023-09-12T12:00:00' --slurp 'map(select(.ts | . >= $tsStart and . <= $tsEnd))' log.ndjson
2[
3 {
4 "ts": "2023-09-12T11:58:11+02:00",
5 "src": "hostname.example",
6 "app": "default-app",
7 "lvl": "ERROR",
8 "msg": "Erreur !!"
9 }
10]
comments powered by Disqus