Skip to content

Commit 786e980

Browse files
committed
docs(example,contributing): add README skeleton, ruff formatter, and coding conventions
1 parent aed552c commit 786e980

File tree

7 files changed

+198
-101
lines changed

7 files changed

+198
-101
lines changed

.pre-commit-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ repos:
2323
- id: 'end-of-file-fixer'
2424
- id: 'trailing-whitespace'
2525

26+
- repo: 'https://github.com/astral-sh/ruff-pre-commit'
27+
rev: 'v0.15.9'
28+
hooks:
29+
- id: 'ruff-check'
30+
args: ['--fix']
31+
- id: 'ruff-format'
32+
2633
- repo: 'https://github.com/pylint-dev/pylint'
2734
rev: 'v4.0.5'
2835
hooks:

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414

1515
### Changed
1616

17+
* Add ruff linter and formatter to pre-commit hooks, enforce single-quote style
1718
* CONTRIBUTING: add "no continuous counters" policy with rationale and link to example plugin ([#320](https://github.com/Linuxfabrik/monitoring-plugins/issues/320))
1819
* CONTRIBUTING: add early reference to example plugin as skeleton for new plugins
1920
* CONTRIBUTING: add Grafana migration note for grafanactl ([#1062](https://github.com/Linuxfabrik/monitoring-plugins/issues/1062))
21+
* CONTRIBUTING: add PEP 8 string quoting convention (single quotes, `"""` for triple-quoted)
22+
* CONTRIBUTING: add README structure guidelines with fixed section order, Fact Sheet template, and Nagios/Icinga check name for SEO
2023
* CONTRIBUTING: rewrite unit-test section with declarative test pattern, naming conventions, and tox usage
2124
* CONTRIBUTING: run pylint without `--disable` flags
2225
* CONTRIBUTING: remove inline `pylint: disable` comments from code examples
2326
* example: rewrite as comprehensive skeleton covering all standard patterns (argparse, SQLite delta calculations, regex filtering, `--lengthy` table output, human-readable formatting, get_state/get_worst, Grafana-compatible perfdata)
27+
* example: rewrite README as skeleton template with Overview, Fact Sheet, States, Perfdata, and Troubleshooting sections
2428
* Update and extend pre-commit hooks (add `check-added-large-files`, `check-merge-conflict`, `check-yaml`; update all hook versions)
2529
* Unify CONTRIBUTING and enhance it with the official Monitoring Plugins and Nagios Plugin Development Guidelines
2630

CONTRIBUTING.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,8 @@ A monitoring plugin has to calculate such values always on its own. If this is n
585585

586586
We use [PEP 8 -- Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) where it makes sense.
587587

588+
**String quoting:** Use single quotes as the default. Use double quotes only inside f-string expressions (e.g. `f'{lib.base.state2str(state, prefix=" ")}'`) or when the string itself contains single quotes (e.g. `'Python module "psutil" is not installed.'`). Use `"""` for all triple-quoted strings (docstrings, `DESCRIPTION`, SQL, etc.). This is enforced by `ruff format`.
589+
588590

589591
### Docstrings
590592

@@ -830,6 +832,43 @@ If you want to create a Service Set, edit `assets/icingaweb2-module-director/all
830832
If you want to move a service from one Service Set to another, you have to create a new UUID for the new service (this isn't even possible in the Icinga Director GUI).
831833

832834

835+
### README Structure
836+
837+
Each plugin README follows a fixed structure. See [check-plugins/example/README.md](check-plugins/example/README.md) for the reference template. The sections are:
838+
839+
1. **Overview**: Describes *what* the plugin does. A leading sentence stating the main purpose. This must include at least the text from the plugin's `DESCRIPTION` variable. Followed by subsections:
840+
841+
* **Data Collection**: How data is gathered (shell command, API, psutil, etc.), filtering options, SQLite usage, non-blocking measurement.
842+
* **Compatibility**: Supported platforms, required tools or modules.
843+
* **Important Notes** (optional): Operational edge cases the admin must know before deploying, for example: "Requires sudo", "Only works with Redis 3.0+", "First run returns OK with 'Waiting for more data.'", "After a reboot, counters reset and the check waits for a new baseline". No implementation details - only things that affect deployment and daily operations.
844+
845+
2. **Fact Sheet**: Key properties as a table (download link, check name, check interval, parameters required, Windows support, 3rd party modules, state file path, etc.). Only list applicable rows.
846+
847+
| Fact | Value |
848+
|----|----|
849+
| Check Plugin Download | <https://github.com/Linuxfabrik/monitoring-plugins/tree/main/check-plugins/example> |
850+
| Nagios/Icinga Check Name | `check_example` (for SEO: helps admins find the plugin when searching for the traditional Nagios-style name) |
851+
| Check Interval Recommendation | Every minute, Every 5/15/30 minutes, Every hour, Every 4/8/12 hours, Every day, Every week |
852+
| Can be called without parameters | Yes/No |
853+
| Compiled for Windows | Yes (when `.windows` file exists)/No (runs with Python interpreter) |
854+
| Requirements | command-line tool `foo`; User with higher permissions |
855+
| 3rd Party Python modules | `module-name` |
856+
| Handles Periods | Yes (alerts only after `--count` consecutive threshold violations) |
857+
| Uses State File | `$TEMP/linuxfabrik-monitoring-plugins-<plugin-name>.db` |
858+
859+
3. **Help**: The full `--help` output in a code block. Regenerate via `tools/update-readmes`.
860+
861+
4. **Usage Examples**: One or more realistic invocations with their output. Show at least one OK case. If the plugin has `--lengthy`, show both variants.
862+
863+
5. **States**: Describes *when* the plugin returns which state. Be precise about OK, WARN, CRIT, UNKNOWN conditions (e.g. "WARN if the percentage value is >= `--warning`"). Include `--always-ok` behavior, consecutive-run requirements, and first-run/reboot edge cases.
864+
865+
6. **Perfdata / Metrics**: Table with columns Name, Type, Description. Types: `Bytes`, `Number`, `Percentage`, `Seconds`. Where possible, use the metric descriptions from the vendor's official documentation (e.g. Redis INFO, psutil docs, API references).
866+
867+
7. **Troubleshooting** (optional): Known error messages with their solutions. Format: error message in backticks on its own line, followed by two trailing spaces for a Markdown line break, solution on the next line. Separate entries with a blank line.
868+
869+
8. **Credits, License**: Always present.
870+
871+
833872
### Grafana Dashboards
834873

835874
The title of the dashboard should be capitalized, the name has to match the folder/plugin name (spaces will be replaced with `-`, `/` will be ignored. eg `Network I/O` will become `network-io`). Each Grafana panel should be meaningful, especially when comparing it to other related panels (eg memory usage and CPU usage).

check-plugins/cpu-usage/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Monitors system-wide CPU utilization with sustained load detection to avoid fals
1616
* System-wide aggregate CPU statistics (not per-core)
1717
* Non-blocking measurement using SQLite state persistence between runs
1818
* Platform-specific extended metrics where available (context switches, interrupts, soft interrupts)
19+
1920
**Compatibility:**
2021

2122
* Cross-platform: Linux, Windows, and all psutil-supported systems

check-plugins/example/README.md

Lines changed: 61 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,45 @@
22

33
## Overview
44

5-
Help text from check command.
5+
Skeleton plugin demonstrating all standard patterns and library functions: argparse with append/deprecated/suppress parameters, (success, result) error handling, SQLite delta calculations (no continuous counters), regex filtering, `--lengthy` table output, human-readable formatting (bytes, seconds, numbers), perfdata, get_state/get_worst, and Grafana-compatible panel design. Use this as a template for new check plugins.
66

7-
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
7+
**Data Collection:**
88

9-
Hints:
9+
* Executes a shell command (`cat /etc/os-release` as a placeholder) to collect data
10+
* Items can be filtered by `--name` (exact match) and excluded by `--ignore-regex` (Python regular expression)
11+
* Uses SQLite state persistence between runs to calculate deltas (e.g. bytes per second)
12+
* On the first run, returns "Waiting for more data." until at least two measurements are available
13+
* After a system reboot, counter values may be lower than the previous measurement. The check detects this (negative delta) and returns "Waiting for more data." until the next valid measurement pair
1014

11-
* Might be useful.
12-
* Could help.
15+
**Compatibility:**
1316

17+
* Cross-platform: Linux, Windows, and all psutil-supported systems
1418

1519
## Fact Sheet
1620

1721
| Fact | Value |
1822
|----|----|
1923
| Check Plugin Download | <https://github.com/Linuxfabrik/monitoring-plugins/tree/main/check-plugins/example> |
20-
| Check Interval Recommendation | Once a minute |
21-
| Can be called without parameters | Yes\|No |
22-
| Compiled for Windows | Yes\|No |
23-
| Requirements | command-line tool `foo`; User with higher permissions |
24+
| Nagios/Icinga Check Name | `check_example` |
25+
| Check Interval Recommendation | Every minute |
26+
| Can be called without parameters | No (`--token` is required) |
27+
| Compiled for Windows | No (runs with Python interpreter) |
2428
| 3rd Party Python modules | `psutil` |
25-
| Handles Periods | Yes |
26-
| Uses SQLite DBs | `$TEMP/linuxfabrik-monitoring-plugins-example.db` |
27-
| Perfdata compatible with Prometheus | Yes |
28-
29-
Hints for the Author (delete those):
30-
31-
* Check Interval Recommendation: other texts are "Every 15 minutes", "Once a day" etc.
32-
* Available for: delete inappropriate ones
33-
* Requirements: delete if none
34-
* Handles Periods: delete if not
35-
* Uses SQLite DBs: delete if not
36-
* Perfdata compatible with Prometheus: delete if not
29+
| Uses State File | `$TEMP/linuxfabrik-monitoring-plugins-example.db` |
3730

3831

3932
## Help
4033

4134
```text
4235
usage: example [-h] [-V] [--always-ok] [-c CRIT] [--ignore-regex IGNORE_REGEX]
43-
[--module MODULE] [--name NAME] [--test TEST] --token TOKEN
44-
[-w WARN]
36+
[--lengthy] [--module MODULE] [--name NAME] [--test TEST]
37+
[--timeout TIMEOUT] --token TOKEN [-w WARN]
4538
46-
A working Linuxfabrik monitoring plugin, written in Python 3, as a basis for
47-
further development, and much more text to help admins get this check up and
48-
running.
39+
Skeleton plugin demonstrating all standard patterns and library functions:
40+
argparse with append/deprecated/suppress parameters, (success, result) error
41+
handling, SQLite delta calculations (no continuous counters), regex filtering,
42+
--lengthy table output, human-readable formatting (bytes, seconds, numbers),
43+
perfdata, get_state/get_worst, and Grafana-compatible panel design.
4944
5045
options:
5146
-h, --help show this help message and exit
@@ -56,12 +51,14 @@ options:
5651
Any english title matching this python regex will be
5752
ignored (repeating). Example: '(?i)linuxfabrik' for a
5853
case-insensitive search for "linuxfabrik".
54+
--lengthy Extended reporting.
5955
--module MODULE "modulename" to check (startswith), for example
6056
`--module json --module mbstring` (repeating)
6157
--name NAME Only check items with this name (repeating). If not
6258
specified, all items are checked.
6359
--test TEST For unit tests. Needs "path-to-stdout-file,path-to-
6460
stderr-file,expected-retc".
61+
--timeout TIMEOUT Network timeout in seconds. Default: 8 (seconds)
6562
--token TOKEN Software API token
6663
-w, --warning WARN Set the WARN threshold as a percentage. Default: >= 80
6764
```
@@ -70,48 +67,64 @@ options:
7067
## Usage Examples
7168

7269
```bash
73-
./example --warning 80 --critical 90 --count 5
70+
./example --token=mytoken --warning=80 --critical=90
7471
```
7572

76-
Output:
73+
Output (first run):
7774

7875
```text
79-
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
80-
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
81-
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
82-
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
83-
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
84-
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
76+
Waiting for more data.
8577
```
8678

79+
Output (subsequent runs):
8780

88-
## States
81+
```text
82+
42% used, up 1D 10h, since 2026-04-09 06:30:44, 1.0GiB/s, 42K items
8983
90-
* Always returns OK.
91-
* WARN or CRIT if any condition.
84+
Title ! Value
85+
------------+------
86+
Lorem ipsum ! 42%
87+
```
9288

89+
With `--lengthy`:
9390

94-
## Perfdata / Metrics
91+
```text
92+
42% used, up 1D 10h, since 2026-04-09 06:30:44, 1.0GiB/s, 42K items
9593
96-
There is no perfdata.
94+
Title ! Type ! Value
95+
------------+-------+------
96+
Lorem ipsum ! Lorem ! 42%
97+
```
9798

98-
OR
99+
100+
## States
101+
102+
* OK if the percentage value is below the warning threshold.
103+
* OK with "Waiting for more data." on the first run or after a reboot.
104+
* WARN if the percentage value is >= `--warning` (default: 80).
105+
* CRIT if the percentage value is >= `--critical` (default: 90).
106+
* UNKNOWN on missing Python modules, invalid `--ignore-regex` patterns, or invalid command-line arguments.
107+
* `--always-ok` suppresses all alerts and always returns OK.
108+
109+
110+
## Perfdata / Metrics
99111

100112
| Name | Type | Description |
101113
|----|----|----|
102-
| allocation_btree_compares_total | Continous Counter | Number of allocation B-tree compares for a filesystem. |
103-
| allocation_btree_lookups_total | Bytes | Number of allocation B-tree lookups for a filesystem. |
104-
| allocation_btree_lookups_total | Percentage | Number of allocation B-tree lookups for a filesystem. |
105-
| allocation_btree_lookups_total | None | Number of allocation B-tree lookups for a filesystem. |
114+
| cpu-usage | Percentage | The measured percentage value. |
115+
| rx-bytes-per-second | Bytes | Received bytes per second, calculated as delta between two consecutive check runs. |
106116

107117

108118
## Troubleshooting
109119

110-
My Error Message 1
111-
My Solution goes here.
120+
`Python module "psutil" is not installed.`
121+
Install `psutil`: `pip install psutil` or `dnf install python3-psutil`.
122+
123+
`Waiting for more data.`
124+
This is expected on the first run. The check needs at least two measurements to calculate a delta. Wait for the next check interval.
112125

113-
My Error Message 2
114-
My Solution goes here.
126+
`Unable to compile regex.`
127+
The pattern passed via `--ignore-regex` is not a valid Python regular expression. Check the syntax at <https://docs.python.org/3/library/re.html>.
115128

116129

117130
## Credits, License

0 commit comments

Comments
 (0)