Skip to content

Commit bab1a2c

Browse files
authored
Merge pull request #33 from Cinimex-Informatica/feature/issue9_additional_metrics
Feature/issue9 additional metrics Resolves: #9
2 parents af87d36 + e1618d2 commit bab1a2c

17 files changed

+905
-125
lines changed

src/main/java/ru/cinimex/exporter/Config.java

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@ public class Config {
2020
private String qmgrChannel;
2121
private String user;
2222
private String password;
23-
private Boolean mqscp;
23+
private boolean mqscp;
2424
private int endpPort;
2525
private String endpURL;
2626
private ArrayList<String> queues;
27+
private ArrayList<String> channels;
28+
private ArrayList<String> listeners;
29+
private boolean sendPCFCommands;
30+
private boolean usePCFWildcards;
31+
private int scrapeInterval;
2732

2833
public Config(String path) {
2934
Yaml file = new Yaml();
@@ -38,26 +43,48 @@ public Config(String path) {
3843
LinkedHashMap<String, Object> config = file.load(br);
3944
HashMap<String, Object> qmgrConnectionParams = (HashMap<String, Object>) config.get("qmgrConnectionParams");
4045
HashMap<String, Object> prometheusEndpointParams = (HashMap<String, Object>) config.get("prometheusEndpointParams");
46+
HashMap<String, Object> pcfParameters = (HashMap<String, Object>) config.get("PCFParameters");
4147
this.qmgrName = (String) qmgrConnectionParams.get("qmgrName");
4248
this.qmgrHost = (String) qmgrConnectionParams.get("qmgrHost");
43-
this.qmgrPort = (Integer) (qmgrConnectionParams.get("qmgrPort"));
49+
this.qmgrPort = (Integer) qmgrConnectionParams.get("qmgrPort");
4450
this.qmgrChannel = (String) qmgrConnectionParams.get("qmgrChannel");
4551
this.user = (String) qmgrConnectionParams.get("user");
4652
this.password = (String) qmgrConnectionParams.get("password");
47-
this.mqscp = (Boolean) qmgrConnectionParams.get("mqscp");
53+
this.mqscp = (boolean) qmgrConnectionParams.get("mqscp");
4854
queues = (ArrayList<String>) config.get("queues");
49-
this.endpPort = (Integer) (prometheusEndpointParams.get("port"));
55+
listeners = (ArrayList<String>) config.get("listeners");
56+
channels = (ArrayList<String>) config.get("channels");
57+
this.endpPort = (Integer) prometheusEndpointParams.get("port");
5058
this.endpURL = (String) (prometheusEndpointParams.get("url"));
59+
this.sendPCFCommands = (boolean) pcfParameters.get("sendPCFCommands");
60+
this.usePCFWildcards = (boolean) pcfParameters.get("usePCFWildcards");
61+
this.scrapeInterval = (Integer) pcfParameters.get("scrapeInterval");
5162
}
5263

53-
public Boolean getMqscp() {
64+
public boolean useMqscp() {
5465
return mqscp;
5566
}
5667

5768
public String getQmgrName() {
5869
return qmgrName;
5970
}
6071

72+
public boolean sendPCFCommands() {
73+
return sendPCFCommands;
74+
}
75+
76+
public boolean usePCFWildcards() {
77+
return usePCFWildcards;
78+
}
79+
80+
public ArrayList<String> getChannels() {
81+
return channels;
82+
}
83+
84+
public ArrayList<String> getListeners() {
85+
return listeners;
86+
}
87+
6188
public String getQmgrHost() {
6289
return qmgrHost;
6390
}
@@ -66,6 +93,10 @@ public int getQmgrPort() {
6693
return qmgrPort;
6794
}
6895

96+
public int getScrapeInterval() {
97+
return scrapeInterval;
98+
}
99+
69100
public String getQmgrChannel() {
70101
return qmgrChannel;
71102
}

src/main/java/ru/cinimex/exporter/ExporterLauncher.java

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
import com.ibm.mq.constants.MQConstants;
88
import com.ibm.mq.pcf.PCFMessage;
99
import ru.cinimex.exporter.mq.MQConnection;
10+
import ru.cinimex.exporter.mq.MQObject;
1011
import ru.cinimex.exporter.mq.MQSubscriberManager;
1112
import ru.cinimex.exporter.mq.pcf.PCFClass;
1213
import ru.cinimex.exporter.mq.pcf.PCFDataParser;
1314
import ru.cinimex.exporter.mq.pcf.PCFElement;
1415
import ru.cinimex.exporter.mq.pcf.PCFType;
1516
import ru.cinimex.exporter.prometheus.HTTPServer;
1617
import ru.cinimex.exporter.prometheus.Registry;
17-
import ru.cinimex.exporter.prometheus.metrics.GaugeManager;
18+
import ru.cinimex.exporter.prometheus.metrics.MetricsManager;
1819

1920
import java.io.IOException;
2021
import java.net.InetSocketAddress;
@@ -27,25 +28,49 @@ public class ExporterLauncher {
2728
private static final String topicString = "$SYS/MQ/INFO/QMGR/%s/Monitor/METADATA/CLASSES";
2829
private static final int getMsgOpt = MQConstants.MQGMO_WAIT | MQConstants.MQGMO_COMPLETE_MSG | MQConstants.MQGMO_SYNCPOINT;
2930

30-
public static void main(String[] args) {
31+
public static void main(String[] args) throws MQException, IOException {
3132
if (args.length == 0) {
3233
System.err.println("It seems that you forgot to specify the path to the config file.");
3334
System.exit(1);
3435
}
3536
Config config = new Config(args[0]);
3637
try {
3738
ArrayList<PCFElement> elements = getAllPublishedMetrics(config);
38-
GaugeManager.initGauges(elements);
39-
MQSubscriberManager manager = new MQSubscriberManager(config.getQmgrHost(), config.getQmgrPort(), config.getQmgrChannel(), config.getQmgrName(), config.getUser(), config.getPassword(), config.getMqscp());
40-
manager.runSubscribers(elements, config.getQueues());
39+
ArrayList<MQObject.MQType> monitoringTypes = new ArrayList<>();
40+
ArrayList<MQObject> objects = new ArrayList<>();
41+
42+
if (config.sendPCFCommands()) {
43+
if (config.getQueues().size() > 0) {
44+
monitoringTypes.add(MQObject.MQType.QUEUE);
45+
for (String queueName : config.getQueues()) {
46+
objects.add(new MQObject(queueName, MQObject.MQType.QUEUE));
47+
}
48+
}
49+
if (config.getChannels().size() > 0) {
50+
monitoringTypes.add(MQObject.MQType.CHANNEL);
51+
for (String channelName : config.getChannels()) {
52+
objects.add(new MQObject(channelName, MQObject.MQType.CHANNEL));
53+
}
54+
}
55+
if (config.getListeners().size() > 0) {
56+
monitoringTypes.add(MQObject.MQType.LISTENER);
57+
for (String listenerName : config.getListeners()) {
58+
objects.add(new MQObject(listenerName, MQObject.MQType.LISTENER));
59+
}
60+
}
61+
}
62+
MetricsManager.initMetrics(elements, monitoringTypes);
63+
MQSubscriberManager manager = new MQSubscriberManager(config.getQmgrHost(), config.getQmgrPort(), config.getQmgrChannel(), config.getQmgrName(), config.getUser(), config.getPassword(), config.useMqscp());
64+
manager.runSubscribers(elements, objects, config.sendPCFCommands(), config.usePCFWildcards(), config.getScrapeInterval());
4165
new HTTPServer(new InetSocketAddress("0.0.0.0", config.getEndpPort()), config.getEndpURL(), Registry.getRegistry(), false);
42-
} catch (IOException e) {
43-
System.err.println(e.getStackTrace());
66+
} catch (Exception e) {
67+
System.err.println(e.getMessage());
4468
}
4569
}
4670

4771
/**
4872
* Method goes through system topics structure and returns metrics headers, which are represented by PCFElement
73+
*
4974
* @param config - parsed config file.
5075
* @return - array, filled with metrics headers.
5176
*/
@@ -56,7 +81,7 @@ private static ArrayList<PCFElement> getAllPublishedMetrics(Config config) {
5681
MQGetMessageOptions gmo = new MQGetMessageOptions();
5782
gmo.options = getMsgOpt;
5883
gmo.waitInterval = 30000;
59-
connection.establish(config.getQmgrHost(), config.getQmgrPort(), config.getQmgrChannel(), config.getQmgrName(), config.getUser(), config.getPassword(), config.getMqscp());
84+
connection.establish(config.getQmgrHost(), config.getQmgrPort(), config.getQmgrChannel(), config.getQmgrName(), config.getUser(), config.getPassword(), config.useMqscp());
6085

6186
try {
6287
topic = connection.createTopic(String.format(topicString, config.getQmgrName()));
@@ -79,7 +104,7 @@ private static ArrayList<PCFElement> getAllPublishedMetrics(Config config) {
79104
}
80105
}
81106
} catch (Exception e) {
82-
System.err.println(e.getStackTrace());
107+
System.err.println(e.getMessage());
83108
} finally {
84109
try {
85110
if (topic != null && topic.isOpen()) {

src/main/java/ru/cinimex/exporter/mq/MQConnection.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
import java.util.Hashtable;
1010

1111
/**
12-
* Class represents MQ connection
12+
* Class represents MQ connection.
1313
*/
1414
public class MQConnection {
1515
private Hashtable<String, Object> connectionProperties;
1616
private MQQueueManager queueManager;
1717

1818
/**
19-
* Default constructor
19+
* Default constructor.
2020
*/
2121
public MQConnection() {
2222

@@ -26,10 +26,10 @@ public MQConnection() {
2626
* Method creates connection properties Hashtable from connection parameters.
2727
*
2828
* @param host - host, where queue manager is located.
29-
* @param port - queue manager's port
30-
* @param channel - queue manager's channel
31-
* @param user - user, which has enough privilege on the queue manager (optional)
32-
* @param password - password, which is required to establish connection with queue manager (optional)
29+
* @param port - queue manager's port.
30+
* @param channel - queue manager's channel.
31+
* @param user - user, which has enough privilege on the queue manager (optional).
32+
* @param password - password, which is required to establish connection with queue manager (optional).
3333
* @param useMQCSP - flag, which indicates, if MQCSP auth should be used.
3434
* @return - returns prepared structure with all parameters transformed into queue manager's format.
3535
*/
@@ -63,7 +63,7 @@ public void establish(String host, int port, String channel, String qmName, Stri
6363
try {
6464
queueManager = new MQQueueManager(qmName, connectionProperties);
6565
} catch (MQException e) {
66-
System.err.println(e.getStackTrace());
66+
System.err.println(e.getMessage());
6767
}
6868
}
6969

@@ -78,7 +78,7 @@ public void establish(String qmNqme, Hashtable<String, Object> connectionPropert
7878
try {
7979
queueManager = new MQQueueManager(qmNqme, connectionProperties);
8080
} catch (MQException e) {
81-
System.err.println(e.getStackTrace());
81+
System.err.println(e.getMessage());
8282
}
8383
}
8484

@@ -90,7 +90,7 @@ public void close() {
9090
try {
9191
queueManager.disconnect();
9292
} catch (MQException e) {
93-
System.err.println(e.getStackTrace());
93+
System.err.println(e.getMessage());
9494
}
9595
}
9696
}
@@ -105,4 +105,12 @@ public void close() {
105105
public MQTopic createTopic(String topic) throws MQException {
106106
return queueManager.accessTopic(topic, "", CMQC.MQTOPIC_OPEN_AS_SUBSCRIPTION, CMQC.MQSO_CREATE | CMQC.MQSO_NON_DURABLE | CMQC.MQSO_MANAGED);
107107
}
108+
109+
/**
110+
* Returns MQQueueManager object.
111+
* @return - MQQueueManager object.
112+
*/
113+
public MQQueueManager getQueueManager() {
114+
return this.queueManager;
115+
}
108116
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package ru.cinimex.exporter.mq;
2+
3+
import com.ibm.mq.constants.MQConstants;
4+
import com.ibm.mq.pcf.PCFMessage;
5+
6+
import java.util.HashMap;
7+
import java.util.Iterator;
8+
import java.util.Map;
9+
10+
/**
11+
* Class represents MQObject (Queue, channel or listener). It stores object type and all PCFParameters, required for correct request.
12+
*/
13+
public class MQObject {
14+
private String name;
15+
private MQType type;
16+
private PCFMessage PCFCmd;
17+
private int PCFHeader;
18+
19+
/**
20+
* MQObject constructor.
21+
*
22+
* @param name - object name.
23+
* @param type - object type.
24+
*/
25+
public MQObject(String name, MQType type) {
26+
this.name = name;
27+
this.type = type;
28+
/**
29+
* PCF commands are used to retrieve some specific statistics from queue manager.
30+
*/
31+
switch (type) {
32+
case QUEUE:
33+
PCFCmd = new PCFMessage(MQConstants.MQCMD_INQUIRE_Q); //if object type is queue, exporter would inquire it.
34+
PCFCmd.addParameter(MQConstants.MQCA_Q_NAME, name); //PCF command would try to retrieve statistics about queue with specific name
35+
PCFCmd.addParameter(MQConstants.MQIA_Q_TYPE, MQConstants.MQQT_LOCAL); // and specific type
36+
PCFHeader = MQConstants.MQIA_MAX_Q_DEPTH; //the only statistics we want to know about queue is it's max depth.
37+
break;
38+
case LISTENER:
39+
PCFCmd = new PCFMessage(MQConstants.MQCMD_INQUIRE_LISTENER_STATUS); //if object type is listener, exporter would inquire it.
40+
PCFCmd.addParameter(MQConstants.MQCACH_LISTENER_NAME, name);//PCF command would try to retrieve statistics about listener with specific name
41+
PCFHeader = MQConstants.MQIACH_LISTENER_STATUS;//the only statistics we want to know about listener is it's status.
42+
break;
43+
case CHANNEL:
44+
PCFCmd = new PCFMessage(MQConstants.MQCMD_INQUIRE_CHANNEL_STATUS); //if object type is channel, exporter would inquire it.
45+
PCFCmd.addParameter(MQConstants.MQCACH_CHANNEL_NAME, name); //PCF command would try to retrieve statistics about channel with specific name
46+
PCFHeader = MQConstants.MQIACH_CHANNEL_STATUS;//the only statistics we want to know about channel is it's status.
47+
break;
48+
default:
49+
//TODO:Exception
50+
}
51+
}
52+
53+
/**
54+
* This method returns MQConstant int code, which represents name for input object.
55+
*
56+
* @param type - object type.
57+
* @return - integer code.
58+
*/
59+
public static int objectNameCode(MQObject.MQType type) {
60+
int code = -1;
61+
switch (type) {
62+
case QUEUE:
63+
code = MQConstants.MQCA_Q_NAME;
64+
break;
65+
case CHANNEL:
66+
code = MQConstants.MQCACH_CHANNEL_NAME;
67+
break;
68+
case LISTENER:
69+
code = MQConstants.MQCACH_LISTENER_NAME;
70+
break;
71+
}
72+
return code;
73+
}
74+
75+
76+
/**
77+
* Getter for object name.
78+
*
79+
* @return object name.
80+
*/
81+
public String getName() {
82+
return name;
83+
}
84+
85+
/**
86+
* Getter for PCFHeader.
87+
*
88+
* @return - MQConstant integer code.
89+
*/
90+
public int getPCFHeader() {
91+
return PCFHeader;
92+
}
93+
94+
/**
95+
* Getter for object type.
96+
*
97+
* @return object type.
98+
*/
99+
public MQType getType() {
100+
return type;
101+
}
102+
103+
/**
104+
* Getter for PCF command.
105+
*
106+
* @return - prepared PCF command object.
107+
*/
108+
public PCFMessage getPCFCmd() {
109+
return PCFCmd;
110+
}
111+
112+
/**
113+
* This enum represents all supported MQObject types.
114+
*/
115+
public enum MQType {
116+
QUEUE, CHANNEL, LISTENER
117+
}
118+
}

0 commit comments

Comments
 (0)