8 Configurazione di Elasticsearch

Zabbix può memorizzare i dati di cronologia in Elasticsearch come alternativa a un database relazionale.

Il supporto di Elasticsearch è attualmente sperimentale.

Questa guida descrive la configurazione per Elasticsearch 7.X. Se si utilizza una versione diversa, alcune funzionalità potrebbero non funzionare come previsto.

La configurazione prevede la creazione di una posizione di archiviazione Elasticsearch per ciascun tipo di valore, l'impostazione del preprocessing (se necessario) e la connessione di Zabbix alla propria istanza Elasticsearch.

Elasticsearch può memorizzare i seguenti tipi di valore:

Tipo di valore dell'item Tabella del database Tipo Elasticsearch
Numerico (senza segno) history_uint uint
Numerico (virgola mobile) history dbl
Carattere history_str str
Log history_log log
Testo history_text text
Binario history_bin non supportato da Zabbix
JSON history_json json

Note importanti

  • Elasticsearch richiede libcurl. Per i dettagli, vedere i requisiti.
  • L'housekeeper non elimina i dati da Elasticsearch.
  • Se tutti i dati di history sono archiviati in Elasticsearch, i trend non vengono calcolati né archiviati nel database. Valutare l'estensione del periodo di archiviazione della history.
  • Quando viene utilizzato Elasticsearch, le query di intervallo che recuperano valori dal database sono limitate dal timestamp del periodo di archiviazione dei dati.
  • Elasticsearch non è supportato per Zabbix proxy; utilizzare invece SQLite.

Se Elasticsearch non è ancora installato, fare riferimento alla guida ufficiale all'installazione prima di procedere.

Configurazione di Elasticsearch

Per memorizzare i dati di storico in Elasticsearch, è necessario:

  • Creare un indice per ogni tipo di valore che si desidera memorizzare: è qui che Elasticsearch archivia i dati, in modo simile a una tabella in un database relazionale.
  • Definire una mappatura per ogni indice: questa definisce la struttura dei dati, in modo simile allo schema di una tabella.
  • Configurare una pipeline di ingest per elaborare i valori prima della memorizzazione (necessaria per i valori JSON e per gli indici basati sulla data).

Elasticsearch può memorizzare i dati in un singolo indice per tipo di valore oppure in più indici basati sulla data. Entrambi gli approcci sono descritti di seguito.

Archiviazione della cronologia in un singolo indice

In questo approccio, tutti i dati di cronologia per un determinato tipo di valore vengono scritti in un singolo indice (ad esempio, uint o text).

Per creare un indice per il tipo di valore Numeric (unsigned), invia la seguente richiesta (con /uint nell'URL) alla tua istanza 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 risponderà con una conferma che l'indice è stato creato:

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

Richieste simili devono essere inviate per ogni ulteriore tipo di valore che si desidera memorizzare in Elasticsearch.

Le mappature per tutti i tipi di valore sono disponibili nel repository sorgente di Zabbix.

Ad esempio, per creare un indice per il tipo di valore Text:

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"
         }
      }
   }
}'
Tipo di valore JSON

A differenza degli altri tipi di valore, i valori JSON richiedono un'elaborazione aggiuntiva prima dell'archiviazione.

L'indice seguente utilizza campi separati per i valori analizzati e grezzi, quindi è necessaria una pipeline di ingest per analizzare ogni valore come JSON e memorizzarlo nel campo corretto.

Per creare un indice per il tipo di valore JSON, invia la seguente richiesta (con /json nell'URL) alla tua istanza 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 }
    }
  }
}'

Quindi, crea la pipeline di ingest:

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 risponderà con una conferma della creazione della pipeline di ingest:

{"acknowledged": true}

Memorizzazione della cronologia in indici basati sulla data

Invece di scrivere tutti i dati della cronologia in un singolo indice (ad esempio, uint), Elasticsearch può distribuire questi dati su più indici basati sulla data (ad esempio, uint-2026-01-01, uint-2026-01-02). Questo rende più semplice gestire il volume dei dati e la conservazione nel tempo.

Per abilitare questa funzionalità, è necessario:

  • Creare un template di indice per ogni tipo di valore che si desidera memorizzare: questo indica a Elasticsearch quale mapping applicare quando crea automaticamente un nuovo indice basato sulla data.
  • Creare una pipeline di ingest per ogni tipo di valore: elabora ogni valore in ingresso e lo instrada verso il corretto indice basato sulla data.
  • Configurare il parametro HistoryStorageDateIndex nel file di configurazione del server Zabbix: questo abilita la memorizzazione dei valori in più indici basati sulla data.
Template di indice

Per creare un template per l'indice text, invia una richiesta con i seguenti dettagli:

  • Usa _template/text_template nell'URL della tua istanza Elasticsearch.
  • Usa "text*" nel campo "index_patterns" per corrispondere al nome dell'indice.
  • Usa una mappatura per il tipo di valore text (vedi le mappature nel repository sorgente di 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"
         }
      }
   }
}'

Template per l'indice 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 }
      }
   }
}'
Pipeline di ingestione

Per creare una pipeline di ingestione per l'indice text:

  • Usa _ingest/pipeline/text-pipeline nell'URL della tua istanza Elasticsearch.
  • Includi un processore date_index_name per instradare ogni valore all'indice basato sulla data corretto in base al relativo timestamp.
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"
         }
      }
   ]
}'

Per l'indice json, la pipeline deve anche analizzare il valore JSON prima di instradarlo all'indice corretto:

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"
         }
      }
   ]
}'

Configurazione di Zabbix server

Nel file di configurazione di Zabbix server (zabbix_server.conf), impostare i seguenti parametri:

Ad esempio, per memorizzare in Elasticsearch i valori di tipo Character, Log, Text e JSON (mantenendo i valori Numeric in un database):

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

Se si utilizzano indici basati sulla data per tutti i valori memorizzati in Elasticsearch, impostare anche il parametro HistoryStorageDateIndex:

HistoryStorageDateIndex=1

Dopo aver apportato le modifiche, riavviare Zabbix server:

systemctl restart zabbix-server

Configurazione del frontend di Zabbix

Nel file di configurazione del frontend di Zabbix (zabbix.conf.php), dichiarare $HISTORY come variabile globale e impostare i valori url e types in modo che corrispondano alla configurazione del server:

// File di configurazione della GUI di Zabbix.
global $DB, $HISTORY;

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

Risoluzione dei problemi

I seguenti passaggi possono aiutarti a risolvere i problemi con la tua configurazione di Elasticsearch:

  1. Verifica che auto_create_index sia abilitato:
curl -X GET \
 "http://localhost:9200/_cluster/settings?include_defaults=true&filter_path=**.auto_create_index"

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

Per abilitarlo, invia la seguente richiesta:

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. Verifica che mapping, template e pipeline di ingest siano corretti inviando richieste GET ai rispettivi URL:
curl -X GET http://localhost:9200/json
curl -X GET http://localhost:9200/_template/json*
curl -X GET http://localhost:9200/_ingest/pipeline/json*

Puoi confrontare le risposte ricevute con quelle previste nella documentazione API di Elasticsearch.

  1. Controlla se alcuni shard si trovano in uno stato di errore; il riavvio di Elasticsearch potrebbe risolvere il problema.

  2. Verifica che la configurazione di Elasticsearch consenta l'accesso da Zabbix server e Zabbix frontend.

  3. Usa il parametro di configurazione di Zabbix server LogSlowQueries per identificare le query lente.

  4. Controlla i log di Elasticsearch per eventuali errori.

  5. Se devi reimpostare la tua configurazione di Elasticsearch e ricominciare da capo, puoi eliminare tutti gli indici, i template e le pipeline di ingest:

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