\documentclass[10pt,a4paper]{article} % Packages \usepackage{fancyhdr} % For header and footer \usepackage{multicol} % Allows multicols in tables \usepackage{tabularx} % Intelligent column widths \usepackage{tabulary} % Used in header and footer \usepackage{hhline} % Border under tables \usepackage{graphicx} % For images \usepackage{xcolor} % For hex colours %\usepackage[utf8x]{inputenc} % For unicode character support \usepackage[T1]{fontenc} % Without this we get weird character replacements \usepackage{colortbl} % For coloured tables \usepackage{setspace} % For line height \usepackage{lastpage} % Needed for total page number \usepackage{seqsplit} % Splits long words. %\usepackage{opensans} % Can't make this work so far. Shame. Would be lovely. \usepackage[normalem]{ulem} % For underlining links % Most of the following are not required for the majority % of cheat sheets but are needed for some symbol support. \usepackage{amsmath} % Symbols \usepackage{MnSymbol} % Symbols \usepackage{wasysym} % Symbols %\usepackage[english,german,french,spanish,italian]{babel} % Languages % Document Info \author{dlicudi} \pdfinfo{ /Title (guidelines-for-writing-checks-for-check-mk.pdf) /Creator (Cheatography) /Author (dlicudi) /Subject (Guidelines for writing checks for Check\_MK Cheat Sheet) } % Lengths and widths \addtolength{\textwidth}{6cm} \addtolength{\textheight}{-1cm} \addtolength{\hoffset}{-3cm} \addtolength{\voffset}{-2cm} \setlength{\tabcolsep}{0.2cm} % Space between columns \setlength{\headsep}{-12pt} % Reduce space between header and content \setlength{\headheight}{85pt} % If less, LaTeX automatically increases it \renewcommand{\footrulewidth}{0pt} % Remove footer line \renewcommand{\headrulewidth}{0pt} % Remove header line \renewcommand{\seqinsert}{\ifmmode\allowbreak\else\-\fi} % Hyphens in seqsplit % This two commands together give roughly % the right line height in the tables \renewcommand{\arraystretch}{1.3} \onehalfspacing % Commands \newcommand{\SetRowColor}[1]{\noalign{\gdef\RowColorName{#1}}\rowcolor{\RowColorName}} % Shortcut for row colour \newcommand{\mymulticolumn}[3]{\multicolumn{#1}{>{\columncolor{\RowColorName}}#2}{#3}} % For coloured multi-cols \newcolumntype{x}[1]{>{\raggedright}p{#1}} % New column types for ragged-right paragraph columns \newcommand{\tn}{\tabularnewline} % Required as custom column type in use % Font and Colours \definecolor{HeadBackground}{HTML}{333333} \definecolor{FootBackground}{HTML}{666666} \definecolor{TextColor}{HTML}{333333} \definecolor{DarkBackground}{HTML}{36A333} \definecolor{LightBackground}{HTML}{F2F9F2} \renewcommand{\familydefault}{\sfdefault} \color{TextColor} % Header and Footer \pagestyle{fancy} \fancyhead{} % Set header to blank \fancyfoot{} % Set footer to blank \fancyhead[L]{ \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{C} \SetRowColor{DarkBackground} \vspace{-7pt} {\parbox{\dimexpr\textwidth-2\fboxsep\relax}{\noindent \hspace*{-6pt}\includegraphics[width=5.8cm]{/web/www.cheatography.com/public/images/cheatography_logo.pdf}} } \end{tabulary} \columnbreak \begin{tabulary}{11cm}{L} \vspace{-2pt}\large{\bf{\textcolor{DarkBackground}{\textrm{Guidelines for writing checks for Check\_MK Cheat Sheet}}}} \\ \normalsize{by \textcolor{DarkBackground}{dlicudi} via \textcolor{DarkBackground}{\uline{cheatography.com/22839/cs/4821/}}} \end{tabulary} \end{multicols}} \fancyfoot[L]{ \footnotesize \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{LL} \SetRowColor{FootBackground} \mymulticolumn{2}{p{5.377cm}}{\bf\textcolor{white}{Cheatographer}} \\ \vspace{-2pt}dlicudi \\ \uline{cheatography.com/dlicudi} \\ \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Cheat Sheet}} \\ \vspace{-2pt}Published 11th August, 2015.\\ Updated 12th May, 2016.\\ Page {\thepage} of \pageref{LastPage}. \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Sponsor}} \\ \SetRowColor{white} \vspace{-5pt} %\includegraphics[width=48px,height=48px]{dave.jpeg} Measure your website readability!\\ www.readability-score.com \end{tabulary} \end{multicols}} \begin{document} \raggedright \raggedcolumns % Set font size to small. Switch to any value % from this page to resize cheat sheet text: % www.emerson.emory.edu/services/latex/latex_169.html \footnotesize % Small font. \begin{multicols*}{3} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Naming}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} The check types should be named short and unique. They must consist only of lower case characters, digits and underscores and begin with a lower case character.} \tn % Row Count 4 (+ 4) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Checks where one item of the check represents one thing (e.g. fan, power supply), should be named in singular, e.g. `casa\_fan`, `if`, `oracle\_tablespace`. Checks where each item checks a quantity, e.g. number of logins, should be named in plural (e.g. `user\_logins`, `printer\_pages`). Note: due to historic misconducts many existing check types are named contrarily to this rule. That does not mean that new checks should be named inconsistently as well!} \tn % Row Count 14 (+ 10) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} {\emph{Vendor specific checks}} must be prefixed with a vendor specific unique abbreviation (which you think of). Example: `fsc\_` for Fujitsu Siemens Computers.} \tn % Row Count 18 (+ 4) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} {\emph{Product specific checks}} must be prefixed with a product abbreviation, for example `steelhead\_status` for a Steelhead appliance of Riverbed.} \tn % Row Count 22 (+ 4) % Row 4 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} {\emph{SNMP based checks}}: if the check makes use of a standardized MIB which is or might be implemented by more than one vendor, then the check should not be named after the vendor but after the MIB. An example are the hr\_* checks.} \tn % Row Count 27 (+ 5) % Row 5 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Service descriptions of different check types fundamentally doing the same must be identical (e.g. \seqsplit{`if`/`if64`/`ifoperstatus`)}. Reason: this makes rules in `main.mk` simpler for the user!} \tn % Row Count 32 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Configuration variables}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Configuration variables for `main.mk` should be named after the check if they are only used by this check. This does not hold for variables, that are used by several checks (e.g. \seqsplit{`filesystem\_default\_levels`} is used by `df`, `hr\_fs`, `df\_netapp`, ...)} \tn % Row Count 6 (+ 6) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} The variable that is used for the check's default parameters and entered in the inventory function must be named \seqsplit{CHECKTYP`\_default\_levels`} (if not used by more than one check, see above). Example: check foo\_bar has the configuration variable \seqsplit{`foo\_bar\_default\_levels`}.} \tn % Row Count 12 (+ 6) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} If a check does not use check parameters, the inventory function must return None as parameter and the check function must name the parameter argument `\_no\_params`.} \tn % Row Count 16 (+ 4) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} The name of the inventory and check function must be prefixed with the name of the check type, for example \seqsplit{`inventory\_h3c\_lanswitch\_cpu`} for the `check h3c\_lanswitch`.} \tn % Row Count 20 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Plugin output}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Each check returns one line of text - the plugin output (or sometimes called check output). In order to unify things the output must be formated according to the following rules:} \tn % Row Count 4 (+ 4) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} when returning measurement values, place exactly one space between the value an the unit (e.g. 17.3 V). Only exception: Put {\bf{no}} space before a percent sign. (correct e.g. 89.4\%).} \tn % Row Count 9 (+ 5) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} When returning measurement values, name the names of the quantities in upper case, then add the value separated by a colon. Examples: Voltage: `24.5 V`, Phase: `negative`, Flux-Capacitor: `operational`} \tn % Row Count 14 (+ 5) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Do not directly use return codes or cryptic return strings internal to the device. Instead, try to translate them to human readable messages. Example: Instead of `routeMonitorFail` use `route monitor has failed`} \tn % Row Count 19 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Performance data}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{{\bf{Format of Performance data}}} \tn % Row Count 1 (+ 1) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Always send int or float data as performance data. Do not attach a unit. Write temp instead of "\%0.2fC" \% temp!} \tn % Row Count 4 (+ 3) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} If you need to omit fields in the middle of the data list (e.g. warn or crit), add a None instead, for example {[}("usage", usage, None, None, 0, size){]}} \tn % Row Count 8 (+ 4) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} If you need to omit fields at the end, simply omit them. Do not add trailing Nones.} \tn % Row Count 11 (+ 3) % Row 4 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Naming of performance data variables: Names consist of only lowercase letters and underscores (rare). Also trailing digits are allowed (e.g. phase3).} \tn % Row Count 15 (+ 4) % Row 5 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Naming of performance data variables: The name of the variable should be named correctly after the thing, not after the unit. Example: use current instead of ampere. Use size instead of bytes.} \tn % Row Count 20 (+ 5) % Row 6 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Always use the canonical unit: send Bytes, not KB, MB or GB. Send Celsius, not Fahrenheit. Send Bits/sec, not MBits/sec. It is the task of the graphing tool to do a useful scaling.} \tn % Row Count 24 (+ 4) % Row 7 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{{\bf{Performance data flag}}} \tn % Row Count 25 (+ 1) % Row 8 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Only set "has\_perfdata" to True in check\_info if the check really produces performance data output.} \tn % Row Count 28 (+ 3) % Row 9 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{{\bf{PNP Graph definition}}} \tn % Row Count 29 (+ 1) % Row 10 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Each check returning performance data must have a dedicated PNP graph definition in pnp-templates. If the check has warning and critical levels, the graph must display these levels as yellow and red lines.} \tn % Row Count 34 (+ 5) \end{tabularx} \par\addvspace{1.3em} \vfill \columnbreak \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Performance data (cont)}} \tn % Row 11 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} PNP graphs should always use the consolidation function MAX (there are some rare exceptions where only MIN makes sense).} \tn % Row Count 3 (+ 3) % Row 12 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} However: the Average value which is printed in the labelling of the graph must use the consolidation function AVERAGE. Using MAX would compute the average of the maximum values - which is totally useless.} \tn % Row Count 8 (+ 5) % Row 13 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{{\bf{RRA definition}}} \tn % Row Count 9 (+ 1) % Row 14 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Each check returning performance data must also have an RRA definition specifiying which of MAX, MIN and AVERAGE is needed to display the graph in its current (and maybe future) forms. These definitions are in pnp-rraconf. Use a symlink here.} \tn % Row Count 15 (+ 6) % Row 15 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{{\bf{Perf-O-Meter}}} \tn % Row Count 16 (+ 1) % Row 16 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Each check returning performance data should have a Perf-O-Meter. For checks which are part of Check\_MK the Perf-O-Meter must be defined in \seqsplit{web/plugins/perfometer/check\_mk}.py. For third-party checks it should be defined in a separate file in web/plugins/perfometer.} \tn % Row Count 22 (+ 6) % Row 17 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{{\bf{SNMP based checks}}} \tn % Row Count 23 (+ 1) % Row 18 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Only use numeric OIDs in your checks. Name-based OIDs rely on MIB files and the check won't work when the MIB files are not in place. Always have your OIDs start with a root, for example: .1.3.6.1.4.1} \tn % Row Count 28 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Simple memory checks}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Many devices report memory usage in a simple way: used and total memory in absolute terms, or, equivalently, used and free memory in absolute terms.} \tn % Row Count 3 (+ 3) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} To ensure uniform behaviour, all these checks should use the check\_memory function defined in memory.include.} \tn % Row Count 6 (+ 3) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} The check group should be memory\_simple. Note that this requires that the check has an item. For devices with no modules, (i.e. only one memory value) the item should be the empty string.} \tn % Row Count 11 (+ 5) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} The service description should be "Memory" or "Memory \%s" for checks with nonempty items.} \tn % Row Count 14 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Check Layout}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} All checks must follow the same layout specified below:} \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-bolt\}\} fileheader with GPL notice} \tn % Row Count 3 (+ 1) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-bolt\}\} name and email address of the author - if check was contributed} \tn % Row Count 5 (+ 2) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-bolt\}\} example output as sent by the agent} \tn % Row Count 6 (+ 1) % Row 4 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-bolt\}\} default settings of configuration variables} \tn % Row Count 8 (+ 2) % Row 5 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-bolt\}\} helper functions and variables, if any are needed} \tn % Row Count 10 (+ 2) % Row 6 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-bolt\}\} the inventory function} \tn % Row Count 11 (+ 1) % Row 7 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-bolt\}\} the check function} \tn % Row Count 12 (+ 1) % Row 8 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-bolt\}\} the `check\_info` declaration} \tn % Row Count 13 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Coding Style: Add an author}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} If the check is contributed by a third party (i.e., not by the developers of Check\_MK), the name and email address of the contributor should be added as a comment, right after the header.} \tn % Row Count 5 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Coding style: Readability, looks and indents.}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Avoid long lines. Ideally, your lines shouldn't exceed 100 chars.} \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Use four spaces to indent your code. Don't use tab chars! And if you really can't live without tabs, set the tab width to 8 spaces.} \tn % Row Count 6 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Coding style: File Header}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} For checks which are supposed to be part of the official Check\_MK project the file header with the copyright information must be present. This will be automatically created if you call 'make headers' in the main source directory.} \tn % Row Count 6 (+ 6) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Coding style: Example agent output}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Including example output of the agent is very helpful for understanding how the check parser works.} \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} TCP-Agent based checks {\bf{must}} include an output example of the agent. If the agent output can have different formats or output styles, then put an example for each kind of style the check supports (e.g.: the output of multipath -l has changed its layout between SLES 10 and SLES 11).} \tn % Row Count 9 (+ 7) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} For SNMP based checks, at least include examples if the kind of output is remarkable in some respect.} \tn % Row Count 12 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Coding style: Use of lambda functions}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{When it comes to `parse\_function`, `inventory\_function` and `check\_function`, the usage of `lambda` functions is only allowed in order to reuse {\emph{existing}} functions while providing some additional argument. Example:} \tn % Row Count 5 (+ 5) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{`"inventory\_function" : \seqsplit{inventory\_foobar\_generic(info}, "temperature")`} \tn % Row Count 7 (+ 2) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{It is not allowed to implement the function itself as `lambda` expression. Example:} \tn % Row Count 9 (+ 2) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{{\bf{`\# This is bad, ugly and unreadable code!!`}}} \tn % Row Count 10 (+ 1) % Row 4 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{`'check\_function' : lambda \_no\_item, \_no\_params, info: \textbackslash{}`} \tn % Row Count 12 (+ 2) % Row 5 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{`(0, "Memory used: \%s" \% get\_bytes\_human\_readable(int(info{[}0{]}{[}0{]}))),`} \tn % Row Count 14 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Manpages}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Each check must have a check man page. This should be:} \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{complete} \tn % Row Count 3 (+ 1) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{precise} \tn % Row Count 4 (+ 1) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{terse} \tn % Row Count 5 (+ 1) % Row 4 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{helpful!} \tn % Row Count 6 (+ 1) % Row 5 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Information that must be contained in the check description:} \tn % Row Count 8 (+ 2) % Row 6 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{What does the check exactly do?} \tn % Row Count 9 (+ 1) % Row 7 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{A definition under which circumstances the check status will change to WARN/CRIT?} \tn % Row Count 11 (+ 2) % Row 8 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Which devices are supported by the check?} \tn % Row Count 12 (+ 1) % Row 9 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{Does the check require some configuration of the agent or some separate agent plugin? (example: the logwatch check requires the agent plugin mk\_logwatch to be installed)} \tn % Row Count 16 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Service Descriptions}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Checks doing the same should always have the same (consistent) service description. Examples:} \tn % Row Count 3 (+ 3) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{CPU utilization services must be named CPU utilization.} \tn % Row Count 5 (+ 2) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Temperature services must begin with the word Temperature.} \tn % Row Count 7 (+ 2) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{Services for main RAM usage should be named Memory used.} \tn % Row Count 9 (+ 2) % Row 4 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Services for fans should be named Fan or Fan \%s.} \tn % Row Count 10 (+ 1) % Row 5 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{Services for power supplies should be named Power Supply or Power Supply \%s.} \tn % Row Count 12 (+ 2) % Row 6 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Service descriptions should be capitalized like English titles, e.g. "Source of Output"} \tn % Row Count 15 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Forbidden Things}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-exclamation-triangle\}\} Never use a global import statement in a check file} \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-exclamation-triangle\}\} Do not use datetime for date/time parsing. Use time. It can do all you need, really !!!} \tn % Row Count 5 (+ 3) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-exclamation-triangle\}\} Do not use any other modules, except: sys, os, time, socket} \tn % Row Count 7 (+ 2) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-exclamation-triangle\}\} If you need regular expressions, use the function regex(). Do not use re directly.} \tn % Row Count 10 (+ 3) % Row 4 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-exclamation-triangle\}\} Neither the check function nor the inventory function may use the print command, or otherwise output any data to stdout or stderr, or communicate with the outside world in any other way. An rare exception to this are checks which need a dedicated data storage (such as logwatch: it keeps unread log messages in files).} \tn % Row Count 17 (+ 7) % Row 5 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-exclamation-triangle\}\} Never fetch SNMP data that is not actually used in the check or inventory function.} \tn % Row Count 20 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Temperature checks}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} The item name should reflect the kind of temperature being monitored. Please refer to the following table to make sure that the same kinds of temperatures get the same item.} \tn % Row Count 4 (+ 4) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{Ambient: Built-in sensor measuring ambient air temperature} \tn % Row Count 6 (+ 2) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{External: An external, freely placeable sensor connected to the device} \tn % Row Count 8 (+ 2) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{System: System mainboard temperature} \tn % Row Count 9 (+ 1) % Row 4 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{CPU: CPU temperature} \tn % Row Count 10 (+ 1) % Row 5 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} To ensure that all temperature checks work in the same way, use the check\_temperature function in temperature.include.} \tn % Row Count 13 (+ 3) % Row 6 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} The check group should be temperature.} \tn % Row Count 15 (+ 2) % Row 7 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} check\_temperature can handle device levels and status in various ways configurable in the temperature WATO rule. Do not pass both device status and device levels to check\_temperature - if a device provides levels, pass those and not the status.} \tn % Row Count 21 (+ 6) % Row 8 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Some devices can output temperature in various units, and specify which unit it is. In those cases, pass the temperature in the unit the device states, along with the unit as the dev\_unit parameter to check\_temperature.} \tn % Row Count 26 (+ 5) % Row 9 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Some devices have a very large number of similar temperature sensors, where one item per sensor would be unreasonable. (Dozens of ambient temperature sensors in a small device do not really provide more information than a single one.) In those cases, use the check\_temperature\_list function defined in temperature.include. Use the temperature check group just as you would for regular temperature checks.} \tn % Row Count 35 (+ 9) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Setting default values for configuration variables}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Default values for check parameters (e.g. \seqsplit{`switch\_cpu\_default\_levels`)} must be chosen in a way that they make sense for {\emph{everybody}}, not just for your special case. If case you are unsure, rather choose too loose than too tight levels. This helps avoid false alarms.} \tn % Row Count 6 (+ 6) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} If you set default values, add a short comment about how you came to choose said values. If it is merely a rough estimate, document that it is, if you got them from a very specific source, document where you got them.} \tn % Row Count 11 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Reuse of configuration variables}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} If the same configuration variable is used in multiple checks, it must be set to a default value in {\bf{all}} checks and the values must be identical!} \tn % Row Count 4 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Error handling}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Your check should assume that the agent is always producing valid data. It should {\bf{not}} try to handle cases when the agent output is broken. Reason: broken agent output is already handled by Check\_MK via Python exceptions. Intercepting these exceptions in your check code makes debugging of broken outputs much more difficult.} \tn % Row Count 7 (+ 7) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Do not handle cases in the agent output for which you have no indication that they can actually happen.} \tn % Row Count 10 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{int() vs. saveint() and float}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} vs. `savefloat()` `int()` will throw an exception if the argument is not a valid number string (or if it is empty). Check\_MK will catch the exception and make the check result "UNKNOWN" with an appropriate error message. `saveint()`, however, will assume 0 if the argument cannot be converted to a valid integer.} \tn % Row Count 7 (+ 7) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Use `saveint()` in all cases when you know or suspect that your device may supply invalid data, {\bf{but}} the check should work with the rest of the data and produce useful results. Disadvantage: you may never find out that the device has supplied invalid data, because the check wont tell you !} \tn % Row Count 14 (+ 7) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Use `int()` in all other cases, e.g. if you want to be notified with an exception if the check has received invalid data from your device. In most cases this is what you want !} \tn % Row Count 18 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Interpretation of levels}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Many checks have parameters defining warning and critical levels which are compared to an actual value. Please observe the following important rules and conventions if you are writting such checks.} \tn % Row Count 5 (+ 5) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Warning and critical levels should always be checked with \textgreater{}= and \textless{}=. Example: a check monitors the length of a mail queue. The critical upper level is at 100. This means that if the length is exactly 100, the check should already be critical. There might be a few exceptions to this where this wouldn't make sense.} \tn % Row Count 12 (+ 7) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} If there are both upper and lower levels, the labelling should be: Warning at or above \_\_\_, Critical at or above \_\_\_, Warning at or below \_\_\_ and Critical at or below \_\_\_.} \tn % Row Count 16 (+ 4) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} If there are both upper and lower levels, the labelling should be: Warning at or above \_\_\_, Critical at or above \_\_\_, Warning at or below \_\_\_ and Critical at or below \_\_\_.} \tn % Row Count 20 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{return versus yield}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} A check function producing several subresults (e.g. current usage and growth) must use the `yield` function for returning these results. On the other hand, check generating exactly one result must use `return`.} \tn % Row Count 5 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{check\_info{[}...{]} keys}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Do not add keys here which are not used. The only mandatory keys are "`service\_description`" and "`check\_function`". Add "`has\_perfdata`" and other keys with a boolean value only if its value is `True`.} \tn % Row Count 5 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Various}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Here are some frequent errors and further mixed guidelines:} \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} If your check is accompanied by an agent plugin, you should observe the following rules:} \tn % Row Count 5 (+ 3) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Put it into share/check\_mk/agents for UNIX like systems and make it executable (mode 755).} \tn % Row Count 7 (+ 2) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{Put it into \seqsplit{share/check\_mk/agents/windows} for Windows.} \tn % Row Count 9 (+ 2) % Row 4 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Do not add a file extension like .sh or .py.} \tn % Row Count 10 (+ 1) % Row 5 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{For shell scripts, add \#!/bin/sh in the first line. Use \#!/bin/bash only if the BASH is really required.} \tn % Row Count 13 (+ 3) % Row 6 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Add the standard Check\_MK file header with the GPL notice.} \tn % Row Count 15 (+ 2) % Row 7 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{Make sure that the plugin does not do any harm even if installed on a system where the check in question is not relevant or does not work.} \tn % Row Count 18 (+ 3) % Row 8 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{Make sure that the check manpage tells the user that the plugin is needed and which additional software needs to be installed in order to make it work.} \tn % Row Count 22 (+ 4) % Row 9 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{The plugin must not output a section header if the tool or technology to be monitored does not exist on the system.} \tn % Row Count 25 (+ 3) % Row 10 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{If the plugin needs a configuration file, expect it in \$MK\_CONFDIR and give it the same name as the plugin, but with the extension .cfg, and with any mk\_ prefix removed.} \tn % Row Count 29 (+ 4) % Row 11 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} A check which does not get the information which is needed decide whether or not the check is OK, must simply return None. This can be the case when a check with an item can not found the data matching this item in the agent output or SNMP data. Another possible situation is when the data provided by the agent or SNMP is completely empty.} \tn % Row Count 37 (+ 8) \end{tabularx} \par\addvspace{1.3em} \vfill \columnbreak \begin{tabularx}{5.377cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{5.377cm}}{\bf\textcolor{white}{Various (cont)}} \tn % Row 12 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{When a check returns None, Check\_MK will produce an UNKNOWN state with a state output which tells the user that this thing could not be found.} \tn % Row Count 3 (+ 3) % Row 13 \SetRowColor{white} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} The state markers (!) and (!!) must only be used in checks which can go warning or critical for several different reasons, like sub-checks.} \tn % Row Count 7 (+ 4) % Row 14 \SetRowColor{LightBackground} \mymulticolumn{1}{x{5.377cm}}{\{\{fa-check-square-o\}\} Your check must also work with Nagios as Core. If you use functions or variables from *.include files then you must declare them in check\_info in the key "includes" and you must then test our check with Nagios as the core.} \tn % Row Count 12 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} % That's all folks \end{multicols*} \end{document}