Bonjour à toutes et à tous,

Je maintiens un script de vérification de fonctionnalités étalé sur plusieurs serveurs remplissant des fonctions diverses. Une famille de serveurs (une douzaine) exposent via une api un retour JSON sur l'état de leurs composants (topics Kafka et consommateurs)

Chaque serveur exécute une série de topics (TOPIC_x), et pour chacun d'entre eux des consommateurs sont assignés (worker-TOPIX_x-n) auquel s'ajoute leur état ([RUNNING], [TERMINATED] ou [FAILED])

La structure du retour json est la suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
{
  "status": "UP",
  "components": {
    "workersHealth": {
      "status": "UP",
      "details": {
        "TOPIC_A": [
          "worker-TOPIC_A-0 [RUNNING]"
        ],
        "TOPIC_B": [
          "worker-TOPIC_B-0 [RUNNING]",
          "worker-TOPIC_B-1 [RUNNING]",
          "worker-TOPIC_B-2 [RUNNING]",
          "worker-TOPIC_B-3 [RUNNING]",
          "worker-TOPIC_B-4 [RUNNING]",
          "worker-TOPIC_B-5 [RUNNING]"
        ],
        "TOPIC_C": [
          "worker-TOPIC_C-0 [RUNNING]"
        ],
        "TOPIC_D": [
          "worker-TOPIC_D-0 [RUNNING]"
        ],
        "TOPIC_E": [
          "worker-TOPIC_E-0 [RUNNING]",
          "worker-TOPIC_E-1 [RUNNING]",
          "worker-TOPIC_E-2 [RUNNING]"
        ],
        "TOPIC_F": [
          "worker-TOPIC_F-0 [RUNNING]"
        ],
        "TOPIC_G": [
          "worker-TOPIC_G-0 [RUNNING]"
        ],
        "TOPIC_H": [
          "worker-TOPIC_H-0 [TERMINATED]"
        ],
        "TOPIC_I": [
          "worker-TOPIC_I-0 [RUNNING]",
          "worker-TOPIC_I-1 [FAILED]",
          "worker-TOPIC_I-2 [RUNNING]",
          "worker-TOPIC_I-3 [RUNNING]",
          "worker-TOPIC_I-4 [RUNNING]",
          "worker-TOPIC_I-5 [RUNNING]"
        ],
        "TOPIC_J": [
          "worker-TOPIC_J-0 [RUNNING]"
        ],
        "TOPIC_K": [
          "worker-TOPIC_K-0 [RUNNING]",
          "worker-TOPIC_K-1 [RUNNING]",
          "worker-TOPIC_K-2 [RUNNING]"
        ],
        "TOPIC_L": [
          "worker-TOPIC_L-0 [RUNNING]"
        ],
        "TOPIC_M": [
          "worker-TOPIC_M-0[RUNNING]",
          "worker-TOPIC_M-1[RUNNING]",
          "worker-TOPIC_M-2[RUNNING]"
        ]
      }
    }
  }
}
Actuellement, je suis capable de boucler pour ma douzaine de serveurs et faire pour chacun d'entre eux un curl suivi d'un jq puis un egrep pour ne récupérer que la partie qui m'intéresse (c'est à dire pointer tous les workers qui ont une valeur FAILED ou TERMINATED afin que la personne qui fasse le contrôle effectue les actions nécessaires à leur correction).

Cela prend la forme suivante, plutôt crados (histoire d'avoir une v0 qui fonctionne rapidement) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
TESTWORKER = $(curl -sm 3000 "https://${SERVEUR}/${URL_HEALTH}" | jq -r .components.workersHealth.details | egrep 'FAILED|TERMINATED')
Le retour ressemble actuellement à ça :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "worker-TOPIC_A-0 [FAILED]"
Sauf que maintenant j'aimerais faire un truc un peu plus propre, surtout quand je vois la puissance de jq :

  • Pour des raisons de lisibilité, je ne veux pas remonter la valeur complète de l'array (donc le consumer), mais plutôt le nom du topic contenant des consommateurs satisfaisant aux critères FAILED ou TERMINATED. Donc je sais déjà que je veux terminer ma commande par un | keys[]
  • Mon idée c'est d'utiliser select avec un contains, mais pour l'instant tout ce que récupère, c'est un "jq: error: array and string cannot have their containment checked"


Actuellement ma commande juste pour afficher les noms des arrays dont une valeur contient "FAILED" ou "TERMINATED" est la suivante (je ne cherche pas à compter) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
jq -r 'select(.components.workersHealth.details[] | contains ("TERMINATED") or contains ("FAILED"))| keys[]'
Je m'attends à avoir un retour (avec l'exemple ci-dessus) :


Ma difficulté par rapport aux exemples que je trouve à droite à gauche sur les internets, c'est que la plupart des recherches dans des arrays portent sur des objets (donc "array1":["property": "value"]) ou bien spécifient une valeur exacte.

Je vous remercie par avance pour votre aide et conseils
Cordialement