![]() |
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
Un importante vantaggio di Checkmk rispetto ad altri sistemi di monitoraggio è il gran numero di plug-in di controllo ben curati che vengono forniti di serie. Affinché questi plug-in abbiano una qualità uniformemente alta, ci sono dei criteri standardizzati che ogni plug-in deve soddisfare.
Una nota importante riguardo ai criteri: non dare per scontato che tutti i plug-in forniti con Checkmk siano conformi a tutti gli standard attuali. Evita il copia e incolla: è più consigliabile orientare il tuo lavoro in base alle informazioni contenute in questo articolo.
Se stai sviluppando plug-in solo per uso personale, sei ovviamente libero di farlo e non sei vincolato ai nostri standard.
1.1. Qualità
Per i plug-in di controllo che sono componenti ufficiali di Checkmk, o che sono destinati a diventarlo, è richiesta una qualità superiore rispetto a quelli scritti "per uso personale". Questa aspettativa si applica sia alla loro qualità "esterna" (come viene vista dall'utente), sia alla loro qualità interna (leggibilità del codice, ecc.).
Ti invitiamo a codificare bene il plug-in e a rispettare gli standard più elevati che sei in grado di raggiungere.
1.2. Ambito di applicazione di un plug-in di controllo
Ogni plug-in di controllo deve includere almeno i seguenti componenti:
Il plug-in di controllo stesso.
Una pagina man.
I plug-in di controllo con parametri del check richiedono una definizione per il set di regole applicabile.
Definizioni metriche per i grafici e il Perf-O-Meter se il controllo produce dati metrici.
Una definizione per l'Agent bakery se è presente un plug-in dell'agente.
Una serie di esempi completi e diversificati degli output degli agenti, o rispettivamente delle passeggiate SNMP.
2. Convenzioni di denominazione
2.1. Controllare il nome del plug-in
La scelta del nome del plug-in è particolarmente importante perché questo nome non può essere modificato in un secondo momento.
Il nome del plug-in deve essere breve, sufficientemente esplicito e comprensibile. Esempio:
firewall_status
è un buon nome solo se il plug-in funziona per tutti o almeno per molti firewall.Un nome è composto da lettere minuscole e numeri. È consentito un trattino basso come separatore.
Le parole
status
ostate
non sono necessarie in un nome, poiché ovviamente ogni plug-in monitora uno stato. Lo stesso vale per la parola superfluacurrent
. Quindi, piuttosto chefoobar_current_temp_status
usa semplicementefoobar_temp
.I plug-in di controllo in cui l'elemento rappresenta un oggetto fisico (es. ventola, alimentatore) dovrebbero avere un nome al singolare- ad esempio,
casa_fan
,oracle_tablespace
. I plug-in di controllo in cui ogni elemento si riferisce a un numero o a multipli dovrebbero avere un nome al plurale - ad esempio,user_logins
,printer_pages
.I plug-in di controllo specifici per i prodotti devono essere preceduti dal nome del prodotto - es.
oracle_tablespace
.I plug-in di controllo specifici per il produttore che non si applicano a un prodotto specifico devono essere preceduti dall'abbreviazione del produttore - es.
fsc_
per Fujitsu Siemens Computers.I plug-in di controllo basati su SNMP che utilizzano un componente comune della MIB che potrebbe essere supportato da più di un produttore dovrebbero essere denominati con il nome della MIB, piuttosto che con quello di un produttore - es. i plug-in di controllo di
hr_*
.
2.2. Nome del servizio
Usa abbreviazioni comuni e ben definite (es. CPU, DB, VPN, IO,...).
Scrivi le abbreviazioni in maiuscolo.
Usa le maiuscole (es.
CPU utilization
, nonCpu Utilization
) - i nomi propri fanno eccezione.Scrivi i nomi dei prodotti come definiti dal produttore (es.
vSphere
).Usa l'inglese americano (es.
utilization
, nonutilisation
).Attieniti agli schemi di denominazione esistenti, se esistono. Ad esempio, tutti i servizi di interfaccia utilizzano il modello
Interface %s
.Cerca di essere breve e di mantenere brevi le descrizioni, poiché i nomi del servizio vengono troncati nei dashboard, nelle visualizzazioni e nei report se sono troppo lunghi.
2.3. Nomi delle metriche
Le metriche per le quali esiste già una definizione significativa dovrebbero essere riutilizzate.
In caso contrario, si applicano regole simili a quelle utilizzate per il nome del plug-in di controllo (prodotto specifico, manufattura specifica, ecc.).
2.4. Nome del gruppo di controllo per il set di regole
Si applica la stessa convenzione utilizzata per le metriche.
3. Costruire un plug-in di controllo
3.1. Struttura generale
Il file Python che si trova su ~/share/check_mk/checks/
deve avere la seguente struttura (rispettando la sequenza di codifica):
Un'intestazione del file con una nota GPL.
Il nome e l'indirizzo e-mail dell'autore originale se il plug-in non è stato sviluppato dal progetto Checkmk.
Un breve esempio dell'output dell'agente.
Valori predefiniti per i parametri del check (
factory_settings
).Funzioni ausiliarie, se disponibili.
La funzione di parsing, se disponibile.
La funzione di ricerca.
La funzione di controllo.
La dichiarazione
check_info
.
3.2. Linee guida per la codifica
Autorizzazioni
Se il plug-in non è stato sviluppato dal team di Checkmk, il nome e l'indirizzo e-mail dell'autore devono essere codificati direttamente dopo l'intestazione del file.
Leggibilità
Evita righe di codice troppo lunghe: la lunghezza massima consentita è di 100 caratteri.
In ogni caso l'indentazione è di quattro caratteri vuoti - non usare schede.
Orientati nello standard Python PEP 8.
Esempio di output dell'agente
Includere un esempio dell'output di un agente semplifica notevolmente la lettura del codice di esempio. In questo caso, è importante includere vari output possibili nell'esempio. Fai in modo che l'esempio non sia più lungo del necessario. Con i controlli basati su SNMP, fornisci una passeggiata SNMP:
Example excerpt from SNMP data:
.1.3.6.1.4.1.2.3.51.2.2.7.1.0 255
.1.3.6.1.4.1.2.3.51.2.2.7.2.1.1.1 1
.1.3.6.1.4.1.2.3.51.2.2.7.2.1.2.1 "Good"
.1.3.6.1.4.1.2.3.51.2.2.7.2.1.3.1 "No critical or warning events"
.1.3.6.1.4.1.2.3.51.2.2.7.2.1.4.1 "No timestamp"
Se, ad esempio, vengono prodotti formati di output diversi a causa delle diverse versioni del firmware dei dispositivi di destinazione, è necessario fornire un esempio che indichi la versione per ciascuno di essi. Un buon esempio di questo caso si trova nel plug-in di controllo multipath
.
MIB SNMP
Quando si definisce snmp_info
, nei commenti si deve indicare il percorso leggibile dell'OID. Esempio:
'snmp_info' : (".1.3.6.1.2.1.47.1.1.1.1", [
OID_END,
"2", # ENTITY-MIB::entPhysicalDescription
"5", # ENTITY-MIB::entPhysicalClass
"7", # ENTITY-MIB::entPhysicalName
]),
Utilizzo di lambda
Evita espressioni complesse con lambda
. È consentito l'uso di lambda
nella funzione di scansione lambda oid: …
e quando desideri invocare funzioni esistenti con solo un argomento modificato, ad esempio:
"inventory_function" : lambda info: inventory_foobar_generic(info, "temperature")
Iterazione dei dati dell'agente SNMP
Con i controlli che analizzano i dati SNMP, un indice come questo non dovrebbe essere utilizzato:
for line in info:
if line[1] != '' and line[0] ...
È meglio spacchettare ogni riga come variabile significativa:
for *sensor_id, state_state, foo, bar* in info:
if sensor_state != '1' and sensor_id ...
Funzioni di parsing
Utilizza sempre le funzioni di parsing ogni volta che l'analisi dell'output di un agente non è banale. L'argomento della funzione di parsing deve essere sempre chiamato info
, e nelle funzioni di discovery e check l'argomento deve essere chiamato parsed
invece di info
. In questo modo sarà chiaro al lettore che il risultato proviene da una funzione di parsing.
Controlli con risultati parziali multipli
Un controllo che produce più risultati parziali - ad esempio, le allocazioni e la crescita attuali - deve restituirli con yield
. I controlli che producono un solo risultato devono utilizzare return
.
if "abs_levels" in params:
warn, crit = params["abs_levels"]
if value >= crit:
yield 2, "...."
elif value >= warn:
yield 1, "...."
else:
yield 0, "..."
if "perc_levels" in params:
warn, crit = params["perc_levels"]
if percentage >= crit:
yield 2, "...."
elif percentage >= warn:
yield 1, "...."
else:
yield 0, "..."
I marcatori (!)
e (!!)
sono obsoleti e non possono più essere utilizzati; devono essere sostituiti da yield
.
Chiavi in check_info[…]
Memorizza in check_info
solo le chiavi che verranno utilizzate nella tua voce. Le uniche voci obbligatorie sono "service_description"
e "check_function"
. Inserisci "has_perfdata"
e altre chiavi con valori booleani solo se il loro valore è True
.
3.3. Plug-in dell'agente
Se il tuo plug-in di controllo richiede un plug-in dell'agente, tieni presente le seguenti regole:
Memorizza il plug-in in
~/share/check_mk/agents/plugins
per i sistemi Unix e imposta i diritti di esecuzione su755
.In Windows la directory si chiama
~/share/check_mk/agents/windows/plugins
.Gli script shell e Python non devono avere un'estensione del nome del file (omettere
.sh
e.py
).Usa
#!/bin/sh
nella prima riga degli script di shell. Utilizza#!/bin/bash
solo se sono richieste le funzioni di Bash.Usa l'intestazione standard del file Checkmk con l'avviso GPL.
Il tuo plug-in non deve danneggiare il sistema di destinazione, soprattutto se il plug-in non è supportato dal sistema.
Non dimenticare il riferimento al plug-in nella pagina man del plug-in di controllo.
Se il componente che il plug-in deve monitorare non esiste effettivamente su un sistema, il plug-in non deve produrre un header sezioni.
Se il plug-in richiede un file di configurazione, questo deve essere cercato (in Linux) nella directory
$MK_CONFDIR
e il file deve avere lo stesso nome del plug-in - a parte l'estensione.cfg
e senza un eventuale prefissomk_
. La procedura è simile per Windows - la directory in Windows è%MK_CONFDIR%
.Non codificare i plug-in per Windows in PowerShell: non è portabile e in ogni caso è molto avaro di risorse. Usa VBScript.
Non codificare i plug-in in Java.
3.4. Non fare
Non utilizzare
import
nel tuo file plug-in di controllo. Tutti i moduli Python consentiti sono già stati importati.Non usare
datetime
per il parsing e il calcolo delle specifiche temporali: usatime
, che può svolgere tutti i compiti necessari. Davvero!Gli argomenti che ricevono le tue funzioni non devono in alcun modo modificare le funzioni stesse. Questo vale soprattutto per
params
einfo
.Se vuoi davvero lavorare con le espressioni regolari (sono lente!), invocale con la funzione
regex()
- non usare direttamentere
.Naturalmente non è consentito utilizzare
print
, né instradare gli output versostdout
, né comunicare con il mondo esterno in alcun modo!La funzione di scansione SNMP non è autorizzata a recuperare OID diversi da
.1.3.6.1.2.1.1.1.0
e.1.3.6.1.2.1.1.2.0
. Eccezione: la funzione di scansione SNMP ha precedentemente garantito, controllando uno di questi due OID, che ulteriori OID vengano recuperati solo da un numero strettamente limitato di dispositivi.
4. Controllare il comportamento del plug-in
4.1. Eccezioni
Il tuo plug-in di controllo non deve, anzi deve sempre presumere che l'output di un agente sia sintatticamente valido. In nessun caso il plug-in può tentare di gestire situazioni di errore sconosciute nell'output stesso!
Checkmk dispone di una funzione molto raffinata per la gestione automatica di tali errori. Per l'utente può generare report completi sui crash e inoltre imposta lo stato del plug-in di controllo su SCONOSCIUTO, il che è molto più utile rispetto al caso in cui il controllo, ad esempio, produca semplicemente un unknown SNMP code 17
.
La funzione di discovery, parse e/o check dovrebbe in genere segnalare un'eccezione se l'output dell'agente non è nel formato definito e conosciuto per il quale è stato sviluppato il plug-in di controllo.
4.2. saveint() e savefloat()
Le funzioni saveint()
e savefloat()
convertono una stringa in int
o float
e producono un 0
se la stringa non può essere convertita (es. è una stringa vuota).
Utilizza queste funzioni solo se il valore vuoto o non valido è una condizione nota, altrimenti i messaggi di errore importanti saranno soppressi (vedi sopra).
4.3. Elemento non trovato
Un controllo che non trova un elemento monitorato dovrebbe semplicemente produrre un None
e non generare un proprio messaggio di errore. In questo caso Checkmk produrrà un messaggio di errore standardizzato e coerente e imposterà il servizio su SCONOSCIUTO.
4.4. Soglie
Molti plug-in di controllo hanno parametri che definiscono le soglie per specifiche metriche e quindi determinano quando il controllo assume lo stato WARN o CRIT. Tieni presente le seguenti regole che assicurano che Checkmk reagisca in modo coerente:
Le soglie per WARN e CRIT devono essere sempre verificate con
>=
e<=
. Esempio: un plug-in monitora la lunghezza della coda di posta elettronica. Il limite superiore critico è 100. Questo significa che se il valore effettivo è "100" è già critico!Se ci sono solo soglie superiori o inferiori (i casi più comuni), i campi di inserimento nel set di regole devono essere codificati con Warning at e Critical at.
Se ci sono soglie superiori e inferiori, la codifica dovrebbe essere la seguente: Warning at or above, Critical at or above, Warning at or below e Critical at or below.
4.5. Output del plug-in di controllo
Ogni controllo produce una riga di testo: l'output del plug-in. Per ottenere un comportamento coerente per tutti i plug-in, si applicano le seguenti regole:
Per mostrare i valori misurati, un carattere vuoto deve separare esattamente il valore e l'unità (es.
17.4 V
). L'unica eccezione a questa regola è rappresentata da%
, dove non c'è alcun carattere vuoto:89.5%
.Quando si elencano i valori misurati, il nome del valore con l'iniziale maiuscola è seguito dai due punti. Esempio:
Voltage: 24.5 V, Phase: negative, Flux-Compensator: operational
Non mostrare chiavi interne, codewords, SNMP-internals o altre sciocchezze negli output dei plug-in che non sono di alcuna utilità per l'utente. Usa termini significativi e leggibili dall'uomo. Usa termini che l'utente si aspetta normalmente. Esempio: Usa
route monitor has failed
piuttosto cherouteMonitorFail
.Se l'elemento di controllo ha una specifica aggiuntiva, codificala tra parentesi quadre all'inizio dell'output (es.
Interface 2 - [eth0] …
).Negli elenchi, gli elementi sono separati da virgole e quelli successivi hanno l'iniziale maiuscola:
Swap used: …, Total virtual memory used: …
4.6. Soglie predefinite
Ogni plug-in che lavora con le soglie dovrebbe avere dei valori predefiniti significativi definiti per le soglie. Si applicano le seguenti regole:
Le soglie predefinite utilizzate nel controllo devono essere definite 1:1 come parametri predefiniti nel set di regole applicabile.
Le soglie predefinite devono essere definite in
factory_settings
(se il controllo ha un dizionario come parametro).Le soglie predefinite devono essere scelte su basi tecnicamente valide: esistono specifiche del produttore o best practices?
È essenziale che la fonte dei threshold sia documentata nel controllo.
4.7. Nagios vs. CMC
Assicurati che il tuo controllo funzioni anche con un nucleo di monitoraggio Nagios. Di solito questo avviene automaticamente, ma non sempre.
5. Metriche
5.1. Formati per le metriche
Il plug-in di controllo restituisce sempre i dati metrici come
int
ofloat
. Le stringhe non sono ammesse.Se vuoi ottenere la sei-tupla da un campo di valori metrici, usa
None
nella sua posizione. Esempio:[("taple_util", utilization, None, None, 0, size)]
Se non hai bisogno della voce alla fine, accorcia semplicemente la tupla. Non usare
None
alla fine.
5.2. Nomi delle metriche
I nomi delle metriche sono costituiti da lettere minuscole e trattini bassi. I numeri sono consentiti, ma non sono in testa.
I nomi delle metriche devono essere, come per i plug-in di controllo, brevi e specifici. Le metriche che saranno utilizzate da più plug-in devono avere nomi generici.
Evita di usare l'inutile parola di riempimento
current
. Il valore misurato è sempre quello corrente.La metrica dovrebbe prendere il nome dalla "cosa", non dall'unità di misura: ad esempio,
current
piuttosto cheampere
, oppuresize
piuttosto chebytes
.
Importante: usa sempre la dimensione canonica. Davvero! Checkmk ridimensiona i dati in modo appropriato. Esempi:
Tipo di misura | Unità canonica |
---|---|
Durata |
Secondi |
Dimensione del file |
Byte |
Temperatura |
Celsius |
Velocità di rete |
Ottetti al secondo (non bit al secondo!) |
Valore percentuale |
Un valore da 0 a 100 (non da 0,0 a 1,0) |
Eventi per periodo di tempo |
1 al secondo |
Prestazioni elettriche |
Watt (non mW) |
5.3. Flag per i dati metrici
Imposta "has_perfdata"
in check_info
a True
solo se il controllo emette effettivamente dati metrici (o può emetterli).
5.4. Definizione del grafico e del Perf-O-Meter
Le definizioni per i grafici devono essere come quelle presenti in ~/web/plugins/metrics/check_mk.py
. Non creare definizioni per i grafici PNP. Anche in Checkmk Raw queste saranno generate sulla base delle definizioni metriche di Checkmk stesso.
6. Definizione del set di regole
6.1. Nome del gruppo di controllo
I plug-in di controllo con parametri richiedono la definizione di un set di regole obbligatorio. La connessione tra un plug-in e un set di regole avviene attraverso il gruppo di controllo (la voce "group"
in check_info
). Tutti i controlli configurati con lo stesso set di regole vengono consolidati attraverso il gruppo.
Se il tuo plug-in deve essere configurato con un set di regole esistente, utilizza anche un gruppo esistente.
Se il tuo plug-in è così specifico da richiedere un gruppo a sé stante, allora crea un gruppo specifico in cui il nome del gruppo deve fare riferimento al plug-in.
Se è prevedibile che in futuro altri plug-in possano utilizzare lo stesso set di regole, allora utilizza un nome generico.
6.2. Valori predefiniti per i ValueSpecs
Quando definisci le definizioni dei parametri del check(ValueSpecs), utilizza gli stessi valori predefiniti dei valori effettivamente utilizzati nei controlli (se possibile).
Esempio: se senza una regola il controllo assume la soglia (5, 10)
per WARN e CRIT, allora il ValueSpec deve essere definito in modo che 5
e 10
vengano proposti automaticamente come soglie.
6.3. Scegliere i ValueSpec
Per alcuni tipi di dati esistono dei ValueSpec specializzati. Un esempio è Age
per un certo numero di secondi. Questo deve essere utilizzato ovunque sia appropriato. Non utilizzare, ad esempio, Integer
in questo caso.
7. File di inclusione
Per diversi tipi di controlli esistono implementazioni già pronte in file di inclusione, che non solo possono essere utilizzate, ma dovrebbero essere utilizzate. I file di inclusione più importanti sono:
|
Monitoraggio delle temperature |
|
Fasi elettriche AC (es. in USV) |
|
Ventilatori |
|
Interfacce di rete |
|
Livelli del file system |
|
Monitoraggio della RAM (memoria principale) |
|
Processi del sistema operativo |
Importante: utilizza i file di inclusione esistenti solo se sono stati progettati per lo scopo in questione e non semplicemente perché si adattano in modo approssimativo!
8. Pagine man
Ogni plug-in di controllo deve avere una pagina man. Se hai programmato diversi plug-in in un unico file di plug-in di controllo, ognuno di questi deve ovviamente avere la propria pagina man.
La pagina man è destinata all'utente! Scrivi informazioni che possano aiutarlo. Non si tratta di documentare ciò che hai programmato, ma di fornire all'utente le informazioni utili di cui ha bisogno.
Una pagina man deve essere
completa,
precisa,
breve,
utile.
Una pagina man è composta da diverse sezioni, alcune delle quali sono facoltative:
8.1. Titolo
Con la macro title:
puoi determinare il titolo, che consiste in:
il nome esatto del dispositivo o del gruppo di dispositivi per cui è stato scritto il controllo,
informazioni sul monitoraggio del controllo (es. salute del sistema).
Queste due parti sono separate da due punti: solo in questo modo i controlli esistenti possono essere facilmente ricercati e, soprattutto, trovati.
8.2. Categorie di agenti
La macro agents:
può avere diverse categorie. Le categorie sono fondamentalmente tre:
Agenti: In questo caso vengono specificati i sistemi operativi per i quali il controllo è stato integrato ed è disponibile, ad esempio
linux
, olinux, windows, solaris
.SNMP: in questo caso è presente solo la voce
snmp
.Active check: Se un active check è stato integrato nell'interfaccia Checkmk, utilizza la categoria
active
.
8.3. Voce di catalogo
Utilizza l'intestazione catalog:
per specificare dove deve essere memorizzata la pagina man nel catalogo dei plug-in di controllo.
Se manca una categoria, ad esempio per un nuovo produttore, questa deve essere definita nella variabile catalog_titles
del file cmk/utils/man_pages.py
. Attualmente questo file non può essere esteso in local/
dai plug-in, quindi solo gli sviluppatori di Checkmk possono apportare modifiche.
Attenzione all'esatta maiuscola dei nomi dei prodotti e delle aziende! Questo vale non solo per le voci del catalogo, ma anche per tutti gli altri testi in cui compaiono. Esempio: NetApp
si scrive sempre NetApp
e non netapp
, NETAPP
, Netapp
o simili. Google può aiutarti a trovare l'ortografia corretta.
8.4. Descrizione del plug-in
Le seguenti informazioni devono essere incluse nella pagina man description:
:
Esattamente quale hardware o software monitora il controllo? Ci sono caratteristiche speciali di certe versioni del firmware o dei prodotti dei dispositivi? Non fare riferimento a una MIB, ma alle denominazioni dei prodotti. Esempio: Non è utile se scrivi "Questo controllo funziona per tutti i dispositivi che supportano il Foobar-17.11-MIB". Scrivi con precisione quali linee di prodotti o simili sono supportate.
Quale aspetto viene monitorato? Cosa fa il controllo?
In quali condizioni il controllo è OK, WARN o CRIT?
È necessario un plug-in dell'agente per il controllo? Se sì, come si installa? Deve funzionare anche senza l'Agent bakery.
Ci sono altri requisiti per il funzionamento del controllo (preparazione del sistema di destinazione, installazione di driver, ecc. Questi dovrebbero essere elencati solo se non sono normalmente soddisfatti (ad es. il montaggio di
/proc
in Linux).
Non scrivere nulla che riguardi tutti i controlli insieme: ad esempio, non ripetere cose generali come l'impostazione dei controlli basati su UPMP.
8.5. Elemento
Per i controlli che hanno un elemento (cioè un %s
nel nome del servizio), la pagina man sotto item:
deve descrivere come viene formato. Se il plug-in del controllo non utilizza un elemento, puoi omettere completamente questa riga.
8.6. La scoperta del servizio
In inventory:
, scrivi in quali condizioni il servizio o i servizi di questo check verranno trovati automaticamente, cioè come si comporta la scoperta del servizio. Un esempio da nfsmounts
:
inventory:
All NFS mounts are found automatically. This is done
by scanning {/proc/mounts}. The file {/etc/fstab} is irrelevant.
Assicurati che il testo sia comprensibile senza una conoscenza approfondita del MIB o del codice - quindi non scrivere:
One service is created for each temperature sensor if the state is 1.
Invece, è meglio tradurre il più possibile:
One service is created for each temperature sensor, if the state is "active".