Skip to content

Commit 233af69

Browse files
authored
Merge pull request #4 from AATools/0.2
Update to v.0.2
2 parents ef8a791 + 677247f commit 233af69

15 files changed

+612
-230
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ The Grafana dashboard visualizes collected metrics. This is an example of a dash
6060

6161
| Metric | Description |
6262
|:---|:---|
63-
| ib_broker_status | The metric shows current status of IB broker.<br /> If there are several brokers on host, there will be a own metric for each broker.<br> Possible values:<br> <span style="margin-left:2em">`0` - STOPPED;</span><br> <span style="margin-left:2em">`1` - RUNNING.</span><br> Example display in Pushgateway:<br> `ib_broker_status{brokername="BRK1",instance="",job="BRK1",qmname="QM1"} 1` |
64-
| ib_exec_group_status | The metric shows current status of IB execution group.<br /> If there are several execution groups on host, there will be a own metric for each execution group.<br> Possible values:<br> <span style="margin-left:2em">`0` - STOPPED;</span><br> <span style="margin-left:2em">`1` - RUNNING.</span><br> Example display in Pushgateway:<br> `ib_exec_group_status{brokername="BRK1",egname="EG1",instance="",job="BRK1"} 1` |
65-
| ib_application_status | The metric shows current status of IB application.<br /> If there are several applications on host, there will be a own metric for each application.<br> Possible values:<br> <span style="margin-left:2em">`0` - STOPPED;</span><br> <span style="margin-left:2em">`1` - RUNNING.</span><br> Example display in Pushgateway:<br> `ib_application_status{appname="Application1",brokername="BRK1",egname="EG1",instance="",job="BRK1"} 1` |
66-
| ib_message_flow_status | The metric shows current status of IB message flow.<br /> If there are several message flows on host, there will be a own metric for each message flow.<br> Possible values:<br> <span style="margin-left:2em">`0` - STOPPED;</span><br> <span style="margin-left:2em">`1` - RUNNING.</span><br> Example display in Pushgateway:<br> `ib_message_flow_status{appname="Application1",brokername="BRK1",egname="EG1",instance="",job="BRK1",messageflowname="adapter.reply"} 1` |
63+
| ib_broker_status | The metric shows current status of IB broker.<br> Metric type: `gauge`.<br> If there are several brokers on host, there will be a own metric for each broker.<br> Possible values:<br> <span style="margin-left:2em">`0` - STOPPED;</span><br> <span style="margin-left:2em">`1` - RUNNING.</span><br> Example display in Pushgateway:<br> `ib_broker_status{brokername="BRK1",instance="",job="BRK1",qmname="QM1"} 1` |
64+
| ib_exec_group_status | The metric shows current status of IB execution group.<br> Metric type: `gauge`.<br> If there are several execution groups on host, there will be a own metric for each execution group.<br> Possible values:<br> <span style="margin-left:2em">`0` - STOPPED;</span><br> <span style="margin-left:2em">`1` - RUNNING.</span><br> Example display in Pushgateway:<br> `ib_exec_group_status{brokername="BRK1",egname="EG1",instance="",job="BRK1"} 1` |
65+
| ib_application_status | The metric shows current status of IB application.<br> Metric type: `gauge`.<br> If there are several applications on host, there will be a own metric for each application.<br> Possible values:<br> <span style="margin-left:2em">`0` - STOPPED;</span><br> <span style="margin-left:2em">`1` - RUNNING.</span><br> Example display in Pushgateway:<br> `ib_application_status{appname="Application1",brokername="BRK1",egname="EG1",instance="",job="BRK1"} 1` |
66+
| ib_message_flow_status | The metric shows current status of IB message flow.<br> Metric type: `gauge`.<br> If there are several message flows on host, there will be a own metric for each message flow.<br> Possible values:<br> <span style="margin-left:2em">`0` - STOPPED;</span><br> <span style="margin-left:2em">`1` - RUNNING.</span><br> Example display in Pushgateway:<br> `ib_message_flow_status{appname="Application1",brokername="BRK1",egname="EG1",instance="",job="BRK1",messageflowname="adapter.reply"} 1` |

iib_metrics_client.py

Lines changed: 38 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,178 +1,97 @@
11
# -*- coding: utf-8 -*-
2-
import requests
3-
from log.logger_client import set_logger
4-
from requests import ConnectionError
5-
from urllib3.exceptions import ResponseError
2+
"""Python client for collecting IBM Integration Bus metrics and exporting to Prometheus pushgateway."""
63
import sys
4+
import time
75
import traceback
86
import platform
9-
import time
7+
import requests
8+
from requests import ConnectionError
9+
from urllib3.exceptions import ResponseError
10+
from modules.iib_brokers import (
11+
get_brokers_status,
12+
format_broker,
13+
get_broker_items)
14+
from modules.iib_exec_groups import format_exec_groups
15+
from modules.iib_applications import format_applications
16+
from modules.iib_message_flows import format_message_flows
17+
from log.logger_client import set_logger
1018
from modules.iib_api import run_iib_command
1119

1220

1321
logger = set_logger()
1422

15-
STATUS_MAP = {
16-
'running.': 1,
17-
'stopped.': 0
18-
}
19-
2023

2124
class PrometheusBadResponse(Exception):
2225
pass
2326

2427

28+
def static_content():
29+
"""Client name and version."""
30+
name = "ib-metrics-pyclient"
31+
version = "0.2"
32+
return '{0} v.{1}'.format(name, version)
33+
34+
2535
def put_metric_to_gateway(metric_data, job):
36+
"""Sends data to Prometheus pushgateway."""
2637
hostname = platform.node()
2738
port = 9091
2839
src_url = "http://{0}:{1}".format(hostname, port)
2940
headers = {"Content-Type": "text/plain; version=0.0.4"}
3041
dest_url = "{0}/metrics/job/{1}".format(src_url, job)
3142
logger.info("Destination url: {0}".format(dest_url))
43+
# Debug info
3244
# logger.info("Metric data to push: {0}".format(metric_data))
3345
try:
3446
response = requests.put(dest_url, data=metric_data, headers=headers)
3547
if not response.ok:
36-
raise PrometheusBadResponse("Bad response - {0} \
37-
from {1}\nResponseText: {2}".format(
38-
response,
39-
dest_url,
40-
response.text
41-
))
48+
raise PrometheusBadResponse("Bad response - {0} from {1}\nResponseText: {2}".format(response, dest_url, response.text))
4249
logger.info("Success! Server response: {0}".format(response))
4350
except (ConnectionError, ResponseError):
4451
raise PrometheusBadResponse("{0} is not available!".format(dest_url))
4552

4653

47-
def get_brokers_status(brokers_data):
48-
output_list = brokers_data.split('\n')
49-
brokers = []
50-
for record in filter(None, output_list):
51-
record_list = record.split()
52-
broker_name = record_list[2].replace("'", "")
53-
qm_name = record_list[6].replace("'", "")
54-
status = record_list[8].replace("'", "")
55-
brokers.append([broker_name, status, qm_name])
56-
return brokers
57-
58-
59-
def get_broker_items(broker_row_data):
60-
output_list = broker_row_data.split('\n')
61-
exec_groups = []
62-
applications = []
63-
message_flows = []
64-
# See IBM diagnostic messages:
65-
# https://www.ibm.com/support/knowledgecenter/en/SSMKHH_9.0.0/com.ibm.etools.mft.bipmsgs.doc/ay_bip1.htm
66-
# Also you can use command: mqsiexplain <bip_code>
67-
bip_codes = {
68-
'BIP1286I': exec_groups,
69-
'BIP1287I': exec_groups,
70-
'BIP1275I': applications,
71-
'BIP1276I': applications,
72-
'BIP1277I': message_flows,
73-
'BIP1278I': message_flows
74-
}
75-
for record in output_list:
76-
if record:
77-
bip_code = record.split()[0].replace(':', '')
78-
if bip_code in bip_codes.keys():
79-
bip_codes[bip_code].append(record)
80-
return exec_groups, applications, message_flows
81-
82-
83-
def format_broker(broker_name, status, qm_name):
84-
broker_metric = 'ib_broker_status{brokername="%s", qmname="%s"} %d\n' % (
85-
broker_name,
86-
qm_name,
87-
STATUS_MAP[status]
88-
)
89-
return broker_metric
90-
91-
92-
def format_applications(applications, broker_name):
93-
app_metric_data = ''
94-
for app in applications:
95-
app_list = app.split()
96-
egname, app_name, status = app_list[6], app_list[2], app_list[8]
97-
app_metric = 'ib_application_status{egname="%s", brokername="%s", appname="%s"} %d\n' % (
98-
egname.replace("'", ""),
99-
broker_name,
100-
app_name.replace("'", ""),
101-
STATUS_MAP[status]
102-
)
103-
app_metric_data += app_metric
104-
return app_metric_data
105-
106-
107-
def format_exec_groups(exec_groups):
108-
eg_metric_data = ''
109-
for eg in exec_groups:
110-
eg_list = eg.split()
111-
broker_name, egname, status = eg_list[6], eg_list[3], eg_list[8]
112-
eg_metric = 'ib_exec_group_status{brokername="%s", egname="%s"} %d\n' % (
113-
broker_name.replace("'", ""),
114-
egname.replace("'", ""),
115-
STATUS_MAP[status]
116-
)
117-
eg_metric_data += eg_metric
118-
return eg_metric_data
119-
120-
121-
def format_message_flows(message_flows, broker_name):
122-
msg_flow_metric_data = ''
123-
for msg_flow in message_flows:
124-
msg_flow_list = msg_flow.split()
125-
egname, app_name, message_flow_name, status = msg_flow_list[7], msg_flow_list[11], msg_flow_list[3], msg_flow_list[9]
126-
msg_flow_metric = 'ib_message_flow_status{egname="%s", brokername="%s", appname="%s", messageflowname="%s"} %d\n' % (
127-
egname.replace("'", ""),
128-
broker_name,
129-
app_name.replace("'", "").replace(",", ""),
130-
message_flow_name.replace("'", ""),
131-
STATUS_MAP[status]
132-
)
133-
msg_flow_metric_data += msg_flow_metric
134-
return msg_flow_metric_data
135-
136-
13754
def main():
13855
start_time = time.time()
13956
logger.info("Starting metrics collecting for Integration Bus!")
14057
try:
14158
brokers_data = run_iib_command(task='get_brokers_status')
142-
brokers = get_brokers_status(brokers_data)
59+
brokers = get_brokers_status(brokers_data=brokers_data)
14360
for broker in brokers:
14461
broker_name, status, qm_name = broker
145-
broker_data = format_broker(broker_name, status, qm_name)
62+
broker_data = format_broker(
63+
broker_name=broker_name,
64+
status=status,
65+
qm_name=qm_name)
14666
if status == 'running.':
14767
broker_row_data = run_iib_command(
14868
task='get_broker_objects',
149-
broker_name=broker_name
150-
)
151-
exec_groups, applications, message_flows = get_broker_items(broker_row_data)
152-
exec_groups_data = format_exec_groups(exec_groups)
153-
applications_data = format_applications(applications, broker_name)
154-
message_flows_data = format_message_flows(message_flows, broker_name)
69+
broker_name=broker_name)
70+
exec_groups, applications, message_flows = get_broker_items(broker_row_data=broker_row_data)
71+
exec_groups_data = format_exec_groups(exec_groups=exec_groups)
72+
applications_data = format_applications(applications=applications, broker_name=broker_name)
73+
message_flows_data = format_message_flows(message_flows=message_flows, broker_name=broker_name)
15574
metric_data = "{0}{1}{2}{3}".format(
15675
broker_data,
15776
exec_groups_data,
15877
applications_data,
159-
message_flows_data
160-
)
161-
put_metric_to_gateway(metric_data, broker_name)
78+
message_flows_data)
79+
put_metric_to_gateway(metric_data=metric_data, job=broker_name)
16280
logger.info("All metrics pushed successfully!")
16381
else:
82+
put_metric_to_gateway(metric_data=broker_data, job=broker_name)
16483
logger.warning("The status of broker is {0}\nOther metrics will not be collected!".format(status))
165-
put_metric_to_gateway(broker_data, broker_name)
84+
logger.info("Script finished in - {0} seconds -".format(time.time() - start_time))
16685
except PrometheusBadResponse as error:
16786
logger.error(error)
16887
except Exception as e:
16988
tb = sys.exc_info()[-1]
17089
stk = traceback.extract_tb(tb, 1)[0]
17190
logger.error("Function: {0}\n{1}".format(stk, e))
172-
logger.info("Script finished in - %s seconds -" % (time.time() - start_time))
17391

17492

17593
if __name__ == "__main__":
94+
logger.info("Run {0}".format(static_content()))
17695
while True:
17796
main()
17897
time.sleep(60)

log/logger_client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# -*- coding: utf-8 -*-
2+
"""Various functions for logging."""
23
import os
34
import logging
45
from logging.handlers import RotatingFileHandler
56

67

78
def set_logger():
9+
"""Sets logger."""
810
logs_dir = os.getenv("METRICS_LOGS_PATH")
911
if logs_dir:
1012
log_path = os.path.join(logs_dir, 'iib_client.log')
@@ -20,4 +22,4 @@ def set_logger():
2022
handler = RotatingFileHandler(log_path, maxBytes=max_file_size, backupCount=3, encoding='utf-8')
2123
handler.setFormatter(formatter)
2224
logger.addHandler(handler)
23-
return logger
25+
return logger

modules/iib_api.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
# -*- coding: utf-8 -*-
2+
"""Various functions for client api."""
23
import subprocess
34

45

56
def run_iib_command(**kwargs):
7+
"""Calls predefined commands and returns their result."""
68
command_mapping = {
79
'get_brokers_status': 'mqsilist | grep Broker',
810
'get_broker_objects': 'mqsilist {0} -r',
911
}
10-
broker = ''
12+
broker = str()
1113
for arg_name, arg_value in kwargs.items():
1214
if arg_name == 'task':
1315
iib_command = command_mapping[arg_value]
@@ -17,10 +19,24 @@ def run_iib_command(**kwargs):
1719
command = iib_command.format(broker)
1820
else:
1921
command = iib_command
22+
output = execute_command(command=command)
23+
return output
24+
25+
26+
def execute_command(command):
27+
"""Executes in shell."""
2028
proc = subprocess.Popen(command,
2129
shell=True,
2230
stdout=subprocess.PIPE,
2331
stderr=subprocess.STDOUT,
2432
universal_newlines=True)
25-
output = proc.communicate()[0]
26-
return output
33+
result = proc.communicate()[0]
34+
return result
35+
36+
37+
def get_status(status):
38+
"""Returns a numeric status value."""
39+
status_map = {
40+
'running.': 1,
41+
'stopped.': 0}
42+
return status_map[status]

modules/iib_applications.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# -*- coding: utf-8 -*-
2+
"""Various functions for ib applications."""
3+
from modules.iib_api import get_status
4+
5+
6+
def get_metric_name(metric_label):
7+
"""Returns pushgateway formatted metric name."""
8+
return 'ib_application_{0}'.format(metric_label)
9+
10+
11+
def get_metric_annotation():
12+
"""Returns dictionary with annotations 'HELP' and 'TYPE' for metrics."""
13+
annotations = {
14+
'status': '# HELP {0} Current status of IB application.\n\
15+
# TYPE {0} gauge\n'.format(get_metric_name('status'))}
16+
return annotations
17+
18+
19+
def format_applications(applications, broker_name):
20+
"""Returns string with all metrics for all applications which ready to push to pushgateway."""
21+
metrics_annotation = get_metric_annotation()
22+
app_metric_data = str()
23+
for app in applications:
24+
app_list = app.split()
25+
egname, app_name, status = app_list[6], app_list[2], app_list[8]
26+
template_string = 'egname="{0}", brokername="{1}", appname="{2}"'.format(
27+
egname.replace("'", ""),
28+
broker_name,
29+
app_name.replace("'", ""))
30+
app_metric = '{0}{{{1}}} {2}\n'.format(
31+
get_metric_name(metric_label='status'),
32+
template_string,
33+
get_status(status=status))
34+
app_metric_data += app_metric
35+
app_metric_data = '{0}{1}'.format(
36+
metrics_annotation['status'],
37+
app_metric_data)
38+
return app_metric_data

0 commit comments

Comments
 (0)