Skip to content

Commit d070dcd

Browse files
authored
Merge pull request #75 from Cinimex-Informatica/develop
Release 0.1.2.
2 parents 931b801 + 542b095 commit d070dcd

26 files changed

+1505
-267
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.metadata/
2+
log/
23
*.class
34
**/target/
45
*.jar

README.md

Lines changed: 281 additions & 61 deletions
Large diffs are not rendered by default.

pom.xml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
<mq.allclient.version>9.0.0.1</mq.allclient.version>
1212
<snakeyaml.version>1.23</snakeyaml.version>
1313
<prometheus.version>0.6.0</prometheus.version>
14-
<mq.allclient.jar.path>./lib/com.ibm.mq.allclient.jar</mq.allclient.jar.path>
14+
<log4j.version>2.11.2</log4j.version>
15+
<mq.allclient.jar.path>/lib/com.ibm.mq.allclient.jar</mq.allclient.jar.path>
1516
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1617
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
1718
</properties>
@@ -23,6 +24,8 @@
2324
<groupId>com.ibm.mq</groupId>
2425
<artifactId>com.ibm.mq.allclient</artifactId>
2526
<version>${mq.allclient.version}</version>
27+
<scope>system</scope>
28+
<systemPath>${basedir}${mq.allclient.jar.path}</systemPath>
2629
</dependency>
2730
<dependency>
2831
<groupId>org.yaml</groupId>
@@ -39,9 +42,19 @@
3942
<artifactId>simpleclient_common</artifactId>
4043
<version>${prometheus.version}</version>
4144
</dependency>
45+
<dependency>
46+
<groupId>org.apache.logging.log4j</groupId>
47+
<artifactId>log4j-api</artifactId>
48+
<version>${log4j.version}</version>
49+
</dependency>
50+
<dependency>
51+
<groupId>org.apache.logging.log4j</groupId>
52+
<artifactId>log4j-core</artifactId>
53+
<version>${log4j.version}</version>
54+
</dependency>
4255
</dependencies>
4356
<build>
44-
<finalName>webspheremq_exporter</finalName>
57+
<finalName>mq_exporter</finalName>
4558
<plugins>
4659
<!-- Set a JDK compiler level -->
4760
<plugin>
@@ -59,6 +72,10 @@
5972
<artifactId>maven-jar-plugin</artifactId>
6073
<version>3.1.1</version>
6174
<configuration>
75+
<excludes>
76+
<exclude>**/exporter_config.yaml</exclude>
77+
<exclude>**/log4j2.properties</exclude>
78+
</excludes>
6279
<archive>
6380
<manifest>
6481
<!-- Jar file entry point -->

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

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package ru.cinimex.exporter;
22

3+
import org.apache.logging.log4j.LogManager;
4+
import org.apache.logging.log4j.Logger;
35
import org.yaml.snakeyaml.Yaml;
46

57
import java.io.BufferedReader;
@@ -14,16 +16,22 @@
1416
* Class is used for parsing config file.
1517
*/
1618
public class Config {
19+
private static final Logger logger = LogManager.getLogger(Config.class);
1720
private String qmgrName;
1821
private String qmgrHost;
1922
private int qmgrPort;
2023
private String qmgrChannel;
2124
private String user;
2225
private String password;
23-
private Boolean mqscp;
26+
private boolean mqscp;
2427
private int endpPort;
2528
private String endpURL;
2629
private ArrayList<String> queues;
30+
private ArrayList<String> channels;
31+
private ArrayList<String> listeners;
32+
private boolean sendPCFCommands;
33+
private boolean usePCFWildcards;
34+
private int scrapeInterval;
2735

2836
public Config(String path) {
2937
Yaml file = new Yaml();
@@ -32,32 +40,55 @@ public Config(String path) {
3240
try {
3341
br = new BufferedReader(new FileReader(rawFile));
3442
} catch (FileNotFoundException e) {
35-
System.err.println(String.format("Unable to locate config file. Make sure %s is valid path.", path));
43+
logger.error("Unable to locate config file. Make sure \"{}\" is a valid path.", path);
3644
System.exit(1);
3745
}
3846
LinkedHashMap<String, Object> config = file.load(br);
3947
HashMap<String, Object> qmgrConnectionParams = (HashMap<String, Object>) config.get("qmgrConnectionParams");
4048
HashMap<String, Object> prometheusEndpointParams = (HashMap<String, Object>) config.get("prometheusEndpointParams");
49+
HashMap<String, Object> pcfParameters = (HashMap<String, Object>) config.get("PCFParameters");
4150
this.qmgrName = (String) qmgrConnectionParams.get("qmgrName");
4251
this.qmgrHost = (String) qmgrConnectionParams.get("qmgrHost");
43-
this.qmgrPort = (Integer) (qmgrConnectionParams.get("qmgrPort"));
52+
this.qmgrPort = (Integer) qmgrConnectionParams.get("qmgrPort");
4453
this.qmgrChannel = (String) qmgrConnectionParams.get("qmgrChannel");
4554
this.user = (String) qmgrConnectionParams.get("user");
4655
this.password = (String) qmgrConnectionParams.get("password");
47-
this.mqscp = (Boolean) qmgrConnectionParams.get("mqscp");
56+
this.mqscp = (boolean) qmgrConnectionParams.get("mqscp");
4857
queues = (ArrayList<String>) config.get("queues");
49-
this.endpPort = (Integer) (prometheusEndpointParams.get("port"));
58+
listeners = (ArrayList<String>) config.get("listeners");
59+
channels = (ArrayList<String>) config.get("channels");
60+
this.endpPort = (Integer) prometheusEndpointParams.get("port");
5061
this.endpURL = (String) (prometheusEndpointParams.get("url"));
62+
this.sendPCFCommands = (boolean) pcfParameters.get("sendPCFCommands");
63+
this.usePCFWildcards = (boolean) pcfParameters.get("usePCFWildcards");
64+
this.scrapeInterval = (Integer) pcfParameters.get("scrapeInterval");
65+
logger.info("Successfully parsed configuration file!");
5166
}
5267

53-
public Boolean getMqscp() {
68+
public boolean useMqscp() {
5469
return mqscp;
5570
}
5671

5772
public String getQmgrName() {
5873
return qmgrName;
5974
}
6075

76+
public boolean sendPCFCommands() {
77+
return sendPCFCommands;
78+
}
79+
80+
public boolean usePCFWildcards() {
81+
return usePCFWildcards;
82+
}
83+
84+
public ArrayList<String> getChannels() {
85+
return channels;
86+
}
87+
88+
public ArrayList<String> getListeners() {
89+
return listeners;
90+
}
91+
6192
public String getQmgrHost() {
6293
return qmgrHost;
6394
}
@@ -66,6 +97,10 @@ public int getQmgrPort() {
6697
return qmgrPort;
6798
}
6899

100+
public int getScrapeInterval() {
101+
return scrapeInterval;
102+
}
103+
69104
public String getQmgrChannel() {
70105
return qmgrChannel;
71106
}

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

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@
66
import com.ibm.mq.MQTopic;
77
import com.ibm.mq.constants.MQConstants;
88
import com.ibm.mq.pcf.PCFMessage;
9+
import org.apache.logging.log4j.LogManager;
10+
import org.apache.logging.log4j.Logger;
911
import ru.cinimex.exporter.mq.MQConnection;
12+
import ru.cinimex.exporter.mq.MQObject;
1013
import ru.cinimex.exporter.mq.MQSubscriberManager;
1114
import ru.cinimex.exporter.mq.pcf.PCFClass;
1215
import ru.cinimex.exporter.mq.pcf.PCFDataParser;
1316
import ru.cinimex.exporter.mq.pcf.PCFElement;
1417
import ru.cinimex.exporter.mq.pcf.PCFType;
1518
import ru.cinimex.exporter.prometheus.HTTPServer;
1619
import ru.cinimex.exporter.prometheus.Registry;
17-
import ru.cinimex.exporter.prometheus.metrics.GaugeManager;
20+
import ru.cinimex.exporter.prometheus.metrics.MetricsManager;
1821

1922
import java.io.IOException;
2023
import java.net.InetSocketAddress;
@@ -24,28 +27,53 @@
2427
* Main class of mq exporter tool. Parses config, scans topics, starts subscribers.
2528
*/
2629
public class ExporterLauncher {
30+
private static final Logger logger = LogManager.getLogger(ExporterLauncher.class);
2731
private static final String topicString = "$SYS/MQ/INFO/QMGR/%s/Monitor/METADATA/CLASSES";
2832
private static final int getMsgOpt = MQConstants.MQGMO_WAIT | MQConstants.MQGMO_COMPLETE_MSG | MQConstants.MQGMO_SYNCPOINT;
2933

3034
public static void main(String[] args) {
3135
if (args.length == 0) {
32-
System.err.println("It seems that you forgot to specify the path to the config file.");
36+
logger.error("It seems like you forgot to specify path to the config file.");
3337
System.exit(1);
3438
}
3539
Config config = new Config(args[0]);
40+
41+
ArrayList<PCFElement> elements = getAllPublishedMetrics(config);
42+
ArrayList<MQObject.MQType> monitoringTypes = new ArrayList<>();
43+
ArrayList<MQObject> objects = new ArrayList<>();
44+
45+
if (config.getQueues() != null && config.getQueues().size() > 0) {
46+
monitoringTypes.add(MQObject.MQType.QUEUE);
47+
for (String queueName : config.getQueues()) {
48+
objects.add(new MQObject(queueName, MQObject.MQType.QUEUE));
49+
}
50+
}
51+
if (config.getChannels() != null && config.getChannels().size() > 0) {
52+
monitoringTypes.add(MQObject.MQType.CHANNEL);
53+
for (String channelName : config.getChannels()) {
54+
objects.add(new MQObject(channelName, MQObject.MQType.CHANNEL));
55+
}
56+
}
57+
if (config.getListeners() != null && config.getListeners().size() > 0) {
58+
monitoringTypes.add(MQObject.MQType.LISTENER);
59+
for (String listenerName : config.getListeners()) {
60+
objects.add(new MQObject(listenerName, MQObject.MQType.LISTENER));
61+
}
62+
}
63+
64+
MetricsManager.initMetrics(elements, monitoringTypes);
65+
MQSubscriberManager manager = new MQSubscriberManager(config.getQmgrHost(), config.getQmgrPort(), config.getQmgrChannel(), config.getQmgrName(), config.getUser(), config.getPassword(), config.useMqscp());
66+
manager.runSubscribers(elements, objects, config.sendPCFCommands(), config.usePCFWildcards(), config.getScrapeInterval());
3667
try {
37-
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());
4168
new HTTPServer(new InetSocketAddress("0.0.0.0", config.getEndpPort()), config.getEndpURL(), Registry.getRegistry(), false);
4269
} catch (IOException e) {
43-
System.err.println(e.getStackTrace());
70+
logger.error("Error occurred during expanding endpoint for Prometheus: ", e);
4471
}
4572
}
4673

4774
/**
4875
* Method goes through system topics structure and returns metrics headers, which are represented by PCFElement
76+
*
4977
* @param config - parsed config file.
5078
* @return - array, filled with metrics headers.
5179
*/
@@ -56,9 +84,8 @@ private static ArrayList<PCFElement> getAllPublishedMetrics(Config config) {
5684
MQGetMessageOptions gmo = new MQGetMessageOptions();
5785
gmo.options = getMsgOpt;
5886
gmo.waitInterval = 30000;
59-
connection.establish(config.getQmgrHost(), config.getQmgrPort(), config.getQmgrChannel(), config.getQmgrName(), config.getUser(), config.getPassword(), config.getMqscp());
60-
6187
try {
88+
connection.establish(config.getQmgrHost(), config.getQmgrPort(), config.getQmgrChannel(), config.getQmgrName(), config.getUser(), config.getPassword(), config.useMqscp());
6289
topic = connection.createTopic(String.format(topicString, config.getQmgrName()));
6390
MQMessage msg = getEmptyMessage();
6491
topic.get(msg, gmo);
@@ -78,19 +105,19 @@ private static ArrayList<PCFElement> getAllPublishedMetrics(Config config) {
78105
elements.addAll(PCFDataParser.getPCFElements(pcfResponse));
79106
}
80107
}
81-
} catch (Exception e) {
82-
System.err.println(e.getStackTrace());
108+
} catch (MQException | IOException e) {
109+
logger.error("Failed!", e);
83110
} finally {
84111
try {
85112
if (topic != null && topic.isOpen()) {
86113
topic.close();
87114
}
88115
connection.close();
89116
} catch (MQException e) {
90-
System.err.println(String.format("Error occured during disconnecting from topic %s. Error: %s", topic.toString(), e.getStackTrace()));
117+
logger.error("Error occurred during disconnecting from topic {}. Error: ", topic.toString(), e);
91118
}
92-
return elements;
93119
}
120+
return elements;
94121
}
95122

96123
private static MQMessage getEmptyMessage() {

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

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,21 @@
55
import com.ibm.mq.MQTopic;
66
import com.ibm.mq.constants.CMQC;
77
import com.ibm.mq.constants.MQConstants;
8+
import org.apache.logging.log4j.LogManager;
9+
import org.apache.logging.log4j.Logger;
810

911
import java.util.Hashtable;
1012

1113
/**
12-
* Class represents MQ connection
14+
* Class represents MQ connection.
1315
*/
1416
public class MQConnection {
17+
private static final Logger logger = LogManager.getLogger(MQConnection.class);
1518
private Hashtable<String, Object> connectionProperties;
1619
private MQQueueManager queueManager;
1720

1821
/**
19-
* Default constructor
22+
* Default constructor.
2023
*/
2124
public MQConnection() {
2225

@@ -26,18 +29,18 @@ public MQConnection() {
2629
* Method creates connection properties Hashtable from connection parameters.
2730
*
2831
* @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)
32+
* @param port - queue manager's port.
33+
* @param channel - queue manager's channel.
34+
* @param user - user, which has enough privilege on the queue manager (optional).
35+
* @param password - password, which is required to establish connection with queue manager (optional).
3336
* @param useMQCSP - flag, which indicates, if MQCSP auth should be used.
3437
* @return - returns prepared structure with all parameters transformed into queue manager's format.
3538
*/
3639
protected static Hashtable<String, Object> createMQConnectionParams(String host, int port, String channel, String user, String password, boolean useMQCSP) {
3740
Hashtable<String, Object> properties = new Hashtable<String, Object>();
3841
properties.put(MQConstants.TRANSPORT_PROPERTY, host == null ? MQConstants.TRANSPORT_MQSERIES_BINDINGS : MQConstants.TRANSPORT_MQSERIES_CLIENT);
3942
if (host != null) properties.put(MQConstants.HOST_NAME_PROPERTY, host);
40-
if (port != 0) properties.put(MQConstants.PORT_PROPERTY, new Integer(port));
43+
if (port != 0) properties.put(MQConstants.PORT_PROPERTY, port);
4144
if (channel != null) properties.put(MQConstants.CHANNEL_PROPERTY, channel);
4245
if (user != null || password != null) {
4346
if (useMQCSP) properties.put(MQConstants.USE_MQCSP_AUTHENTICATION_PROPERTY, true);
@@ -58,13 +61,9 @@ protected static Hashtable<String, Object> createMQConnectionParams(String host,
5861
* @param password - password, which is required to establish connection with queue manager (optional).
5962
* @param useMQCSP - flag, which indicates, if MQCSP auth should be used.
6063
*/
61-
public void establish(String host, int port, String channel, String qmName, String user, String password, boolean useMQCSP) {
64+
public void establish(String host, int port, String channel, String qmName, String user, String password, boolean useMQCSP) throws MQException {
6265
connectionProperties = createMQConnectionParams(host, port, channel, user, password, useMQCSP);
63-
try {
64-
queueManager = new MQQueueManager(qmName, connectionProperties);
65-
} catch (MQException e) {
66-
System.err.println(e.getStackTrace());
67-
}
66+
queueManager = new MQQueueManager(qmName, connectionProperties);
6867
}
6968

7069

@@ -74,12 +73,8 @@ public void establish(String host, int port, String channel, String qmName, Stri
7473
* @param qmNqme - queue manager's name.
7574
* @param connectionProperties - prepared structure with all parameters transformed into queue manager's format. See {@link #createMQConnectionParams(String, int, String, String, String, boolean)} for more info.
7675
*/
77-
public void establish(String qmNqme, Hashtable<String, Object> connectionProperties) {
78-
try {
79-
queueManager = new MQQueueManager(qmNqme, connectionProperties);
80-
} catch (MQException e) {
81-
System.err.println(e.getStackTrace());
82-
}
76+
public void establish(String qmNqme, Hashtable<String, Object> connectionProperties) throws MQException {
77+
queueManager = new MQQueueManager(qmNqme, connectionProperties);
8378
}
8479

8580
/**
@@ -90,7 +85,7 @@ public void close() {
9085
try {
9186
queueManager.disconnect();
9287
} catch (MQException e) {
93-
System.err.println(e.getStackTrace());
88+
logger.error("Failed!", e);
9489
}
9590
}
9691
}
@@ -105,4 +100,13 @@ public void close() {
105100
public MQTopic createTopic(String topic) throws MQException {
106101
return queueManager.accessTopic(topic, "", CMQC.MQTOPIC_OPEN_AS_SUBSCRIPTION, CMQC.MQSO_CREATE | CMQC.MQSO_NON_DURABLE | CMQC.MQSO_MANAGED);
107102
}
103+
104+
/**
105+
* Returns MQQueueManager object.
106+
*
107+
* @return - MQQueueManager object.
108+
*/
109+
public MQQueueManager getQueueManager() {
110+
return this.queueManager;
111+
}
108112
}

0 commit comments

Comments
 (0)