-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
179 lines (159 loc) · 6.47 KB
/
main.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import logging
import sqlite3
import time
import socket
from prometheus_client import start_http_server, GaugeMetricFamily
from prometheus_client.core import REGISTRY
from optparse import OptionParser
# Logging configuration
logging.basicConfig(
encoding="utf-8",
level=logging.INFO,
format="level=%(levelname)s datetime=%(asctime)s %(message)s",
)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
# Command-line arguments parsing
parser = OptionParser()
parser.add_option(
"--config",
dest="config_file",
help="Path to the Zabbix Proxy configuration file (Default: /etc/zabbix/zabbix_proxy.conf).",
default="/etc/zabbix/zabbix_proxy.conf",
)
parser.add_option("--port", dest="port", help="Listen port.", default=9200, type="int")
(options, domain) = parser.parse_args()
config_file = options.config_file
port = options.port
class ZabbixProxyExporter:
def __init__(self):
self.proxy = socket.gethostname()
with open(config_file, "r") as conf_proxy:
for line in conf_proxy:
if "DBName" in line:
line = line.strip()
self.db = line[7:]
if "Hostname" in line and "#" not in line:
line = line.strip()
self.proxy = line[9:]
self.con = None # Initialize database connection
def __open_database(self):
try:
logging.info("Initializing database")
self.con = sqlite3.connect(self.db, check_same_thread=False)
self.cur = self.con.cursor()
except sqlite3.Error as e:
logging.error(f"Error opening database: {e}")
raise # Re-raise the exception to stop execution
def __close_db(self):
if self.con:
logging.info("Closing database")
self.con.close()
def get_value_type_items(self):
logger.info("Get number of items by value_type")
try:
res = self.cur.execute(
"select value_type, count(*) from items group by value_type;"
)
return res.fetchall() # Return query results
except sqlite3.Error as e:
logging.error(f"Error executing query: {e}")
return [] # Return an empty list in case of error
def set_value_type_items(self, data):
metric = GaugeMetricFamily(
"zbx_items_value_type",
"Number of items grouped by value_type.",
labels=["value_type", "proxy"],
)
for d in data:
metric.add_metric([str(d[0]), self.proxy], d[1])
return metric
def get_proxy_queue(self):
logger.info("Get proxy queue information")
try:
res = self.cur.execute(
"select max(id)-(select nextid from ids where table_name = 'proxy_history' limit 1) from proxy_history;"
)
return res.fetchone() # Return query result
except sqlite3.Error as e:
logging.error(f"Error executing query: {e}")
return (None,) # Return an empty tuple in case of error
def set_proxy_queue(self, data):
metric = GaugeMetricFamily(
"zbx_proxy_history",
"Number of values in the proxy history table waiting to be sent to the server.",
labels=["proxy"],
)
if data[0] is not None: # Check if value is None
metric.add_metric([self.proxy], data[0])
return metric
def get_proxy_hosts(self):
logger.info("Get proxy hosts information")
try:
res = self.cur.execute("select count(*) from hosts where status = 0;")
return res.fetchone() # Return query result
except sqlite3.Error as e:
logging.error(f"Error executing query: {e}")
return (None,) # Return an empty tuple in case of error
def set_proxy_hosts(self, data):
metric = GaugeMetricFamily(
"zbx_proxy_hosts", "Number of monitored hosts.", labels=["proxy"]
)
if data[0] is not None: # Check if value is None
metric.add_metric([self.proxy], data[0])
return metric
def get_number_enabled_items(self):
logger.info("Get number of enabled items")
try:
res = self.cur.execute("select count(*) from items where status = 0;")
return res.fetchone() # Return query result
except sqlite3.Error as e:
logging.error(f"Error executing query: {e}")
return (None,) # Return an empty tuple in case of error
def set_number_enabled_items(self, data):
metric = GaugeMetricFamily(
"zbx_enabled_items", "Number of enabled items.", labels=["proxy"]
)
if data[0] is not None: # Check if value is None
metric.add_metric([self.proxy], data[0])
return metric
def get_items_type(self):
logger.info("Get number of enabled items by type")
try:
res = self.cur.execute("select type, count(*) from items group by type")
return res.fetchall() # Return query results
except sqlite3.Error as e:
logging.error(f"Error executing query: {e}")
return [] # Return an empty list in case of error
def set_items_type(self, data):
metric = GaugeMetricFamily(
"zbx_items_by_type", "Number of items by type.", labels=["type", "proxy"]
)
for d in data:
metric.add_metric([str(d[0]), self.proxy], d[1])
return metric
def collect(self):
try:
self.__open_database() # Open connection once at the beginning
logger.info("Collecting proxy information")
data = self.get_proxy_queue()
yield self.set_proxy_queue(data)
data = self.get_proxy_hosts()
yield self.set_proxy_hosts(data)
data = self.get_value_type_items()
yield self.set_value_type_items(data)
data = self.get_number_enabled_items()
yield self.set_number_enabled_items(data)
data = self.get_items_type()
yield self.set_items_type(data)
logger.info("Done collecting proxy information")
except Exception as e:
logging.error(f"An error occurred during collection: {e}")
finally:
self.__close_db() # Ensure connection is closed in case of errors
if __name__ == "__main__":
collector = ZabbixProxyExporter()
start_http_server(port)
REGISTRY.register(collector)
while True:
time.sleep(30)