-
Notifications
You must be signed in to change notification settings - Fork 7
/
cups_exporter.py
executable file
·155 lines (130 loc) · 4.91 KB
/
cups_exporter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python3
"""Export CUPS metrics to prometheus
"""
import argparse
import time
import cups
from prometheus_client import start_http_server
from prometheus_client.core import (REGISTRY, CounterMetricFamily,
GaugeMetricFamily)
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
"--cups-host", help="The cups host to connect to", default="localhost")
parser.add_argument("--cups-port", type=int,
help="The cups port to use", default=631)
parser.add_argument(
"--cups-user", help="The user to connect with", default="default")
parser.add_argument("--listen-port", type=int,
help="The port the exporter will listen on", default=9329)
args = parser.parse_args()
class CUPSCollector:
"""CUPSCollector collects status data about
currently configured printers in cups
"""
def __init__(self, host, port, user):
"""Set cups connection parameters
Arguments:
host {str} -- Cups Hostname
port {int} -- Cups Port
user {str} -- Cups username
"""
self._prometheus_metrics = {}
self.host = host
self.port = port
self.user = user
def collect(self):
"""Collects the metrics from cups
"""
start = time.time()
self._setup_empty_prometheus_metrics()
cups.setServer(self.host)
cups.setPort(self.port)
cups.setUser(self.user)
try:
conn = cups.Connection()
printers = conn.getPrinters()
self._prometheus_metrics['printersNum'].add_metric(
[],
len(printers))
self._getPrinterStatus(printers)
self._getJobData(conn)
self._prometheus_metrics['cupsUp'].add_metric([], 1)
except Exception as e:
self._prometheus_metrics['cupsUp'].add_metric([], 0)
print(e)
duration = time.time() - start
self._prometheus_metrics['scrape_duration_seconds'].add_metric(
[], duration)
for metric in self._prometheus_metrics.values():
yield metric
def _setup_empty_prometheus_metrics(self):
"""
The metrics we want to export.
"""
self._prometheus_metrics = {
'printJobsNum':
GaugeMetricFamily('cups_print_jobs_active',
'Number of current print jobs'),
'printJobsTotal':
CounterMetricFamily('cups_print_jobs_total',
'Total number of print jobs'),
'printersNum':
GaugeMetricFamily('cups_printers',
'Number of printers'),
'printerStatus':
GaugeMetricFamily('cups_printer_status_info',
'Status about printer alerts',
labels=['printer', 'model', 'status']),
'cupsUp':
GaugeMetricFamily('cups_up',
'CUPS status'),
'scrape_duration_seconds':
GaugeMetricFamily('cups_scrape_duration_seconds',
'Amount of time each scrape takes',
labels=[])
}
def _getJobData(self, conn):
"""Collects data about cups
"""
jobs = conn.getJobs(which_jobs="all")
if len(jobs) == 0:
self._prometheus_metrics['printJobsTotal'].add_metric([], 0)
else:
lastjobID = list(jobs.keys())[-1]
self._prometheus_metrics['printJobsTotal'].add_metric(
[], lastjobID)
jobs = conn.getJobs()
if len(jobs) == 0:
self._prometheus_metrics['printJobsNum'].add_metric([], 0)
else:
self._prometheus_metrics['printJobsNum'].add_metric(
[],
len(jobs))
def _getPrinterStatus(self, printers):
"""Gathers printer status data
Arguments:
printers {dict} -- dict of printers
"""
for key, value in printers.items():
if value['printer-state-reasons'][0] != 'none':
self._prometheus_metrics['printerStatus'].add_metric([
key,
value['printer-make-and-model'],
value['printer-state-reasons'][0]],
0)
else:
self._prometheus_metrics['printerStatus'].add_metric([
key,
value['printer-make-and-model'],
'happy'],
1)
if __name__ == '__main__':
# Start up the server to expose the metrics.
REGISTRY.register(CUPSCollector(
args.cups_host,
args.cups_port,
args.cups_user))
start_http_server(args.listen_port)
while True:
time.sleep(1)