Skip to content

Commit

Permalink
Add support for "last update" metrics (#12)
Browse files Browse the repository at this point in the history
* Add support for "last update" metrics

* Update exported metrics
  • Loading branch information
margau authored Jan 5, 2022
1 parent 1617178 commit a573a65
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 2 deletions.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ Additionally, `pkg_reboot_required` is exported to indicate that an reboot is ne
# HELP pkg_reboot_required Node Requires an Reboot
# TYPE pkg_reboot_required gauge
pkg_reboot_required 1.0
# HELP pkg_update_start_time timestamp of last apt update start
# TYPE pkg_update_start_time gauge
pkg_update_start_time 1.641382890503045e+09
# HELP pkg_update_end_time Timestamp of last apt update finish
# TYPE pkg_update_end_time gauge
pkg_update_end_time 1.641382892755024e+09
# HELP pkg_update_time_available Availability of the apt update timestamp
# TYPE pkg_update_time_available gauge
pkg_update_time_available 1.0
# HELP pkg_installed Installed packages per origin
# TYPE pkg_installed gauge
pkg_installed{archive="focal-updates",component="main",label="Ubuntu",origin="Ubuntu",site="ftp.fau.de",trusted="True"} 672.0
Expand Down Expand Up @@ -58,12 +67,16 @@ The exporter needs to be executed with appropriate privileges, which are not nec

An example configuration will be provided in this repository in the future.

### apt hook
To enable monitoring for apt update calls, place the file under `docs/00-pve-exporter` in `/etc/apt/apt.conf.d` on your system. It will place files under `/tmp`, you can see the success of monitoring the apt update timestamps if the following metric is 1: `pkg_update_time_available 1.0`

Please not that the presence of an timestamp does not mean that all repositories were updated without issues.

## Alerting

Example alerting rules will be provided in the future.

## Roadmap

- Support for other pkg managers
- Timestamp Support ("Last List/Cache Update")
- Deployment as dpkg-Packet
4 changes: 4 additions & 0 deletions docs/00-pve-exporter
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# this is the apt hook provided by the pve exporter. This file shall be placed under /etc/apt/apt.conf.d
APT::Update::Pre-Invoke {"touch /tmp/pkg-exporter-apt-update-pre"; };
APT::Update::Post-Invoke {"touch /tmp/pkg-exporter-apt-update-post"; };
APT::Periodic::Update-Package-Lists "1";
28 changes: 28 additions & 0 deletions src/pkg_exporter/pkgmanager/apt.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import apt
import apt.progress
from pathlib import Path


class AptPkgManager:
Expand All @@ -14,6 +15,11 @@ def __init__(self):
self.metricDict["broken"] = \
{"description": "Broken packages per origin"}
self.metricsByOrigin = {}
self.metaMetrics = {}
self.metaMetrics["update_time_available"] = 0
self.metaMetrics["update_start_time"] = 0
self.metaMetrics["update_end_time"] = 0

self.cache = apt.Cache()
self.cache.open(None)

Expand All @@ -25,6 +31,16 @@ def labelValues(self, origin):
def getMetricDict(self):
return self.metricDict

def getMetaMetricDict(self):
updateMetrics = {}
updateMetrics["update_start_time"] = \
{"description": "timestamp of last apt update start"}
updateMetrics["update_end_time"] = \
{"description": "Timestamp of last apt update finish"}
updateMetrics["update_time_available"] = \
{"description": "Availability of the apt update timestamp"}
return updateMetrics

def getLabelNames(self):
labelNames = ["archive", "component", "label", "origin",
"site", "trusted"]
Expand Down Expand Up @@ -54,6 +70,15 @@ def query(self):
self.metricsByOrigin[key]["auto_removable"] += 1
if selected_package.is_now_broken:
self.metricsByOrigin[key]["broken"] += 1
# apt update time
preUpdatePath = Path("/tmp/pkg-exporter-apt-update-pre")
postUpdatePath = Path("/tmp/pkg-exporter-apt-update-post")
if preUpdatePath.is_file() and postUpdatePath.is_file():
self.metaMetrics["update_time_available"] = 1
self.metaMetrics["update_start_time"] = \
preUpdatePath.stat().st_mtime
self.metaMetrics["update_end_time"] = \
postUpdatePath.stat().st_mtime

def getMetricValue(self, name):
metricValue = []
Expand All @@ -66,3 +91,6 @@ def getMetricValue(self, name):
continue
metricValue.append(v)
return metricValue

def getMetaValue(self, name):
return self.metaMetrics[name]
14 changes: 13 additions & 1 deletion src/pkg_exporter/textfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ def main():
# initially, check which metrics and labels are available
metrics = pkgmanager.getMetricDict()
labels = pkgmanager.getLabelNames()
gauges = {}
meta_gauges = {}

# also add reboot metrics
rebootmanager = reboot.RebootManager()
Expand All @@ -23,8 +25,15 @@ def main():
[], registry=registry
)

# add update statistics
meta_metric = pkgmanager.getMetaMetricDict()
for key, value in meta_metric.items():
meta_gauges[key] = Gauge(
f'pkg_{key}', value["description"],
registry=registry
)

# Create all the gauge metrics
gauges = {}
for key, value in metrics.items():
gauges[key] = Gauge(
f'pkg_{key}', value["description"],
Expand All @@ -40,6 +49,9 @@ def main():
for m in metricList:
gauge.labels(*m["label"]).set(m["value"])

for name, gauge in meta_gauges.items():
gauge.set(pkgmanager.getMetaValue(name))

rebootmanager.query()
reboot_gauge.set(rebootmanager.getMetricValue())

Expand Down

0 comments on commit a573a65

Please sign in to comment.