8 Configuration d'Elasticsearch

Zabbix peut stocker les données d'historique dans Elasticsearch comme alternative à une base de données relationnelle.

La prise en charge d'Elasticsearch est actuellement expérimentale.

Ce guide couvre la configuration d'Elasticsearch 7.X. Si vous utilisez une autre version, certaines fonctionnalités peuvent ne pas fonctionner comme prévu.

La configuration implique la création d'un emplacement de stockage Elasticsearch pour chaque type de valeur, la mise en place du prétraitement (si nécessaire) et la connexion de Zabbix à votre instance Elasticsearch.

Elasticsearch peut stocker les types de valeurs suivants :

Type de valeur de l'élément Table de base de données Type Elasticsearch
Numérique (non signé) history_uint uint
Numérique (virgule flottante) history dbl
Caractère history_str str
Journal history_log log
Texte history_text text
Binaire history_bin non pris en charge par Zabbix
JSON history_json json

Remarques importantes

  • Elasticsearch nécessite libcurl. Voir les prérequis pour plus de détails.
  • Le housekeeper ne supprime pas les données d'Elasticsearch.
  • Si toutes les données d'historique sont stockées dans Elasticsearch, les tendances ne sont pas calculées ni stockées dans la base de données. Envisagez d'étendre la période de conservation de l'historique.
  • Lorsque Elasticsearch est utilisé, les requêtes de plage récupérant des valeurs depuis la base de données sont limitées par l'horodatage de la période de stockage des données.
  • Elasticsearch n'est pas pris en charge pour Zabbix proxy ; veuillez utiliser SQLite à la place.

Si Elasticsearch n'est pas encore installé, consultez le guide d'installation officiel avant de continuer.

Configuration d'Elasticsearch

Pour stocker les données d'historique dans Elasticsearch, vous devez :

  • Créer un index pour chaque type de valeur que vous souhaitez stocker — c'est là qu'Elasticsearch stocke les données, de manière similaire à une table dans une base de données relationnelle.
  • Définir un mapping pour chaque index — cela définit la structure des données, de manière similaire au schéma d'une table.
  • Configurer un pipeline d'ingestion pour traiter les valeurs avant leur stockage (requis pour les valeurs JSON et les index basés sur des dates).

Elasticsearch peut stocker les données dans un seul index par type de valeur, ou dans plusieurs index basés sur des dates. Les deux approches sont décrites ci-dessous.

Stockage de l'historique dans un seul index

Dans cette approche, toutes les données d'historique pour un type de valeur donné sont écrites dans un seul index (par exemple, uint ou text).

Pour créer un index pour le type de valeur Numérique (non signé), envoyez la requête suivante (avec /uint dans l'URL) à votre instance Elasticsearch :

curl -X PUT \
 http://localhost:9200/uint \
 -H 'content-type:application/json' \
 -d '{
     "settings": {
      "index": {
         "number_of_replicas": 1,
         "number_of_shards": 5
      }
   },
   "mappings": {
      "properties": {
         "itemid": { "type": "long" },
         "clock": { "format": "epoch_second", "type": "date" },
         "value": { "type": "long" }
      }
   }
}'

Elasticsearch répondra avec une confirmation indiquant que l'index a été créé :

{"acknowledged": true, "shards_acknowledged": true, "index": "uint"}

Des requêtes similaires doivent être envoyées pour chaque type de valeur supplémentaire que vous souhaitez stocker dans Elasticsearch.

Les mappings pour tous les types de valeur sont disponibles dans le dépôt source de Zabbix.

Par exemple, pour créer un index pour le type de valeur Texte :

curl -X PUT \
 http://localhost:9200/text \
 -H 'content-type:application/json' \
 -d '{
   "settings": {
      "index": {
         "number_of_replicas": 1,
         "number_of_shards": 5
      }
   },
   "mappings": {
      "properties": {
         "itemid": { "type": "long" },
         "clock": { "format": "epoch_second", "type": "date" },
         "value": {
            "fields": {
               "analyzed": { "index": true, "type": "text", "analyzer": "standard" }
            },
            "index": false,
            "type": "text"
         }
      }
   }
}'
Type de valeur JSON

Contrairement aux autres types de valeur, les valeurs JSON nécessitent un traitement supplémentaire avant le stockage.

L’index ci-dessous utilise des champs distincts pour les valeurs analysées et brutes ; un pipeline d’ingestion est donc nécessaire pour analyser chaque valeur en tant que JSON et la stocker dans le champ approprié.

Pour créer un index pour le type de valeur JSON, envoyez la requête suivante (avec /json dans l’URL) à votre instance Elasticsearch.

curl -X PUT \
 http://localhost:9200/json \
 -H 'content-type:application/json' \
 -d '{
   "settings": {
      "number_of_shards": 5,
      "number_of_replicas": 1
   },
   "mappings": {
      "dynamic": false,
      "properties": {
         "itemid": { "type": "long" },
         "clock": { "type": "date", "format": "epoch_second" },
         "ns": { "type": "long" },
         "value_parsed": { "type": "flattened" },
         "value_raw": { "type": "keyword", "ignore_above": 1000000 }
    }
  }
}'

Créez ensuite le pipeline d’ingestion :

curl -X PUT \
 http://localhost:9200/_ingest/pipeline/json \
 -H 'content-type:application/json' \
 -d '{
   "processors": [
      {
         "json": {
            "field": "value",
            "target_field": "value_parsed",
            "ignore_failure": true
         }
      },
      {
         "set": {
            "if": "ctx.value_parsed == null",
            "field": "value_raw",
            "value": "{{{ value }}}"
         }
      }
   ],
   "on_failure": [
      {
         "set": {
            "field": "value_raw",
            "value": "{{{ value }}}"
         }
      }
   ]
}'

Elasticsearch répondra par une confirmation indiquant que le pipeline d’ingestion a été créé :

{"acknowledged": true}

Stockage de l’historique dans des index basés sur la date

Au lieu d’écrire toutes les données d’historique dans un seul index (par exemple, uint), Elasticsearch peut répartir ces données entre plusieurs index basés sur la date (par exemple, uint-2026-01-01, uint-2026-01-02). Cela facilite la gestion du volume de données et de leur rétention au fil du temps.

Pour activer cela, vous devez :

  • Créer un modèle d’index pour chaque type de valeur que vous souhaitez stocker — cela indique à Elasticsearch quel mapping appliquer lorsqu’il crée automatiquement un nouvel index basé sur la date.
  • Créer un pipeline d’ingestion pour chaque type de valeur — il traite chaque valeur entrante et l’achemine vers l’index basé sur la date approprié.
  • Configurer le paramètre HistoryStorageDateIndex dans le fichier de configuration du serveur Zabbix — cela active le stockage des valeurs dans plusieurs index basés sur la date.
Modèles d’index

Pour créer un modèle pour l’index text, envoyez une requête avec les détails suivants :

  • Utilisez _template/text_template dans l’URL de votre instance Elasticsearch.
  • Utilisez "text*" dans le champ "index_patterns" pour faire correspondre le nom de l’index.
  • Utilisez un mapping pour le type de valeur text (voir les mappings dans le dépôt source de Zabbix).
curl -X PUT \
 http://localhost:9200/_template/text_template \
 -H 'content-type:application/json' \
 -d '{
   "index_patterns": [ "text*" ],
   "settings": {
      "index": {
         "number_of_replicas": 1,
         "number_of_shards": 5
      }
   },
   "mappings": {
      "properties": {
         "itemid": { "type": "long" },
         "clock": { "format": "epoch_second", "type": "date" },
         "value": {
            "fields": {
               "analyzed": { "index": true, "type": "text", "analyzer": "standard" }
            },
            "index": false,
            "type": "text"
         }
      }
   }
}'

Modèle pour l’index json :

curl -X PUT \
 http://localhost:9200/_template/json_template \
 -H 'content-type:application/json' \
 -d '{
   "index_patterns": [ "json*" ],
   "settings": {
      "number_of_shards": 5,
      "number_of_replicas": 1
   },
   "mappings": {
      "dynamic": false,
      "properties": {
         "itemid": { "type": "long" },
         "clock": { "type": "date", "format": "epoch_second" },
         "ns": { "type": "long" },
         "value_parsed": { "type": "flattened" },
         "value_raw": { "type": "keyword", "ignore_above": 1000000 }
      }
   }
}'
Pipelines d’ingestion

Pour créer un pipeline d’ingestion pour l’index text :

  • Utilisez _ingest/pipeline/text-pipeline dans l’URL de votre instance Elasticsearch.
  • Incluez un processeur date_index_name pour acheminer chaque valeur vers l’index basé sur la date correct en fonction de son horodatage.
curl -X PUT \
 http://localhost:9200/_ingest/pipeline/text-pipeline \
 -H 'content-type:application/json' \
 -d '{
   "description": "daily text index naming",
   "processors": [
      {
         "date_index_name": {
            "field": "clock",
            "date_formats": ["UNIX"],
            "index_name_prefix": "text-",
            "date_rounding": "d"
         }
      }
   ]
}'

Pour l’index json, le pipeline doit également analyser la valeur JSON avant de l’acheminer vers l’index correct :

curl -X PUT \
 http://localhost:9200/_ingest/pipeline/json-pipeline \
 -H 'content-type:application/json' \
 -d '{
   "description": "daily json index naming"
   "processors": [
      {
         "json": {
            "field": "value",
            "target_field": "value_parsed",
            "ignore_failure": true
         }
      },
      {
         "script": {
            "source": "if (ctx.value_parsed == null || !(ctx.value_parsed instanceof Map)) { ctx.value_raw = ctx.value; ctx.remove(\"value_parsed\"); }"
         }
      },
      {
         "date_index_name": {
            "field": "clock",
            "date_formats": [ "UNIX" ],
            "index_name_prefix": "json-",
            "date_rounding": "d"
         }
      }
   ]
}'

Configuration du serveur Zabbix

Dans votre fichier de configuration du serveur Zabbix (zabbix_server.conf), définissez les paramètres suivants :

Par exemple, pour stocker dans Elasticsearch les valeurs de type Character, Log, Text et JSON (tout en conservant les valeurs Numeric dans une base de données) :

HistoryStorageURL=http://localhost:9200
HistoryStorageTypes=str,log,text,json

Si vous utilisez des index basés sur la date pour toutes les valeurs stockées dans Elasticsearch, définissez également le paramètre HistoryStorageDateIndex :

HistoryStorageDateIndex=1

Après avoir effectué les modifications, redémarrez le serveur Zabbix :

systemctl restart zabbix-server

Configuration de l’interface web Zabbix

Dans votre fichier de configuration de l’interface web Zabbix (zabbix.conf.php), déclarez $HISTORY comme variable globale et définissez ses valeurs url et types afin qu’elles correspondent à la configuration du serveur :

// Zabbix GUI configuration file.
global $DB, $HISTORY;

$HISTORY['url']   = 'http://localhost:9200';
$HISTORY['types'] = ['str', 'log', 'text', 'json'];

Dépannage

Les étapes suivantes peuvent vous aider à résoudre les problèmes liés à votre configuration Elasticsearch :

  1. Vérifiez que auto_create_index est activé :
curl -X GET \
 "http://localhost:9200/_cluster/settings?include_defaults=true&filter_path=**.auto_create_index"

# {"defaults": {"action": {"auto_create_index": "false"} } }

Pour l’activer, envoyez la requête suivante :

curl -X PUT \
 http://localhost:9200/_cluster/settings \
 -H 'content-type:application/json' \
 -d '{
   "persistent": {
      "action.auto_create_index": "true"
   }
}'

# {"acknowledged": true, "persistent": {"action": {"auto_create_index": "true"} }, "transient": {} }
  1. Vérifiez que les mappings, les modèles et les pipelines d’ingestion sont corrects en envoyant des requêtes GET à leurs URL respectives :
curl -X GET http://localhost:9200/json
curl -X GET http://localhost:9200/_template/json*
curl -X GET http://localhost:9200/_ingest/pipeline/json*

Vous pouvez comparer les réponses reçues avec les réponses attendues dans la documentation de l’API Elasticsearch.

  1. Vérifiez si des shards sont dans un état d’échec ; le redémarrage d’Elasticsearch peut résoudre ce problème.

  2. Vérifiez que votre configuration Elasticsearch autorise l’accès depuis Zabbix server et Zabbix frontend.

  3. Utilisez le paramètre de configuration du serveur Zabbix LogSlowQueries pour identifier les requêtes lentes.

  4. Vérifiez les journaux Elasticsearch pour détecter d’éventuelles erreurs.

  5. Si vous devez réinitialiser votre configuration Elasticsearch et repartir de zéro, vous pouvez supprimer tous les index, modèles et pipelines d’ingestion :

curl -X DELETE "http://localhost:9200/_all"
curl -X DELETE "http://localhost:9200/_template/*"
curl -X DELETE "http://localhost:9200/_ingest/pipeline/*"