Checkmk
to checkmk.com
Important

This is a machine translation based on the English version of the article. It might or might not have already been subject to text preparation. If you find errors, please file a GitHub issue that states the paragraph that has to be improved.

1. Introduzione

I plug-in di controllo che funzionano con SNMP sono sviluppati in modo simile ai loro parenti basati su agenti. La differenza sta sia nel processo di scoperta del servizio che nel controllo stesso. Con i plug-in di controllo basati su agenti, il plug-in dell'agente viene utilizzato per determinare quali dati vengono inviati all'istanza Checkmk e spesso il pre-filtraggio (ma non la valutazione) avviene già sull'host. Al contrario, con SNMP devi specificare esattamente quali campi di dati ti servono e richiederli esplicitamente. Con SNMP, queste aree (rami di un albero) o i singoli campi di dati (foglie) sono identificati da OID (identificatori di oggetti).

In teoria sarebbe possibile trasferire tutti i dati (utilizzando la cosiddetta SNMP walk), ma anche con dispositivi veloci questo richiede minuti e con switch complessi può richiedere più di un'ora. Questo è quindi un problema già durante la ricerca e ancora di più durante la verifica stessa. In questo caso Checkmk adotta un approccio più mirato. Tuttavia, le SNMP walk sono disponibili in Checkmk per il debug dei controlli esistenti e per lo sviluppo dei tuoi controlli.

Se non hai ancora esperienza con SNMP, ti consigliamo di leggere l'articolo sul Monitoraggio via SNMP.

1.1. Cosa funziona diversamente in SNMP?

Rispetto a un plug-in di controllo per l'agente Checkmk, ci sono alcune caratteristiche speciali da notare con SNMP. Con un plug-in di controllo per SNMP, la scoperta del servizio è divisa in due fasi.

In una prima fase, viene utilizzata la funzione di rilevamento SNMP per individuare il dispositivo. Questo serve a determinare se il plug-in di controllo è di interesse per il rispettivo dispositivo e viene effettuato per ogni dispositivo monitorato tramite SNMP. A questo scopo, vengono recuperati alcuni OID, singoli, senza una passeggiata SNMP. Il più importante di questi è il sysDescr (OID: 1.3.6.1.2.1.1.1.0). Sotto questo OID, ogni dispositivo SNMP fornisce una descrizione di se stesso, ad esempio Flintstones, Inc. Fred Router rev23.

Nella seconda fase, per ognuno di questi candidati vengono recuperati i dati di monitoraggio necessari utilizzando i walk SNMP. Questi vengono poi riassunti in una tabella e forniti alla funzione di scoperta del servizio del plug-in di controllo nell'argomento section, che determina gli elementi da monitorare. Per ognuno di questi elementi viene quindi generato un servizio.

Durante il controllo si sa già se il plug-in di controllo deve essere eseguito per il dispositivo e quindi non è necessario un nuovo rilevamento SNMP. I dati di monitoraggio attuali necessari per il plug-in vengono recuperati tramite walks SNMP.

Quindi cosa devi fare di diverso con un plug-in di controllo per SNMP rispetto a uno basato su agenti?

  1. Non hai bisogno di un plug-in dell'agente.

  2. Definisci gli OID necessari per il rilevamento SNMP e i testi che devono contenere.

  3. Decidi quali rami e foglie dell'albero SNMP devono essere recuperati per il monitoraggio.

1.2. Non aver paura delle MIB!

In questa breve introduzione vorremmo parlare delle famigerate MIB SNMP, su cui esistono molti pregiudizi. La buona notizia è che Checkmk non ha bisogno delle MIB! Tuttavia, possono essere un aiuto importante per lo sviluppo di un plug-in di controllo o per la risoluzione dei problemi dei plug-in di controllo esistenti.

Che cosa sono le MIB? MIB significa letteralmente Management Information Base, che contiene poche informazioni in più rispetto all'abbreviazione stessa. In pratica, una MIB è un file di testo leggibile dall'uomo che descrive i rami e le foglie di un albero di dati SNMP.

Gli OID possono identificare rami o foglie. La descrizione del ramo contiene informazioni sul sistema e sul sottosistema forniti dal ramo. Se un OID fa riferimento a una foglia, le informazioni del MIB contengono informazioni sul tipo di dati (stringa di caratteri, numero a virgola fissa, stringa esadecimale, ...), sull'intervallo di valori e sulla rappresentazione. Ad esempio, le temperature possono essere archiviate come un numero a virgola fissa con segno sulla scala Celsius con una risoluzione di 0,1° o senza segno in passi di 1,0° sulla scala Kelvin.

Checkmk mette a disposizione una serie di file MIB liberamente accessibili. Questi descrivono campi molto generali nell'albero OID globale, ma non contengono campi specifici per i manufatturieri. Pertanto non sono di grande aiuto per i plug-in di controllo sviluppati autonomamente.

Cerca quindi di trovare i file MIB rilevanti per il tuo dispositivo specifico da qualche parte sul sito web del produttore o anche sull'interfaccia di gestione del dispositivo. Installa questi file nell'istanza Checkmk nella directory ~/local/share/snmp/mibs/. Potrai così tradurre i numeri OID in nomi utilizzando i percorsi SNMP e trovare più rapidamente i dati di interesse ai fini del monitoraggio. Come già accennato, le MIB ben curate contengono anche informazioni interessanti nei loro commenti. Puoi visualizzare facilmente un file MIB con un editor di testo o con il pager less.

2. Trovare gli OID corretti

Il prerequisito fondamentale per sviluppare un plug-in di controllo basato su SNMP è sapere quali OID contengono le informazioni rilevanti. Per lo scenario di esempio presentato, abbiamo ipotizzato che tu abbia appena commissionato un lotto di router del tipo Flintstones, Inc. Fred Router rev23. Spesso ti imbatterai in questo dispositivo fittizio nella documentazione del produttore e nei commenti MIB. Tuttavia, hai dimenticato di inserire le informazioni di contatto e di localizzazione di alcuni dispositivi. Un plug-in di controllo scritto da te per Checkmk dovrebbe aiutarti a identificare questi dispositivi.

Tip

L'esempio di plug-in che abbiamo preparato è scritto in modo tale da poter essere eseguito con quasi tutti i dispositivi SNMP. Devi solo adattare la stringa di caratteri da confrontare. Se non hai un dispositivo a portata di mano, troverai varie opzioni di simulazione nel capitolo sulla Risoluzione dei problemi.

Il primo passo consiste nell'effettuare un'esplorazione SNMP completa. Ciò comporta il recupero di tutti i dati disponibili tramite SNMP. Questo può essere fatto in modo molto semplice con Checkmk. Per prima cosa, includi il dispositivo per il quale vuoi sviluppare un plug-in di controllo nel monitoraggio. Assicurati che possa essere monitorato nelle funzioni di base. Come minimo, devono essere trovati i servizi SNMP Info e Uptime e probabilmente anche almeno uno Interface.Questo assicurerà che l'accesso SNMP funzioni correttamente.

Passa quindi alla riga di comando dell'istanza Checkmk, dove potrai eseguire una ricerca completa con il seguente comando - nell'esempio seguente per il dispositivo con il nome host mydevice01. Ti consigliamo di utilizzare anche l'opzione -v (per verbose):

OMD[mysite]:~$ cmk -v --snmpwalk mydevice01
mydevice01:
Walk on ".1.3.6.1.2.1"...3898 variables.
Walk on ".1.3.6.1.4.1"...6025 variables.
Wrote fetched data to /omd/sites/mysite/var/check_mk/snmpwalks/mydevice01.

Come già accennato, una camminata SNMP completa può richiedere minuti o addirittura ore (anche se quest'ultimo caso è raro), quindi non innervosirti se ci vuole un po' di tempo per completarla. I risultati della camminata vengono salvati nel file ~/var/check_mk/snmpwalks/mydevice01. Si tratta di un file di testo di facile lettura che inizia così:

~/var/check_mk/snmpwalks/mydevice01
.1.3.6.1.2.1.1.1.0 Flintstones, Inc. Fred Router rev23
.1.3.6.1.2.1.1.2.0 .1.3.6.1.4.1.424242.2.3
.1.3.6.1.2.1.1.3.0 546522419
.1.3.6.1.2.1.1.4.0 barney@example.com
.1.3.6.1.2.1.1.5.0 big-router-01
.1.3.6.1.2.1.1.6.0 Server room 23, Stonestreet 52, Munich
.1.3.6.1.2.1.1.7.0 72
.1.3.6.1.2.1.1.8.0 0

Ogni riga contiene un OID e poi il suo valore. Il più importante si trova nella prima riga, ovvero sysDescr. Questo dovrebbe essere un identificatore unico per un modello di hardware.

Anche la seconda riga è interessante: al di sotto di 1.3.6.1.4.1 ci sono dei rami che i produttori di hardware possono assegnare loro stessi; in questo caso Flintstones, Inc. ha l'ID fittizio del produttore 424242. Al di sotto di questo, l'azienda ha assegnato 2 per i router e 3 per lo stesso modello. All'interno di questo ramo troverai poi degli OID specifici per i dispositivi.

Se sono installate le MIB corrette, puoi tradurle in nomi in un secondo passo. È meglio reindirizzare l'output del comando seguente, che altrimenti verrebbe visualizzato nel terminale, in un file:

OMD[mysite]:~$ cmk --snmptranslate mydevice01 > /tmp/translated

Una volta che questo file è stato translated si legge come la passeggiata originale, ma in più mostra il nome dell'OID in ogni riga dopo -->:

/tmp/translated
.1.3.6.1.2.1.1.1.0 Flintstones, Inc. Fred Router rev23 --> SNMPv2-MIB::sysDescr.0
.1.3.6.1.2.1.1.2.0 .1.3.6.1.4.1.424242.2.3 --> SNMPv2-MIB::sysObjectID.0
.1.3.6.1.2.1.1.3.0 546522419 --> DISMAN-EVENT-MIB::sysUpTimeInstance
.1.3.6.1.2.1.1.4.0 barney@example.com --> SNMPv2-MIB::sysContact.0
.1.3.6.1.2.1.1.5.0 big-router-01 --> SNMPv2-MIB::sysName.0
.1.3.6.1.2.1.1.6.0 Server room 23, Stonestreet 52, Munich --> SNMPv2-MIB::sysLocation.0
.1.3.6.1.2.1.1.7.0 42 --> SNMPv2-MIB::sysServices.0
.1.3.6.1.2.1.1.8.0 27 --> SNMPv2-MIB::sysORLastChange.0

Nell'output di cui sopra, ad esempio, l'OID 1.3.6.1.2.1.1.4.0 ha il valore barney@example.com e il nome SNMPv2-MIB::sysContact.0. Le informazioni aggiuntive che mostrano i nomi degli OID forniscono informazioni importanti per identificare gli OID di interesse. Per l'esempio presentato, gli OID da 1.3.6.1.2.1.1.4.0 a 1.3.6.1.2.1.1.6.0 sono sufficienti.

3. Scrivere un semplice plug-in di controllo

Hai completato il lavoro preparatorio: ora hai un elenco degli OID che vuoi leggere e valutare. Il compito ora è quello di utilizzare queste note per insegnare a Checkmk quali servizi vengono generati e quando devono passare a WARN o CRIT. La programmazione di un plug-in di controllo in Python utilizzata a questo scopo ha molte analogie con un plug-in di controllo basato su agenti. Poiché ci sono alcune sottigliezze da considerare, mostreremo la struttura completa con tutte le funzioni utilizzate.

3.1. Preparazione del file

Per i tuoi plug-in di controllo troverai la directory di base già pronta nella gerarchia local della directory del sito. Si tratta di ~/local/lib/python3/cmk_addons/plugins/. La directory appartiene all'utente dell'istanza e quindi è scrivibile per te.

In questa directory, i plug-in sono organizzati in famiglie di plug-in, i cui nomi del plug-in possono essere scelti liberamente. Ad esempio, tutti i plug-in relativi ai dispositivi Cisco sono archiviati nella cartella cisco - oppure tutti i plug-in relativi ai router del produttore Flintstones, Inc. sono archiviati nella cartella flintstone.

In questa sottocartella <plug-in_family>, vengono poi create altre sottocartelle con nomi predefiniti a seconda delle necessità per le varie API, ad es. agent_based per l'API Check dei plug-in dell'agente, compresi i plug-in di controllo basati su SNMP.

Crea le due sottodirectory per il nuovo plug-in di controllo e poi switcha su di esse per lavorare:

OMD[mysite]:~$ mkdir -p local/lib/python3/cmk_addons/plugins/flintstone/agent_based
OMD[mysite]:~$ cd local/lib/python3/cmk_addons/plugins/flintstone/agent_based

Crea qui il file flintstone_setup_check.py per il plug-in di controllo. La convenzione vuole che il nome del file rifletta il nome del plug-in di controllo così come è stato definito al momento della creazione del plug-in di controllo come istanza della classe CheckPlugin. È obbligatorio che il file finisca con .py, perché a partire dalla versione di Checkmk 2.0.0 i plug-in di controllo sono sempre veri e propri moduli Python.

Un framework di base eseguibile(scaricabile da GitHub), che verrà ampliato passo dopo passo nel seguito, ha il seguente aspetto:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
#!/usr/bin/env python3

from cmk.agent_based.v2 import (
    CheckPlugin,
    CheckResult,
    startswith,
    DiscoveryResult,
    Result,
    Service,
    SimpleSNMPSection,
    SNMPTree,
    State,
    StringTable,
)

def parse_flintstone(string_table):
    return {}

def discover_flintstone(section):
    yield Service()

def check_flintstone(section):
    yield Result(state=State.OK, summary="Everything is fine")

snmp_section_flintstone_setup = SimpleSNMPSection(
    name = "flintstone_base_config",
    parse_function = parse_flintstone,
    detect = startswith(".1.3.6.1.2.1.1.1.0", "Flintstone"),
    fetch = SNMPTree(base='.1.3.6.1.2.1.1', oids=['4.0']),
)

check_plugin__flintstone_setup = CheckPlugin(
    name = "flintstone_setup_check",
    sections = [ "flintstone_base_config" ],
    service_name = "Flintstone setup check",
    discovery_function = discover_flintstone,
    check_function = check_flintstone,
)

Per prima cosa dovrai importare le funzioni e le classi necessarie per i plug-in di controllo dai moduli Python. Ti sconsigliamo l'uso occasionale di import *, in quanto fa un uso inutile della memoria e oscura i namespace effettivamente disponibili. Per il nostro esempio, importeremo solo ciò che sarà necessario o potrà essere utile nel resto di questo articolo:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
from cmk.agent_based.v2 import (
    CheckPlugin,
    CheckResult,
    startswith,
    DiscoveryResult,
    Result,
    Service,
    SimpleSNMPSection,
    SNMPTree,
    State,
    StringTable,
)

Rispetto al plug-in di controllo basato sull'agente, spiccano le nuove funzioni e classi specifiche per SNMP: SNMPTree SimpleSNMPSection e startswith. SNMPTree è una classe per la visualizzazione degli alberi SNMP. La classe SimpleSNMPSection è utilizzata per creare una sezione SNMP. La funzione startswith() confronta il contenuto di una foglia SNMP con una stringa di caratteri. Maggiori informazioni in seguito.

3.2. Creare una sezione SNMP

Dopo aver identificato gli OID corretti, è il momento di sviluppare il plug-in di controllo. Quando crei la sezione SNMP, devi specificare due cose:

  1. Identifica i dispositivi per i quali deve essere eseguito il plug-in di controllo.
    Nell'esempio seguente, questo viene fatto con la funzione startswith(), che confronta una stringa di caratteri con l'inizio del contenuto di una foglia OID. Altre opzioni di assegnazione sono mostrate di seguito.

  2. Dichiara quali rami o foglie OID devono essere recuperati per il monitoraggio.
    Questo viene fatto con il costruttore della classe SNMPTree.

Estendi il file di esempio preparato in modo che il plug-in venga eseguito solo per un piccolo numero di dispositivi, in questo caso i modelli Flintstones, Inc. Fred Router. Per questi dispositivi vengono recuperati gli OID per il contatto, il nome del dispositivo e la posizione. Questi tre OID sono forniti da ogni dispositivo. Se vuoi testare l'esempio con dispositivi SNMP reali, è quindi sufficiente personalizzare il nome del modello da riconoscere.

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
snmp_section_flintstone_setup_check = SimpleSNMPSection(
    name = "flintstone_base_config",
    parse_function = parse_flintstone,
    detect = startswith(
        ".1.3.6.1.2.1.1.1.0",
        "Flintstones, Inc. Fred Router",
    ),
    fetch = SNMPTree(
        base = '.1.3.6.1.2.1.1',
        oids = ['4.0', '5.0', '6.0'],
    ),
)

L'esempio contiene anche il parametro name con cui viene identificata la sezione SNMP generata e una funzione di parsing, di cui parleremo più avanti.

Il rilevamento SNMP

Utilizza il parametro detect per specificare le condizioni in cui la funzione di ricerca deve essere eseguita. Nel nostro esempio, questo avviene se il valore dell'OID 1.3.6.1.2.1.1.1.0 (cioè sysDescr) inizia con il testo Flintstones, Inc. Fred Router (senza distinzione tra maiuscole e minuscole). Oltre a startswith, c'è tutta una serie di altre possibili funzioni per l'identificazione. Esiste anche un modulo negato di ognuna di esse, che inizia con not_. Nota che ogni funzione deve essere specificata separatamente nell'istruzione import.

Attributo Funzione Negazione

equals(oid, "needle")

Il valore dell'OID corrisponde al testo needle.

not_equals(oid, "needle")

contains(oid, "needle")

Il valore dell'OID contiene il testo needle in qualche punto.

not_contains(oid, "needle")

startswith(oid, "needle")

Il valore dell'OID inizia con il testo needle.

not_startswith(oid, "needle")

endswith(oid, "needle")

Il valore dell'OID termina con il testo needle.

not_endswith(oid, "needle")

matches(oid, regex)

Il valore dell'OID corrisponde all'espressione regolare regex, ancorata dopo e prima, cioè con una corrispondenza esatta. Se hai bisogno solo di una sottostringa, aggiungi semplicemente un .* all'inizio o alla fine.

not_matches(oid, regex).

exists(oid)

L'OID è disponibile sul dispositivo. Il suo valore può essere vuoto.

not_exists(oid)

Esiste anche la possibilità di collegare più attributi con all_of o any_of.

all_of L'esempio seguente assegna il plug-in di controllo a un dispositivo se il testo di sysDescr inizia con foo (o FOO o Foo) el'OID 1.3.6.1.2.1.1.2.0 contiene il testo .4.1.11863.:

detect = all_of(
    startswith(".1.3.6.1.2.1.1.1.0", "foo"),
    contains(".1.3.6.1.2.1.1.2.0", ".4.1.11863.")
)

Al contrario, any_of è soddisfatto se solo uno dei criteri è stato soddisfatto. Ecco un esempio in cui sono ammessi diversi valori per sysDescr:

detect = any_of(
    startswith(".1.3.6.1.2.1.1.1.0", "foo version 3 system"),
    startswith(".1.3.6.1.2.1.1.1.0", "foo version 4 system"),
    startswith(".1.3.6.1.2.1.1.1.0", "foo version 4.1 system"),
)

A proposito: Se hai familiarità con le espressioni regolari, probabilmente potresti semplificare questo esempio e cavartela con una sola riga:

detect = matches(".1.3.6.1.2.1.1.1.0", "FOO Version (3|4|4.1) .*")

Un'altra nota importante: gli OID che passi al rilevamento SNMP per un plug-in di controllo vengono recuperati da ogni dispositivo monitorato tramite SNMP. Questo è l'unico modo in cui Checkmk può determinare a quali dispositivi deve essere applicato il plug-in di controllo.

Per questo motivo, devi prestare molta attenzione all'utilizzo di OID specifici del produttore. Cerca di progettare il tuo rilevamento SNMP in modo da dare priorità al controllo dei dispositivi sysDescr (1.3.6.1.2.1.1.1.0) e sysObjectID (1.3.6.1.2.1.1.2.0).

Se hai bisogno di un OID diverso per l'identificazione esatta, usa all_of() e procedi come segue:

  1. Prima verifica la presenza di sysDescr o sysObjectID.

  2. Con ulteriori argomenti, puoi restringere ulteriormente il gruppo di dispositivi per i quali il plug-in deve essere eseguito.

detect = all_of(
    startswith(".1.3.6.1.2.1.1.1.0", "Flintstone"),   # first check sysDescr
    contains(".1.3.6.1.4.1.424242.2.3.37.0", "foo"),  # fetch vendor specific OID
)

Questo funziona grazie al principio della valutazione pigra: non appena uno dei controlli precedenti fallisce, non vengono eseguiti altri controlli. Nell'esempio precedente, l'OID 1.3.6.1.4.1.424242.2.3.37.0 viene recuperato solo dai dispositivi che hanno anche Flintstone nel loro sysDescr.

3.3. Scrivere la funzione di parsing

Come per i plug-in basati su agenti, anche la funzione di parse del plug-in di controllo basato su SNMP ha il compito di convertire i dati ricevuti dall'agente in un modulo che possa essere processato facilmente e, soprattutto, con prestazioni elevate.

Anche qui ricevi i dati sotto forma di elenco. Tuttavia, ci sono alcune sottigliezze da considerare, poiché fa differenza se stai interrogando le foglie o i rami. Come promemoria, nel nostro esempio precedente vengono richieste le foglie:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
    fetch = SNMPTree(
        base = '.1.3.6.1.2.1.1',
        oids = ['4.0', '5.0', '6.0'],
    )

Se estendi temporaneamente la funzione parse con la funzione print(), puoi visualizzare i dati che Checkmk fornisce da questa query durante il test del plug-in di controllo:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def parse_flintstone(string_table):
    print(string_table)
    return {}

Riceverai un elenco annidato che contiene un solo elemento nel suo primo livello, ovvero l'elenco dei valori recuperati:

[
    ['barney@example.com', 'big-router-01', 'Server room 23, Stonestreet 52, Munich']
]

Il risultato è leggermente diverso se si recuperano rami che contengono più foglie. Supponiamo che il router possa essere dotato di un numero variabile di schede di rete il cui nome, stato di connessione e velocità possono essere letti sotto 1.3.6.1.4.1.424242.2.3.23...

    fetch = SNMPTree(
        base = '.1.3.6.1.4.1.424242.2.3.23',
        oids = [
            '6', # all names
            '7', # all states
            '8', # all speeds
        ],
    )

... allora l'elenco bidimensionale potrebbe avere il seguente aspetto:

[
    # Name, State, Speed
    ['net0', '1', '1000'],
    ['net1', '0', '100'],
    ['net2', '1', '10000'],
    ['net3', '1', '1000'],
]

Tutte le foglie disponibili sotto un OID vengono scritte in una colonna della tabella. Dovrebbe quindi essere ovvio che, ai fini della visualizzazione dei dati, possono essere interrogati solo gli OID corrispondenti.

Tip

L'ultimo esempio mostrato per recuperare i rami OID è anche una parte del nostro percorso SNMP fornito su GitHub, che puoi utilizzare per le simulazioni.

Ma ora torniamo all'esempio in cui vengono interrogati i rami OID per contatto, nome del dispositivo e posizione: la seguente funzione di parse copia semplicemente ogni elemento dell'elenco interno in una coppia chiave-valore nel dizionario restituito:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def parse_flintstone(string_table):
    # print(string_table)
    result = {}
    result["contact"] = string_table[0][0]
    result["name"] = string_table[0][1]
    result["location"] = string_table[0][2]
    # print(result)
    return result

Il risultato della funzione di parsing sarà quindi simile a questo:

{
    'contact': 'barney@example.com',
    'name': 'big-router-01',
    'location': 'Server room 23, Stonestreet 52, Munich'
}

3.4. Creare il plug-in di controllo

Un plug-in di controllo viene creato esattamente come descritto nella sezione plug-in dell'agente.

Poiché nella maggior parte dei casi verranno interrogati diversi rami SNMP e questo darà luogo a diverse sezioni SNMP, di solito è richiesto il parametro sections con l'elenco delle sezioni da valutare:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
check_plugin__flintstone_setup = CheckPlugin(
    name = "flintstone_setup_check",
    sections = [ "flintstone_base_config" ],
    service_name = "Flintstone setup check",
    discovery_function = discover_flintstone,
    check_function = check_flintstone,
)

3.5. Scrivere la funzione di ricerca

Anche la funzione di ricerca corrisponde all'esempio per i plug-in dell'agente di controllo. Per i plug-in di controllo che generano solo un servizio per host, è sufficiente un singolo yield():

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def discover_flintstone(section):
    yield Service()

3.6. Scrivere la funzione di controllo

Nell'esempio, vogliamo verificare se le informazioni sul contatto, sul nome del dispositivo e sulla posizione sono disponibili. È quindi sufficiente controllare quali campi sono vuoti nella funzione di controllo e di conseguenza impostare lo stato su CRIT (se manca qualcosa) o su OK (se tutto è disponibile):

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def check_flintstone(section):
    missing = 0
    for e in ["contact", "name", "location"]:
        if section[e] == "":
            missing += 1
            yield Result(state=State.CRIT, summary=f"Missing information: {e}!")
    if missing > 0:
        yield Result(state=State.CRIT, summary=f"Missing fields: {missing}!")
    else:
        yield Result(state=State.OK, summary="All required information is available.")

Una volta creata la funzione di controllo, il plug-in di controllo sarà pronto per essere utilizzato.

Abbiamo reso disponibile il plug-in di controllo completo su GitHub.

3.7. Test e attivazione del plug-in di controllo

Il test e l'attivazione avvengono come per i plug-in dell'agente.

Il primo passo è la scoperta del servizio per il plug-in:

OMD[mysite]:~$ cmk -vI --detect-plugins=flintstone_setup_check mydevice01
Discovering services and host labels on: mydevice01
mydevice01:
+ FETCHING DATA
No piggyback files for 'mydevice01'. Skip processing.
No piggyback files for '127.0.0.1'. Skip processing.
Get piggybacked data
+ ANALYSE DISCOVERED HOST LABELS
SUCCESS - Found no new host labels
+ ANALYSE DISCOVERED SERVICES
+ EXECUTING DISCOVERY PLUGINS (1)
  1 flintstone_setup_check
SUCCESS - Found 1 services

Come previsto, la scoperta del servizio è andata a buon fine. Ora puoi testare il controllo contenuto nel plug-in di controllo:

OMD[mysite]:~$ cmk -v --detect-plugins=flintstone_setup_check mydevice01
+ FETCHING DATA
No piggyback files for 'mydevice01'. Skip processing.
No piggyback files for '127.0.0.1'. Skip processing.
Get piggybacked data
Flintstone setup check All required information is available.
No piggyback files for 'mydevice01'. Skip processing.
No piggyback files for '127.0.0.1'. Skip processing.
[snmp] Success, [piggyback] Success ...

Dopo aver riavviato il nucleo di monitoraggio...

OMD[mysite]:~$ cmk -R
Generating configuration for core (type nagios)...
Precompiling host checks...OK
Validating Nagios configuration...OK
Restarting monitoring core...OK

... il nuovo servizio sarà visibile nel monitoraggio:

The new service created by the check plug-in in the monitoring.
Poiché tutti i campi dei tre fogli SNMP sono riempiti, il servizio è OK.

4. Risoluzione dei problemi

Poiché la risoluzione dei problemi nei plug-in di controllo basati su agenti si applica essenzialmente anche ai plug-in di controllo basati su SNMP, in questa sede ci occuperemo solo delle specifiche SNMP.

4.1. Opzioni di simulazione

Usare i percorsi SNMP salvati in Checkmk

Nell'articolo sul monitoraggio via SNMP abbiamo mostrato in dettaglio come puoi creare dei walk SNMP dall'interfaccia grafica e come puoi usarli per la simulazione. Questo permette anche di sviluppare plug-in di controllo su sistemi di test che non possono accedere agli host SNMP per i quali stai sviluppando un plug-in. Nel nostro repository GitHub troverai un esempio di walk SNMP, che usiamo in questo articolo e che puoi usare per sviluppare e testare il plug-in di controllo.

Il demone SNMP fittizio

Se vuoi assicurarti che determinati OID cambino a seconda degli altri, può essere utile programmare un demone SNMP fittizio che fornisca dati coerenti. Il modulo Python snmp-agent può essere un aiuto per programmare questo demone fittizio.

4.2. Hardware non cooperativo

Prima di poter monitorare un dispositivo con un nuovo plug-in di controllo basato su SNMP, è necessario che sia in grado di essere monitorato tramite SNMP. Per questo motivo, puoi trovare una panoramica dei problemi noti con le soluzioni suggerite nell'articolo sul Monitoraggio tramite SNMP.

5. File e directory

Percorso del file Descrizione

~/local/lib/python3/cmk_addons/plugins/

Directory di base per la memorizzazione dei file dei plug-in.

~/local/lib/python3/cmk_addons/plugins/<plug-in_family>/agent_based/

Luogo di archiviazione dei plug-in di controllo scritti secondo la Check API V2.

~/local/share/snmp/mibs/

Memorizza qui i file MIB SNMP che devono essere caricati automaticamente.

In questa pagina