Skip to content

Commit

Permalink
Prepare 3.0.6 release
Browse files Browse the repository at this point in the history
  • Loading branch information
paulgear authored Jan 2, 2024
2 parents 0a8ee38 + d3e81db commit 1f0d0a0
Show file tree
Hide file tree
Showing 19 changed files with 284 additions and 39 deletions.
39 changes: 38 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,44 @@
Notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
and this project (mostly) adheres to [Semantic
Versioning](https://semver.org/spec/v2.0.0.html).

Semantic Versioning dictates that only the 0.y.z version should undergo rapid
changes. This project differs in that I want to be able to undertake rapid
changes at multiple stages after stable versions have been released. Hence,
from version 3.x onwards NTPmon will use a versioning style somewhat like the
Linux kernel original versioning scheme, where odd-numbered major versions are
development releases, which can have backwards incompatible changes introduced
over the lifetime of that major version. Even-numbered major versions will be
stable releases which will only contain new features and bug fixes.

The current stable release is 2.1.0. It will be receiving no further
development unless critical security or data integrity bugs are found.

The current development release is 3.0.6. This is the recommended version for
anyone who wants the latest features. It should be suitable for production
deployment very soon.

## [3.0.6] - 2024-01-02

### Added

- `ntpmon_info` metric in prometheus and telegraf modes, including tags for
various system, python, and ntp components.
- If someone wants this for collectd and can explain how to do it in a way
which makes sense, please get in touch.
- `--version` command line argument.
- Roadmap in README.
- Versioning strategy in CHANGELOG.

### Changed

- Fix data type on `stratum` metric for `ntpd`. This was an integer under 2.x and
now is consistently so between `chronyd` and `ntpd`.
- Use `peertype` instead of `type` for individual peer metrics, to provide tag
compatibility between `ntpmon_peer` and `ntpmon_peers` metrics.
- Fix python 3.8 compatibility with debug flag.

## [3.0.5] - 2023-12-30

Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ PREFIX=/usr/local
SHAREDIR=share/$(NAME)
SYSTEMD_SERVICE_DIR=/lib/systemd/system
USER=$(NAME)
VERSION=3.0.5
VERSION=$(shell python3 ./src/ntpmon.py --version)
RELEASE=1

TESTS=\
unit_tests/test_classifier.py \
unit_tests/test_info.py \
unit_tests/test_line_protocol.py \
unit_tests/test_peer_stats.py \
unit_tests/test_peers.py \
Expand All @@ -30,7 +31,7 @@ datatest:
PYTHONPATH=./src ./testdata/testdata.sh

format:
black --line-length=128 --target-version=py39 src/ unit_tests/
black --line-length=128 --target-version=py39 --exclude version_data.py src/ unit_tests/

push:
git push github
Expand Down
31 changes: 22 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ issues with this.

`Collectd` doesn't have a really great way to support these individual peer
metrics, so each peer is considered to be a `collectd` "host". This feature
should be considered experimental for `collectd`, and subject to change (input
on this is welcome).
should be considered experimental for `collectd`, and subject to change or
deprecation (input on this is welcome).

## Prometheus exporter

Expand All @@ -162,17 +162,30 @@ input plugin to be enabled. Use the `--connect` command-line option if you
configure this to listen on a host and/or port other than the default
(127.0.0.1:8094).

Telegraf is the preferred output integration for NTPmon (over collectd and
prometheus), due to its higher resolution timestamps, and measuring the
timestamp at the source which generated it rather than the scraping host. The
other integrations (first collectd, then Nagios, then prometheus) may eventually
go away if they are not widely used. Please let me know if you have strong
feelings about this.

## Startup delay

By default, until the NTP server has been running for 512 seconds (the minimum
time for 8 polls at 64-second intervals), `check_ntpmon` will return OK (zero
return code). This is to prevent false positives on startup or for short-lived
VMs. To ignore this safety precaution, use `--run-time` with a low number
(e.g. 1 sec).

## Roadmap

### Python version

The current minimum python version targeted is 3.8. This version [reaches end
of life in October 2024](https://www.python.org/downloads/) and will be
deprecated in NTPmon sometime between [the release of Ubuntu
24.04](https://discourse.ubuntu.com/t/noble-numbat-release-schedule/35649)
("Noble Numbat") in April 2024 and python 3.8's EOL date.

### Output integrations

Telegraf is the preferred output integration for NTPmon (over collectd and
prometheus), due to its higher resolution timestamps, and measuring the
timestamp at the source which generated it rather than the scraping host. The
other integrations (first collectd, then Nagios, then prometheus) may eventually
go away if they are not widely used. Please let me know (via an
[issue](https://github.com/paulgear/ntpmon/issues)) if you have strong feelings
about this.
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
ntpmon (3.0.6-1) focal; urgency=medium

* New upstream release.

-- Paul Gear <[email protected]> Wed, 03 Jan 2024 07:17:49 +1000

ntpmon (3.0.5-1) focal; urgency=medium

* New upstream release.
Expand Down
2 changes: 1 addition & 1 deletion debian/check_ntpmon-man.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
:Version: 3.0
:Date: 2023-12-28
:Copyright: 2015-2023 Paul Gear
:Copyright: 2015-2024 Paul D. Gear
:Title: check_ntpmon
:Subtitle: NTPmon Nagios check
:Manual group: NTP metrics monitor
Expand Down
2 changes: 1 addition & 1 deletion debian/copyright
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Upstream-Author: Paul Gear <[email protected]>
Source: https://github.com/paulgear/ntpmon

Files: *
Copyright: 2015-2023 Paul D. Gear.
Copyright: 2015-2024 Paul D. Gear.
License: AGPL-3.0+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion debian/ntpmon-man.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
:Version: 3.0
:Date: 2023-12-28
:Copyright: 2015-2023 Paul Gear
:Copyright: 2015-2024 Paul D. Gear
:Title: ntpmon
:Subtitle: NTP metrics monitor
:Manual group: NTP metrics monitor
Expand Down
6 changes: 5 additions & 1 deletion src/alert.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright: (c) 2016-2023 Paul D. Gear
# Copyright: (c) 2016-2024 Paul D. Gear
# License: AGPLv3 <http://www.gnu.org/licenses/agpl.html>

"""
Expand All @@ -13,6 +13,7 @@

import metrics
import outputs
import version

from classifier import MetricClassifier

Expand Down Expand Up @@ -86,6 +87,9 @@ def alert(self, checkobjs: dict, output: outputs.Output, debug: bool = False) ->
"""
Produce the metrics
"""
if "info" in checkobjs:
output.send_info(checkobjs["info"], debug)
del checkobjs["info"]
self.collectmetrics(checkobjs=checkobjs)
self.mc.classify_metrics(self.metrics)
(m, rc) = self.mc.worst_metric(self.checks)
Expand Down
15 changes: 14 additions & 1 deletion src/check_ntpmon.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#!/usr/bin/env python3
#
# Copyright: (c) 2016-2023 Paul D. Gear
# Copyright: (c) 2016-2024 Paul D. Gear
# License: AGPLv3 <http://www.gnu.org/licenses/agpl.html>

import argparse
import sys

import version

from alert import NTPAlerter
from peers import NTPPeers
from process import ntpchecks
Expand Down Expand Up @@ -35,7 +37,18 @@ def get_args(checks):
action="store_true",
help="Obtain peer stats on standard input instead of from running daemon.",
)
parser.add_argument(
"--version",
action="store_true",
default=False,
help="Print the check_ntpmon version and exit",
)
args = parser.parse_args()

if args.version:
print(version.get_version())
sys.exit(0)

return args


Expand Down
59 changes: 59 additions & 0 deletions src/info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
#
# Copyright: (c) 2024 Paul D. Gear
# License: AGPLv3 <http://www.gnu.org/licenses/agpl.html>

import platform
import re
import time

from typing import Dict

import psutil

import process
import version as ntpmon_version

_static_info = None


def get_info(implementation: str, version: str) -> Dict[str, str]:
"""Collect the platform and process info metrics."""
global _static_info
if _static_info is None:
_static_info = {
"ntpmon_version": ntpmon_version.get_version(),
"platform_machine": platform.machine(),
"platform_release": platform.release(),
"platform_system": platform.system(),
"python_version": platform.python_version(),
}

this_process = psutil.Process()
memory = this_process.memory_info()
uptime = time.time() - this_process.create_time()

dynamic_info = {
"implementation_name": implementation,
"implementation_version": extract_version(version),
"ntpmon_rss": memory.rss,
"ntpmon_uptime": uptime,
"ntpmon_vms": memory.vms,
}

dynamic_info.update(_static_info)
return dynamic_info


_version_re = re.compile(r"\b\d\S+")


def extract_version(rawversion: str) -> str:
"""Extract the version string from the line. Raise ValueError if no match."""
return _version_re.search(rawversion).group()


if __name__ == "__main__":
i = process.get_implementation()
v = process.execute("version")[0][0]
print(get_info(implementation=i, version=v))
26 changes: 21 additions & 5 deletions src/ntpmon.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
# Copyright: (c) 2016-2023 Paul D. Gear
# Copyright: (c) 2016-2024 Paul D. Gear
# License: AGPLv3 <http://www.gnu.org/licenses/agpl.html>

import argparse
Expand All @@ -14,6 +14,7 @@
import outputs
import peer_stats
import process
import version

from tailer import Tailer

Expand All @@ -38,7 +39,7 @@ def get_args() -> argparse.Namespace:
)
parser.add_argument(
"--debug",
action=argparse.BooleanOptionalAction,
action="store_true",
help="Run in debug mode (default: True if standard output is a tty device)",
default=sys.stdout.isatty(),
)
Expand All @@ -64,14 +65,29 @@ def get_args() -> argparse.Namespace:
type=str,
help="Log file to follow for peer statistics, if different from the default",
)
parser.add_argument(
"--no-debug",
action="store_false",
dest="debug",
)
parser.add_argument(
"--port",
type=int,
help="TCP port on which to listen when acting as a prometheus exporter (default: 9648)",
default=9648,
)
parser.add_argument(
"--version",
action="store_true",
default=False,
help="Print the ntpmon version and exit",
)
args = parser.parse_args()

if args.version:
print(version.get_version())
sys.exit(0)

if "COLLECTD_INTERVAL" in os.environ:
if args.interval is None:
args.interval = float(os.environ["COLLECTD_INTERVAL"])
Expand Down Expand Up @@ -146,14 +162,14 @@ async def peer_stats_task(args: argparse.Namespace, output: outputs.Output) -> N
for line in lines:
stats = peer_stats.parse_measurement(line)
if stats is not None:
if "type" not in stats:
stats["type"] = find_type(stats["source"], checkobjs["peers"].peers)
if "peertype" not in stats:
stats["peertype"] = find_type(stats["source"], checkobjs["peers"].peers)
output.send_measurement(stats, debug=args.debug)


async def summary_stats_task(args: argparse.Namespace, output: outputs.Output) -> None:
global checkobjs
checks = ["proc", "offset", "peers", "reach", "sync", "vars"]
checks = ["proc", "info", "offset", "peers", "reach", "sync", "vars"]
alerter = alert.NTPAlerter(checks)
while True:
implementation = process.get_implementation()
Expand Down
Loading

0 comments on commit 1f0d0a0

Please sign in to comment.