From 72a9ce51202443d12255e51fe3d6d8c97c1ee6eb Mon Sep 17 00:00:00 2001 From: Robert Garza Date: Fri, 15 Nov 2019 22:51:05 -0600 Subject: [PATCH 1/9] Updating for python 2/3 support --- .gitignore | 2 + python/jmxquery/__init__.py | 237 ++++++++++++++++++++++-------------- 2 files changed, 145 insertions(+), 94 deletions(-) diff --git a/.gitignore b/.gitignore index 8d77f88..e460cc8 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ nbactions.xml *.log MANIFEST python/jmxquery.egg-info/ +.vscode/ +venv/ diff --git a/python/jmxquery/__init__.py b/python/jmxquery/__init__.py index 795d97b..b0719e8 100644 --- a/python/jmxquery/__init__.py +++ b/python/jmxquery/__init__.py @@ -1,46 +1,56 @@ #!/usr/bin/env python3 """ - Python interface to JMX. Uses local jar to pass commands to JMX and read JSON - results returned. + Python interface to JMX. Uses local jar to pass commands to JMX. + Results returned. """ import subprocess import os import json -from typing import List from enum import Enum import logging # Full Path to Jar -JAR_PATH = os.path.dirname(os.path.realpath(__file__)) + '/JMXQuery-0.1.8.jar' +JAR_PATH = "%s/%s" % ( + os.path.dirname(os.path.realpath(__file__)), + 'JMXQuery-0.1.8.jar') + # Default Java path DEFAULT_JAVA_PATH = 'java' + # Default timeout for running jar in seconds DEFAULT_JAR_TIMEOUT = 10 -logger = logging.getLogger(__name__) +logging.basicConfig() +log = logging.getLogger('jmxQuery') + class MetricType(Enum): COUNTER = 'counter' GAUGE = 'gauge' + class JMXQuery: """ - A JMX Query which is used to fetch specific MBean attributes/values from the JVM. The object_name can support wildcards - to pull multiple metrics at once, for example '*:*' will bring back all MBeans and attributes in the JVM with their values. - - You can set a metric name if you want to override the generated metric name created from the MBean path + A JMX Query which is used to fetch specific MBean + attributes/values from the JVM. The object_name + can support wildcards to pull multiple metrics + at once, for example '*:*' will bring back all + MBeans and attributes in the JVM with their values. + + You can set a metric name if you want to override + the generated metric name created from the MBean path. """ def __init__(self, - mBeanName: str, - attribute: str = None, - attributeKey: str = None, - value: object = None, - value_type: str = None, - metric_name: str = None, - metric_labels: dict = None): + mBeanName=None, + attribute=None, + attributeKey=None, + value=None, + value_type=None, + metric_name=None, + metric_labels=None): self.mBeanName = mBeanName self.attribute = attribute @@ -56,81 +66,94 @@ def to_query_string(self) -> str: :return: The query string to find the MBean in format: - {mBeanName}/{attribute}/{attributeKey} + {mBeanName}/{attribute}/{attributeKey} - Example: java.lang:type=Memory/HeapMemoryUsage/init + Example: java.lang:type=Memory/HeapMemoryUsage/init """ - query = "" + query = [] if self.metric_name: - query += self.metric_name - - if ((self.metric_labels != None) and (len(self.metric_labels) > 0)): - query += "<" - keyCount = 0 - for key, value in self.metric_labels.items(): - query += key + "=" + value - keyCount += 1 - if keyCount < len(self.metric_labels): - query += "," - query += ">" - query += "==" - - query += self.mBeanName + query.append(self.metric_name) + + if self.metric_labels != None: + if len(self.metric_labels) > 0: + query.append("<") + keyCount = 0 + for key, value in self.metric_labels.items(): + query.append("%s = %s" % ( + key, + value)) + keyCount += 1 + if keyCount < len(self.metric_labels): + query.append(",") + query.append(">") + query.append("==") + + query.append(self.mBeanName) if self.attribute: - query += "/" + self.attribute + query.append("/%s" % ( + self.attribute)) if self.attributeKey: - query += "/" + self.attributeKey + query.append("/%s" % ( + self.attributeKey)) - return query + return ''.join(query) def to_string(self): - string = "" + data = [] if self.metric_name: - string += self.metric_name - - if ((self.metric_labels != None) and (len(self.metric_labels) > 0)): - string += " {" - keyCount = 0 - for key, value in self.metric_labels.items(): - string += key + "=" + value - keyCount += 1 - if keyCount < len(self.metric_labels): - string += "," - string += "}" + data.append(self.metric_name) + + if self.metric_labels != None: + if len(self.metric_labels) > 0: + data.append(" {") + keyCount = 0 + for key, value in self.metric_labels.items(): + data.append("%s = %s" % ( + key, + value)) + keyCount += 1 + if keyCount < len(self.metric_labels): + data.append(",") + data.append("}") else: - string += self.mBeanName + data.append(self.mBeanName) if self.attribute: - string += "/" + self.attribute + data.append("/%s" % ( + self.attribute)) if self.attributeKey: - string += "/" + self.attributeKey + data.append("/%s" % ( + self.attributeKey)) - string += " = " - string += str(self.value) + " (" + self.value_type + ")" + data.append(" = ") + data.append("%s ( %s )" %( + str(self.value), + self.value_type)) - return string + return ''.join(data) class JMXConnection(object): """ - The main class that connects to the JMX endpoint via a local JAR to run queries + The main class that connects to the JMX endpoint via a local JAR + to run queries """ - - def __init__(self, connection_uri: str, jmx_username: str = None, jmx_password: str = None, java_path: str = DEFAULT_JAVA_PATH): + def __init__(self, uri=None, user=None, passwd=None, jpath=None): """ Creates instance of JMXQuery set to a specific connection uri for the JMX endpoint - :param connection_uri: The JMX connection URL. E.g. service:jmx:rmi:///jndi/rmi://localhost:7199/jmxrmi - :param jmx_username: (Optional) Username if JMX endpoint is secured - :param jmx_password: (Optional) Password if JMX endpoint is secured - :param java_path: (Optional) Provide an alternative Java path on the machine to run the JAR. - Default is 'java' which will use the machines default JVM + :param uri: The JMX connection URL. E.g. + service:jmx:rmi:///jndi/rmi://localhost:7199/jmxrmi + :param user: (Optional) Username if JMX endpoint is secured + :param passwd: (Optional) Password if JMX endpoint is secured + :param jpath: (Optional) Java path. Default is 'java' """ - self.connection_uri = connection_uri - self.jmx_username = jmx_username - self.jmx_password = jmx_password - self.java_path = java_path - def __run_jar(self, queries: List[JMXQuery], timeout) -> List[JMXQuery]: + self.connection_uri = uri + self.jmx_username = user + self.jmx_password = passwd + self.java_path = jpath + + def run_jar(self, queries, timeout): """ Run the JAR and return the results @@ -138,16 +161,27 @@ def __run_jar(self, queries: List[JMXQuery], timeout) -> List[JMXQuery]: :return: The full command array to run via subprocess """ - command = [self.java_path, '-jar', JAR_PATH, '-url', self.connection_uri, "-json"] - if (self.jmx_username): - command.extend(["-u", self.jmx_username, "-p", self.jmx_password]) + command = [ + self.java_path, + '-jar', + JAR_PATH, + '-url', + self.connection_uri, + "-json"] + + if self.jmx_username: + command.extend([ + "-u", + self.jmx_username, + "-p", + self.jmx_password]) queryString = "" for query in queries: queryString += query.to_query_string() + ";" command.extend(["-q", queryString]) - logger.debug("Running command: " + str(command)) + log.debug("Running command: " + str(command)) jsonOutput = "[]" try: @@ -159,16 +193,21 @@ def __run_jar(self, queries: List[JMXQuery], timeout) -> List[JMXQuery]: jsonOutput = output.stdout.decode('utf-8') except subprocess.TimeoutExpired as err: - logger.error("Error calling JMX, Timeout of " + str(err.timeout) + " Expired: " + err.output.decode('utf-8')) + log.error("Timeout of %s Expired: %s" % ( + str(err.timeout), + err.output.decode('utf-8'))) + except subprocess.CalledProcessError as err: - logger.error("Error calling JMX: " + err.output.decode('utf-8')) - raise err + log.error("Error calling JMX: %s" % ( + err.output.decode('utf-8'))) + raise + + log.debug("JSON Output Received: %s" % jsonOutput) + metrics = self.load_from_json(jsonOutput) - logger.debug("JSON Output Received: " + jsonOutput) - metrics = self.__load_from_json(jsonOutput) return metrics - def __load_from_json(self, jsonOutput: str) -> List[JMXQuery]: + def load_from_json(self, jsonOutput): """ Loads the list of returned metrics from JSON response @@ -177,31 +216,41 @@ def __load_from_json(self, jsonOutput: str) -> List[JMXQuery]: """ jsonMetrics = json.loads(jsonOutput) metrics = [] - for jsonMetric in jsonMetrics: - mBeanName = jsonMetric['mBeanName'] - attribute = jsonMetric['attribute'] - attributeType = jsonMetric['attributeType'] + + for jm in jsonMetrics: + mBeanName = jm['mBeanName'] + attribute = jm['attribute'] + attributeType = jm['attributeType'] metric_name = None - if 'metricName' in jsonMetric: - metric_name = jsonMetric['metricName'] + if 'metricName' in jm: + metric_name = jm['metricName'] metric_labels = None - if 'metricLabels' in jsonMetric: - metric_labels = jsonMetric['metricLabels'] + if 'metricLabels' in jm: + metric_labels = jm['metricLabels'] attributeKey = None - if 'attributeKey' in jsonMetric: - attributeKey = jsonMetric['attributeKey'] + if 'attributeKey' in jm: + attributeKey = jm['attributeKey'] value = None - if 'value' in jsonMetric: - value = jsonMetric['value'] + if 'value' in jm: + value = jm['value'] + + metrics.append(JMXQuery( + mBeanName, + attribute, + attributeKey, + value, + attributeType, + metric_name, + metric_labels)) - metrics.append(JMXQuery(mBeanName, attribute, attributeKey, value, attributeType, metric_name, metric_labels)) return metrics - def query(self, queries: List[JMXQuery], timeout=DEFAULT_JAR_TIMEOUT) -> List[JMXQuery]: + def query(self, queries, timeout=DEFAULT_JAR_TIMEOUT): """ Run a list of JMX Queries against the JVM and get the results - :param queries: A list of JMXQuerys to query the JVM for - :return: A list of JMXQuerys found in the JVM with their current values + :param queries: A list of JMXQuerys to query the JVM for + :return: list of query results with their current values """ - return self.__run_jar(queries, timeout) + + return self.run_jar(queries, timeout) From e3de9cc98cc24859216865e0c5a94bdfac3b0f67 Mon Sep 17 00:00:00 2001 From: Robert Garza Date: Fri, 15 Nov 2019 23:01:06 -0600 Subject: [PATCH 2/9] removing extra spaces --- python/jmxquery/__init__.py | 51 ++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/python/jmxquery/__init__.py b/python/jmxquery/__init__.py index b0719e8..cb10d6c 100644 --- a/python/jmxquery/__init__.py +++ b/python/jmxquery/__init__.py @@ -33,13 +33,13 @@ class MetricType(Enum): class JMXQuery: """ - A JMX Query which is used to fetch specific MBean - attributes/values from the JVM. The object_name - can support wildcards to pull multiple metrics - at once, for example '*:*' will bring back all + A JMX Query which is used to fetch specific MBean + attributes/values from the JVM. The object_name + can support wildcards to pull multiple metrics + at once, for example '*:*' will bring back all MBeans and attributes in the JVM with their values. - You can set a metric name if you want to override + You can set a metric name if you want to override the generated metric name created from the MBean path. """ @@ -60,7 +60,7 @@ def __init__(self, self.metric_name = metric_name self.metric_labels = metric_labels - def to_query_string(self) -> str: + def to_query_string(self): """ Build a query string to pass via command line to JMXQuery Jar @@ -139,10 +139,13 @@ class JMXConnection(object): """ def __init__(self, uri=None, user=None, passwd=None, jpath=None): """ - Creates instance of JMXQuery set to a specific connection uri for the JMX endpoint + Creates instance of JMXQuery set to a specific connection uri + for the JMX endpoint. + + :param uri: The JMX connection URL. E.g. + + service:jmx:rmi:///jndi/rmi://localhost:7199/jmxrmi - :param uri: The JMX connection URL. E.g. - service:jmx:rmi:///jndi/rmi://localhost:7199/jmxrmi :param user: (Optional) Username if JMX endpoint is secured :param passwd: (Optional) Password if JMX endpoint is secured :param jpath: (Optional) Java path. Default is 'java' @@ -162,18 +165,18 @@ def run_jar(self, queries, timeout): """ command = [ - self.java_path, - '-jar', - JAR_PATH, - '-url', - self.connection_uri, + self.java_path, + '-jar', + JAR_PATH, + '-url', + self.connection_uri, "-json"] if self.jmx_username: command.extend([ - "-u", - self.jmx_username, - "-p", + "-u", + self.jmx_username, + "-p", self.jmx_password]) queryString = "" @@ -199,7 +202,7 @@ def run_jar(self, queries, timeout): except subprocess.CalledProcessError as err: log.error("Error calling JMX: %s" % ( - err.output.decode('utf-8'))) + err.output.decode('utf-8'))) raise log.debug("JSON Output Received: %s" % jsonOutput) @@ -235,12 +238,12 @@ def load_from_json(self, jsonOutput): value = jm['value'] metrics.append(JMXQuery( - mBeanName, - attribute, - attributeKey, - value, - attributeType, - metric_name, + mBeanName, + attribute, + attributeKey, + value, + attributeType, + metric_name, metric_labels)) return metrics From 991c62a9ab11c850a9e676eb0c168a421aa09be8 Mon Sep 17 00:00:00 2001 From: Robert Garza Date: Mon, 18 Nov 2019 11:00:29 -0600 Subject: [PATCH 3/9] updating to use subprocess32 for backported compatability --- .gitignore | 1 + python/jmxquery/__init__.py | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index e460cc8..7efb9e9 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ MANIFEST python/jmxquery.egg-info/ .vscode/ venv/ +venv3/ diff --git a/python/jmxquery/__init__.py b/python/jmxquery/__init__.py index cb10d6c..256c43c 100644 --- a/python/jmxquery/__init__.py +++ b/python/jmxquery/__init__.py @@ -5,7 +5,7 @@ Results returned. """ -import subprocess +import subprocess32 import os import json from enum import Enum @@ -161,7 +161,7 @@ def run_jar(self, queries, timeout): Run the JAR and return the results :param query: The query - :return: The full command array to run via subprocess + :return: The full command array to run via subprocess32 """ command = [ @@ -188,19 +188,19 @@ def run_jar(self, queries, timeout): jsonOutput = "[]" try: - output = subprocess.run(command, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + output = subprocess32.run(command, + stdout=subprocess32.PIPE, + stderr=subprocess32.PIPE, timeout=timeout, check=True) jsonOutput = output.stdout.decode('utf-8') - except subprocess.TimeoutExpired as err: + except subprocess32.TimeoutExpired as err: log.error("Timeout of %s Expired: %s" % ( str(err.timeout), err.output.decode('utf-8'))) - except subprocess.CalledProcessError as err: + except subprocess32.CalledProcessError as err: log.error("Error calling JMX: %s" % ( err.output.decode('utf-8'))) raise From b145730bf29bed72e732286f0cd002358539c514 Mon Sep 17 00:00:00 2001 From: Robert Garza Date: Mon, 18 Nov 2019 13:03:54 -0600 Subject: [PATCH 4/9] additional changes for testing --- python/jmxquery/__init__.py | 15 ++++++++++----- python/jmxquery/__init__.pyc | Bin 0 -> 6907 bytes .../jmxquery/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 6067 bytes python/tests/__init__.pyc | Bin 0 -> 104 bytes python/tests/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 138 bytes .../__pycache__/test_JMXQuery.cpython-37.pyc | Bin 0 -> 4567 bytes python/tests/test_JMXQuery.py | 12 ++++++++++-- python/tests/test_JMXQuery.pyc | Bin 0 -> 5301 bytes 8 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 python/jmxquery/__init__.pyc create mode 100644 python/jmxquery/__pycache__/__init__.cpython-37.pyc create mode 100644 python/tests/__init__.pyc create mode 100644 python/tests/__pycache__/__init__.cpython-37.pyc create mode 100644 python/tests/__pycache__/test_JMXQuery.cpython-37.pyc create mode 100644 python/tests/test_JMXQuery.pyc diff --git a/python/jmxquery/__init__.py b/python/jmxquery/__init__.py index 256c43c..04cf06e 100644 --- a/python/jmxquery/__init__.py +++ b/python/jmxquery/__init__.py @@ -96,7 +96,7 @@ def to_query_string(self): query.append("/%s" % ( self.attributeKey)) - return ''.join(query) + return ' '.join(query) def to_string(self): @@ -130,14 +130,14 @@ def to_string(self): str(self.value), self.value_type)) - return ''.join(data) + return ' '.join(data) class JMXConnection(object): """ The main class that connects to the JMX endpoint via a local JAR to run queries """ - def __init__(self, uri=None, user=None, passwd=None, jpath=None): + def __init__(self, uri=None, user=None, passwd=None, jpath=DEFAULT_JAVA_PATH): """ Creates instance of JMXQuery set to a specific connection uri for the JMX endpoint. @@ -185,6 +185,7 @@ def run_jar(self, queries, timeout): command.extend(["-q", queryString]) log.debug("Running command: " + str(command)) + print("Running command: %s" % str(command)) jsonOutput = "[]" try: @@ -198,11 +199,15 @@ def run_jar(self, queries, timeout): except subprocess32.TimeoutExpired as err: log.error("Timeout of %s Expired: %s" % ( str(err.timeout), - err.output.decode('utf-8'))) + err)) except subprocess32.CalledProcessError as err: log.error("Error calling JMX: %s" % ( - err.output.decode('utf-8'))) + err)) + raise + + except Exception as err: + log.error("Exception: %s" % err) raise log.debug("JSON Output Received: %s" % jsonOutput) diff --git a/python/jmxquery/__init__.pyc b/python/jmxquery/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d4c4907eddffc383f68892cd7e63b89d370db48 GIT binary patch literal 6907 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 F`5zRYvH}1A literal 0 HcmV?d00001 diff --git a/python/jmxquery/__pycache__/__init__.cpython-37.pyc b/python/jmxquery/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d8c8faa004a43ac59d68017931e4bc6f9f192598 GIT binary patch literal 6067 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 literal 0 HcmV?d00001 diff --git a/python/tests/__init__.pyc b/python/tests/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82c3bcd7c94cf7977b0342cdfb9aa6ff57c89382 GIT binary patch literal 104 zcmZSn%*(YT=X`830~9aYnUiuL2;GxIV_ b;^XxSDoZ$kqBgntDWy57b|AeaK+FIDIjIp* literal 0 HcmV?d00001 diff --git a/python/tests/__pycache__/__init__.cpython-37.pyc b/python/tests/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8404afaa88a2416b90f787f370bf9a099e780e76 GIT binary patch literal 138 zcmZ?b<>g`kf+acUV?p#|5CH>>K!yVl7qb9~6oz01O-8?!3`HPe1o6vQKeRZts93)! zJ+Y`NQQsxCOyA2lBCs^Is8YY6vLquvProF!xTIJ=K0Y%qvm`!Vub}c4hfQvNN@-52 L9mufHK+FID3ke{U literal 0 HcmV?d00001 diff --git a/python/tests/__pycache__/test_JMXQuery.cpython-37.pyc b/python/tests/__pycache__/test_JMXQuery.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c11baabd5bc5d6c644100ade25ac3ff9bbfb6fa2 GIT binary patch literal 4567 zcmb6dYjfMi5f2iCAWD{O*>002MVc}ZHIdj(S~uZXZfr?SR9UoYNqw-BVqn~nf`kWs zchmzGJJV6W`ajrTI@7K8){u^jNN?-nX|xUTG}|UT&8QTY+hv{8lp-sxv@5aQ zw&St(n66=c*Fj}uVPkh3;3}%TECHq6ozqBPjU#0}E8m%?i&jIbLfF53yIi$a0}mXafvr7rCOy5EBt>@rN5yXJTH z{6;%X_b~2p7EzxvOq_!qoVcW)Bw^C!)WDU~)28FNa7lslLxJ<1bC~%(&UfL+k0TK0 zINyVvv{qfuXM9RAVP2PDALMxWdEbxfWc?>P-RjFcD)){Vot?)3v|M*W&paa%?SB|NH|IZKiWwtYkmn= z1Bd`0@DJpdsqQ6s(t9v4jp--)Kx5z(Cwf;O=*QYC^H_ha4-8g1HcoV1V`XM>2pJ~^ zY`+FuYqm0Tt~nR}^`@rPD}=MnCzqbIS}RLit4~_q_S46t#F6Fa!cNs52@@ubMTx;@ z%m^pkw4mXrY2j6xwh{}|(tm4Y8t8xcq5-}{XoGZplKG8gyx$mZL!)=ZcG9FFd_aue zaB87k)Zz~L5}DZJlCcNFDa^dklR7`>;U_t8%j z^a1)%K|e*Vf<8h&Q_#og=L)K!PdL<_zH(A*aR<wP52(HeQi~cj;n?!g0Ct9+#4REtLt< zgpo9gh6=6m2nN4VNU712PA3Wze5T1#+E18L=QmQFGe+Jy9^S>vv){dg1`i?r_wkut zqYB)6s{$9U&c2fJN4MhQalB!%j!R#O6wC=vdbl^jjZur_zcdpXMKhT*<&g5ENG-@&K!J``HV{2 zJjOmGgq27hl276EdYB-ohceG^rFqmT4h9&8ui)Zc!9Z=(`a7tzodgl~lOj`Pd!>(z zEblUXuHv8+YD$GhW3!m(q-jnw(r7-Ilh#n-QC#K~S7b7R7v3gkm6FXJIBECPcV=H) zCF4AGVdt+eapkb*C+NBo3)BUPtJ0PQ|K8-KBij@wku+sXhUf-K14wo$dAQ$QMG=O8 z4De~L|5AST(Ah`1cvmyX)}$7rmR{p$jf&-O;8Woc+DOx=kP#HVs7)sQb$A3`!e^Kl zE@V-#kU9%Tb=w3Zz?lnHg+lsq2-R^iJfER#UK3^Wa!4V7dGR{jBx&lQUKjH4E?-{I zY3WUSUC2*b>y)Wfc&Lv|zt_~Kuyj_MyLGxvaZbjhd8?PBKo33P5d(4QdQiiMQI@#y-n1X{Q_MSW=Xpzw~|XIQX>o{hJD z;Eq9`5C~XTT37L)l1PW|{+@3j6oVG?2?*NCZa)MzQWSM5V4>z*aI(9jXx{NfSWL9) z<9V6*Nf+m1rwZoQme7@Oo97ntaSZL8<@b6xL3vql%}shldDDf`KFiAoBxE=*?WQ4g zEA46oA?7J9a{VyZ*?HHQ6s~hBG6qSMALm-Rq)+Kp-GXMLs#gs@l1~61@XzHJcTe8C zi@pCF0Ef$B&+bF%uJ3AOjzI^{A-D~=&5n6T;|mscX83>fW*189Im?x_wnMJmm`V>R~4X5w{FX_r7U_q0{==t z`?oJzfg3E9ZI=hVEI3Nr5qOXH7GQ5iWKiDdn6su%e}x#BUNJ zj{l}iK~uk(S3D2?1Ms}O5~W=T-Y#)r33(re+)3b1hy?}-TsER@8(L1$6N)xg=8Q6@ z9DnB1Fn}th6L!f*98+Fid9?kt%q_fI6n-Q&Q6`wPEFvJ0O6>bG4jxos0eue!?gut_ Uz>Hx*rYPx-Q8H}X-ms_t4~^}zL;wH) literal 0 HcmV?d00001 diff --git a/python/tests/test_JMXQuery.py b/python/tests/test_JMXQuery.py index 7d2bd7f..99b66b0 100644 --- a/python/tests/test_JMXQuery.py +++ b/python/tests/test_JMXQuery.py @@ -126,8 +126,16 @@ def test_threading(): def printMetrics(metrics): for metric in metrics: if metric.metric_name: - print(f"{metric.metric_name}<{metric.metric_labels}> == {metric.value}") + print("{%s}<{%s}> == {%s}" % ( + metric.metric_name, + metric.metric_labels, + metric.value + )) else: - print(f"{metric.to_query_string()} ({metric.value_type}) = {metric.value}") + print("{%s} ({%s}) = {%s}" % ( + metric.to_query_string, + metric.value_type, + metric.value + )) print("===================\nTotal Metrics: " + str(len(metrics))) \ No newline at end of file diff --git a/python/tests/test_JMXQuery.pyc b/python/tests/test_JMXQuery.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2cc6ae72e555d9a034b9259b483703a6cdfbd158 GIT binary patch literal 5301 zcmb_gdvn{y5kHW6k(Mmkab!15TqLP##S@9`G))tZ<=U21OR*)Zl+?7!crY+akPz4`ASp9UiT zRPcKbU-d6Ep%6Q09TAp9?1&w7Our;{O157XJ7w;dMLZfP(W;7YScD@Y92Mc12rELCMC+0WtAb|7#Vax7gqOt5gb2sQ-yz0j z5l(PtQiPYeGbO@F?pz`9HfN_u>VKlCZY$}AX|OLdH%Qx^6y$CcOE*efy%#Arj4~PM zG&^>6>Z%TgyB*9(S4*YcNB-`>unj{cAN)tV1M*h&1*|DyISd%)7g016@)FU8w)2!`l^-FYTW_^WCZTW?AXJ%u0 zAmhZ(sk}3XiMCYAZ(@-i#ikGvFi%$)UFwS;IPf6cJ!gz#67Ngt=G6IM z#GDUtYxDW2S=!8v`Ubrk3^h}=tm$We@oP)+poU}SO|{Ok-b<4j8yL5qotnqg2iQzg z-eDAnfuDsQ3;Q946`6x5jXRV0t2zNuBrTcPBEISeJos7tLStbWdUQzLL*!8K&zyvp zf*iFZ+!bWSlJI1Zmn=EX1gb0&Xo$r&bpL1gpF+uPf%zP-`$uB&CV z#^K2+WLDSk&4q^S#8Kd{`3Zb2`;z=`VLJ(BmQQFIZupsw$jMdhkAB>h`Vx?g`FONm z|HdMF2H7iudKcoUhj!Ym*?KX^h9GKBqXEA2!j56mr?dtRExV@rf~vljE)a2G zoA<)kxWk`ywLDRedz|~;WfawSgH4Sa-e~Hv^btdrW0M^;aCzTPLL*JCtlwEcFVAM6 z4(sg<)h$TDnu|fvNYsmD zgAwGm-EJ+pxYH|cQay)%BezwRZSEm)*w3GtZ~TJ0p5k&BfovNS-bOtbq3&DAiLaNa=nZjEm(nr9ti5XgHy24{w> zz=H1i(#c(a1&@tOZ6i%%BUN#{D3j_Lv_1L@pll?`(TgYrZS`;1!8>IW3c-aAC8O?m z9HE#8kDxbuUwjH9L}X#Jzgj7 zHlySd45|$@$fU~^XXK)g>!U+RxdrB z5&)p3NZ4srkep5Htlfgb}U|+k3RB9);wA+;0 z^%IoTd#DUUs*xk5aDlr%wxG6dr(qX0I4YLdeI^+e#WdCAF#MpKWe5|l(SDAhcu@o) zL`3$$g{Ss2a8gw2+y|23rd)+_WY67Xe&bsP9=5d%Qmh|>iV6IOhSfXwpU&e4W3 zm=!L9V1q(rUy*U5^hTdr(=UnLvY39j@*Hn+U|JaG^1Ow@9Q}dW@5zQukuJ#4@PGZ` z3fJhQ>2-zDT)dc3CwHj1>n<#~)aebovqXO3=EI+3^}^Xtm2)aLPu}aU2{H6;sBr@g zAIt$4R+B`grgHZ1J_9Dp?^1Zyqk7F8tjRC$)v!}+P_;a!vGaX(I*2v^Ok104cpt$p z3HZf_iL_-}Px1Acuc821+-}rt&?B*ymX;rEKQwWfRK-5gn5Q1G=s!94{=fGbB;Oqq iAntPH`3M6e&JAZAHu`aC5{jre)zV0*GFI8BT=^e=>gq-S literal 0 HcmV?d00001 From 9365e9a8a3c11d5d87c992d5ffd9247d0631ef10 Mon Sep 17 00:00:00 2001 From: Robert Garza Date: Mon, 18 Nov 2019 16:07:11 -0600 Subject: [PATCH 5/9] updating .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7efb9e9..c3fcb62 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ python/jmxquery.egg-info/ .vscode/ venv/ venv3/ +*.pyc From 8410e2934548171f5be66cb890adbe39e2d7cb08 Mon Sep 17 00:00:00 2001 From: Robert Garza Date: Mon, 18 Nov 2019 16:07:43 -0600 Subject: [PATCH 6/9] tested against python 2.7 and 3.6 --- python/jmxquery/__init__.py | 52 ++++++++---------- python/jmxquery/__init__.pyc | Bin 6907 -> 7243 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 6067 -> 6038 bytes .../__pycache__/test_JMXQuery.cpython-37.pyc | Bin 4567 -> 4567 bytes python/tests/test_JMXQuery.pyc | Bin 5301 -> 5301 bytes 5 files changed, 23 insertions(+), 29 deletions(-) diff --git a/python/jmxquery/__init__.py b/python/jmxquery/__init__.py index 04cf06e..3183bf2 100644 --- a/python/jmxquery/__init__.py +++ b/python/jmxquery/__init__.py @@ -63,25 +63,23 @@ def __init__(self, def to_query_string(self): """ Build a query string to pass via command line to JMXQuery Jar - :return: The query string to find the MBean in format: - - {mBeanName}/{attribute}/{attributeKey} - - Example: java.lang:type=Memory/HeapMemoryUsage/init + {mBeanName}/{attribute}/{attributeKey} + Example: java.lang:type=Memory/HeapMemoryUsage/init """ query = [] if self.metric_name: query.append(self.metric_name) if self.metric_labels != None: - if len(self.metric_labels) > 0: + if len(self.metric_labels) > 0: query.append("<") keyCount = 0 for key, value in self.metric_labels.items(): query.append("%s = %s" % ( key, - value)) + value + )) keyCount += 1 if keyCount < len(self.metric_labels): query.append(",") @@ -90,47 +88,42 @@ def to_query_string(self): query.append(self.mBeanName) if self.attribute: - query.append("/%s" % ( - self.attribute)) + query.append("/%s" % self.attribute) if self.attributeKey: - query.append("/%s" % ( - self.attributeKey)) + query.append("/%s" % self.attributeKey) - return ' '.join(query) + return ''.join(query) def to_string(self): - data = [] + string = [] if self.metric_name: - data.append(self.metric_name) + string.append(self.metric_name) if self.metric_labels != None: if len(self.metric_labels) > 0: - data.append(" {") + string.append(" {") keyCount = 0 for key, value in self.metric_labels.items(): - data.append("%s = %s" % ( + string.append("%s = %s" % ( key, - value)) + value + )) keyCount += 1 if keyCount < len(self.metric_labels): - data.append(",") - data.append("}") + string.append(",") + string.append("}") else: - data.append(self.mBeanName) + string.append(self.mBeanName) if self.attribute: - data.append("/%s" % ( - self.attribute)) + string.append("/%s" % self.attribute) if self.attributeKey: - data.append("/%s" % ( - self.attributeKey)) + string.append("/%s" % self.attributeKey) - data.append(" = ") - data.append("%s ( %s )" %( - str(self.value), - self.value_type)) + string.append(" = ") + string.append("%s ( %s )") - return ' '.join(data) + return ''.join(string) class JMXConnection(object): """ @@ -204,6 +197,7 @@ def run_jar(self, queries, timeout): except subprocess32.CalledProcessError as err: log.error("Error calling JMX: %s" % ( err)) + raise except Exception as err: diff --git a/python/jmxquery/__init__.pyc b/python/jmxquery/__init__.pyc index 5d4c4907eddffc383f68892cd7e63b89d370db48..3a96ce1232de168e2d752a5f33a4be3a4c5ad295 100644 GIT binary patch delta 1210 zcmbVL&1(};5Z|{+ce9(smS)$qp=yk6OeMOFl3G-R^uspMs2y4mp~f^>qCpegw-H+r z1S5ji=RpwsAIhEty$ha1&)x*@f}kFBW?RvdBreQvXMS(z^UeOqznxJ7U!wX`^Zk~3 zT24<(l4PxN+u@ees5+ZfYu>(NmCBcvJGQf7-P&-kwOf|B9X7l*IT+~ud(+z-xX0Lt z_^OmdL7fdHcOKDIj|WK?uhec3(@SC@^tg|};!|j3E=!K8!ZbD{4>FTQnZm}<3b3%O zqiwJlo(v%qCy{FmzaQ9x-K;}@j_oTbv&8i$z&#pI0kxF0;5;9sXRJM8XXrlnPL}SXfztG#YS_ zXd0G%*R@-9pdukjWB}ntyW!GI>-Ku5;WIc>(T!!9CAJWA;$sXDbH-X98xm15q|<3t znpNkS@Qkxe_I?^5XBQ}M7@^7At+I{RSL3imq)g;ZpfiXNl*Ijbs`s2YkpjAX@LtEy zuwoI_4E5*l3e1w0BMznC-7r$H2fe)YozKvk0u2?YQy3RlN5>UP3I*|GbgGZC z^Du#K4^TJ-Re}mLW7;V#yib0`ZnQ4Sv?dYJ%3C6QXmlj=83k^DPv YuQ%!tSxaI~Y<3GR zdTXH<1$96V9z2Q{QTFcDgXqDF;?;|1y$D`>FI!QHWqIGc{pZa;^Je$m$zP>#;73e- z^Y!EF@Qf7H8Dri}$qe|}i_imresMZn6I-3FO_K+aus%$v6jlVpqE714T&Z31sW=A zY2v$D)fKECcCv*mV#LK4R)~qkXmQ>RkdxcxeK_)d!XVAkMtlI_1`&-VcZp|68X{0_ z0mFwwt&7jmoNQy_oOqNnLC+>My<4+~XiJt@Csz*_9BZ%58x6aRAn&)K8M@W_t_J(V> z8+??+EQ!?jYG=izMjQ6^^%Z^yGcl@$cl%E<60Jm@o}k5NFKX{>LxlqA%Waa}LTiObc|F-fi;=Ws{^~{Bytm zy@i8R1L8s|1$nWWIxLeJFN?>iVtwDMJAySk7>sQsMQY%+kteljt{O2xLS85s1qCL!6bVqmqL>{e z^5l&1#H=+3TexWbu-*X}UG>(&Y5Q1FO~#&A^@zUSOFQ~DKCr8wGO-yhdy zTJ%XmDxz4g;;+)unR)is7#I0NuDu@jI?ZUX(F;>M42Bn?FbuR_;0(#gbDE6W{h%|{ L6}-3m9Nhi`?&Nou delta 601 zcmY+B&ubG=5XUo{W|VkYcbd^%&wqN zPaeF82M4?eYR?{u?AiZ8#M6S{RWBYDPtKTL++jcaecw0l%RKhgR5WFuw{4x^=jZp& zcY+VLt>6$HR&ClJ%F|;t37YoRS>_Lg$v;r0yM4QAS`KLX)|W4W3H@9ew2=kHrF$gH zJPp68VSX)!=5C^EJq4z|XA}~90Ev!%m!YzC#<7kEfU2V-RaAHtAfOvt{}EvV9qLXmFkGE}1{`cx90 zNAK-z17aE(_}Dlp$!5EGZS87vLDZQ2qOVhDNK)zvx=R$3-itEiz{pG=8b0W zHhJljFlurWuqvhd?;Qa+W4|~G^ diff --git a/python/tests/__pycache__/test_JMXQuery.cpython-37.pyc b/python/tests/__pycache__/test_JMXQuery.cpython-37.pyc index c11baabd5bc5d6c644100ade25ac3ff9bbfb6fa2..20c267f56169b5217ecc4a5a9f29f74d1f4405f1 100644 GIT binary patch delta 19 Zcmcbvd|jE#iIen0D){6iDE`J5! delta 15 Wcmdn0xmA;m`7qP)6xdl4_ From 889019fe24fcdd76d6d33520c55712e4a85c634a Mon Sep 17 00:00:00 2001 From: Robert Garza Date: Mon, 18 Nov 2019 16:29:03 -0600 Subject: [PATCH 7/9] removing pyc files --- python/jmxquery/__init__.pyc | Bin 7243 -> 0 bytes .../jmxquery/__pycache__/__init__.cpython-37.pyc | Bin 6038 -> 0 bytes python/tests/__init__.pyc | Bin 104 -> 0 bytes python/tests/__pycache__/__init__.cpython-37.pyc | Bin 138 -> 0 bytes .../__pycache__/test_JMXQuery.cpython-37.pyc | Bin 4567 -> 0 bytes python/tests/test_JMXQuery.pyc | Bin 5301 -> 0 bytes 6 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 python/jmxquery/__init__.pyc delete mode 100644 python/jmxquery/__pycache__/__init__.cpython-37.pyc delete mode 100644 python/tests/__init__.pyc delete mode 100644 python/tests/__pycache__/__init__.cpython-37.pyc delete mode 100644 python/tests/__pycache__/test_JMXQuery.cpython-37.pyc delete mode 100644 python/tests/test_JMXQuery.pyc diff --git a/python/jmxquery/__init__.pyc b/python/jmxquery/__init__.pyc deleted file mode 100644 index 3a96ce1232de168e2d752a5f33a4be3a4c5ad295..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7243 zcmd5>-E$jP6~8OVvZUCK6X&C83+x2asGY{5bfB$C3XWr%nAmYQPCrc3o%QNUURl~z z_O2Y8*1*vAKj48Ec;HXqnMZhJI#U>4dFGinUf}mTS6ay~(_togK=xkU&$H*=dp>^W zsQAy>+ON+4y{Nh+)tge= zQ_306E356YYL=8PsLr(NR7RDm(lzyo!~f=#Y8BLl?Nh3W*)ys+t+r>CF00O*`a~&* zwbQCu;oR+c)x=V)z`C0HRB^`p+heiRAhIA6=knfj+{pdEk)E&GgyGP4ux z2T_gdDkwU=1DTYuXI*D$6mA{%b$(%d!A(5o914vK!_lCW>%ql%_v-}=WYZ|ZWWY^k zDmyo8&>r zCf`Km*d|L9uap0d`V>-x{sONa^4Kg&rOe~t?#<6}Y;tkSylYoZ*nPYkg}ZKK+=07}cr&~&N;~1YFKUv_NWp23^Zek&4`lTxT{rZg+zn-8FUYLzLI(Zp-6*kK{eh z^yXNcW)eH9CSyi^zS_M z&Zr49>)-}DFd#LxS5)ce+?eg5xpvfEiJf*0G>i+-dsI*d;c#AOiiY{tLr;BBP)9{| z1OoC3=pnDOBqm?pgx8eRYgml?o_x<97;BAIfgE1)sHO1#?vPU1_I<8m5gPCh&%tSV zn>^cDtWB%*v@={=5k9BYh0%PBS5(?KK3>Vk;dDAxGK2Z|>%3j_%*cSyh1?uKpWVO} z`{o+h2B_u8U+hQ0$Y;3SC?5G2YjW0tRFr{KmaOwwVx0!$B(+uqrKZAJO@dCtEcAkG zDW|}dlb?@r(LZW@l#BXg9b$jWaa_{0of&|CUBQIxEVTF~$7 zxG6d#`n8e7I^%+_jzwXkO!v$Qjgy(3B#On@d-Sz3S58#4W=|ik&>IRVG(<AZZq64@JLjEQc)RD(DmteMHMGw;3mBP4&qY3kkjHgQbMK(% znC5;lR1nHHu+Ug@m1yo|XHuj7|1|f}WhdU8*upVoEsT^=Ogq%~gtA^fK0a2~T*u`+ ztl6o`;lQAsP~!~|RgpvYqc6#-cOEw&qIxuvQTc{68%inU+O0#d-50%!XpSY~S&$4)q#R<>wJo+YNlmc%h#``*Fe}e^W`qPn2IzvdNeM5kTSwx`XB1VJS+>}ZziGd+s!U;$Yt?O6l2b%_5|L}J&BS54&`41E&?}}1TI?K2smMJeni z<)S_WDY1Dp*1Z7sIP5Y&$aaGa7GHRfD1kPcC=-UP52KX1bP2&Qv{+mAT%iJgkq%<9 z`jNKyFC3|V4v~0>5O65`S3@Lh#R7lxdl-$}GOq|IGr)r;3xF)$q(#oGFET)WU?La; z-r**2knSLjawEj1dAPTY(dwk~nlZep^f*Is$!4F(hFx5#z!oggCqvwpA7`wzM=GK@<{IQG~r z0O%VX4pQCBcQ$05ao*!52u+aLWM7gt35WkjG97~5lkBX)pIQ{`y0>&I0PbhVag~1d zYR<@p4b79c0t`F32kkEzl&Jz=TEBE)zMj2@HCNu(2b7 zp6!9ovNEOGr4i^u`T#id;4<~&*28Dj5vBllP6-G^7Gqjnd<_#Gy#okoi2(+dRNEq0 zM7n^00D3q+48wO^r2l}+$U82)bsKqxqp~_&QHT&ar#KNg2iB3dm>pH-h-HzEfI0fa zDILLof%cqaG3H4a6yA+LQzfpOS9>*;E;`OpMLFaFxr{UN%8Kfo{nmhwK(?g+nz^;K^b-x6S)sx zyW|@2WhZ-)y`eq+$wN^flQok;HmV{tmYhiz^)$O_z{6b~?g=Y{taa^mLrAb?$7z3o zA65_g5zNpM>V}8Cnx-(ZNIW54Xw%xr2xH0BgHVfQlODp1wfpxr+Cb?m)Oi>%1MHJ60wIT$AK%uIm*t! zoZRFvAM;e~q7cN9`4G}yg9WpRLRHH{6aySqs3IyT$} z)xrhmENU~(T!G(}LKzXo8E3k11~WqnCzB7knf(VE2(B37O9+c-yNv`uQ62o5rs~$i zKS_ix0O*o6o3O-}V5eXoVTv!oh9Ln969o)}uD!BKeHklZtilMK!&M@w;qcF7cnZVS z(Qu6k-r?|XWVnps+GrRVTv$p={0}lbjp0)g-osoMB|8B6pixsF!}ek}3^;M6D8A^ z#Wdyg@@&`0bTQ)3898a_$lP)~G;b47%%VSzjspe(w|NZD6tD=e6;H`-@y>1Yt|X<# z$)^oL0ivJWg(x2t$ymfL(F&!dE;%czledaO)P@VzZBEj=%}$C}r#EKITjTsZvo(I} zQ&Aa@fc>v{1dgcb(@wcC>(u103=LoueWHX8jiLg6&lLoC5Pa|v;6ZNb=`5HA0^rXA z03*tLfg-;zI0P3seJC_UeQ#R};|6WueaI4p3K?H0fb5))Ty93J*r~%8xf3Z}z}Xaukzr~#Cm?(C?qF|qo`GaUyqm1i`aYeDqD}o5 z9&wJUGEC&;fui>b(bB zV!Fo+OYKRJ>J_}^7kDI~FPF;B`GxBB>I?P_^u?C%*HIJ6PmH(DIzhC?PdXmH?XN4{ zq}_(QmJuRvG4{>Kg7gYzA@=IZ02{vFiuenQ_bM9R+bl>*RBk6QQMi)Ct*9*?5Q23V z#C7U@m-FNXsjk*#$W0%B|NO|PNu+MvHP(5@OIzF z{@&i0p0*WSzd!qr4`2MAqWqg0<12^Cbv)4@P%x#YFqLU-wWi9qR@3BLujzQ}ZKGq> zOf~J3tL2!%wO0Pnl4XJ0N9vKv%!YPOsZFt5t;q7VX`VZrIZ{*w?=#FgQfsqsD6GKj zPZef!^PygwLwkx9(JnsJYV&AKvl+Bz_yWEzGVL9ubf*7-?cmxth~!3KMdN;w$tI6_?KpA-k9#8EtZaXUxhv}> zH8EC#UZ-zfj4BtS{yaFp-Q(im>T~7i%deEdI5Ar8p8FLoXJWNF`|`6#qsNzu%5^-^ zA_}fx9Ti$bte;jhn2xy^iM_^S;d@&LU0%z3VUK20Gn;O&$=6F}V%6(`+u`+kV%O`P zkoDSBFV^e#du}`ZQp+#jxx2o#vRO0VSi1Yh%AXZMGRfl6OBJk!h$^D#ioRR9$@ePb znN+%R0V@#wKFzFBuls=?*X!l(fgn@(E{SfSuv9~ploPYdS5c1f+`x%?-EJsi z=Yij5o-0zD==R!ervq#7yKU}tq*|iUZ=5jj__IzU6b|2aJJjLQmFksC#G&nM3qNQ& z+pf3kxb3zaB4vym*qd`KBy4po8wSQZ)bNFqie9$m!1u$RBSqw~LdpHUyCQxB#Mwf$T4?a(+k}PLWWcxQ`VJMPW(;wD&U{F5oe{97hh)7d`e~Z zp*295hVG`^^J73B1NV6g?)ikPB zsZOqVnp?w%dywg-HVN;5gLT}vnsK0!lh?>!~ZluSYULt@J1NvvIduuS_vqNA2t z`6;tL6NiZZ2-)>iGe5!b=vfp>-hg!%HCvrgZ3OK_v^3S$EVPMYYei6I>CyVq(cO+ zjN~{r{lCh;A}F0O{ZtmBj!a+n%AAK4q?8lxkZQcIIUi>#7f)aX#Ca5nI+P0U>#&8s z4U=##!zP@PcnV)fMj*aJ-DOm|KsDM;Pw8I(fGK13=Tcn?hx+}13K`%|slEVRr5#;# zkx^RFzD?=H36+xp93z=>#;TNGPp?v5(5^0MClCb`NxoiZp;xbqvqXBDii=bnizRCm zZAB3U^^kDKvJD+bFS~8qdRq4I&?CDDU0lZ#y^i7phR_&pZZv?CB$hBoSRyyV5_xVl zREZtcT0!E9sbm@!y&MJs_Ip1J`X5RErNGm15nH@Ap}=^@jS;J1vqb-6idS@FaDf^o?PDY_tbN_h1;PK2*$J`G~)?Y zcQ9cf)O;w(mHq|%VUC>vN2@jeP#sufr1YM` zX4&k}`nh#ad0z>3*{8KhEZj(TY zT#I@%C|w!lw2mu;dq9zbf)oX?sJGn}p~s`>M=xY-`o>k{ttfk<-8ZkcA_Ph8Y7b9W z?p%-5AESQ1KL_apLVP3kRj0r3H4>6y?Pniu!6~qFv9K4*H*%6BANw6n1k>B$-frLQ z#f_`4^q<^H$rRwQS+4ANefW75_4WSQ6(JD8kg@|%Hp!WZ-k)CC_qdE2vUz^>ojdE! zonGAS#m*-8xWAV&D4i2OgwZ3hT-vN}EN$Hqm(dg@qUHF0Ojzs+QD}PtAPbv`$@q4! zndsO|6SE6^8z;rdMN4!nWnyf+xv?UilYAKWLdKJs(KJT#CnlyG3h@H?$b_90JI5irSR4fp;YK7T+iKHjPTBpX9K> zScXKGD?Z9rPsNcWk2%z#ayrk6Hc%)91AvfjU6tXna7Bo;XOugkyKZAmU&1>|?dTy~%fF_a*7G8NVz+ANw?=R+%8DBLGE#rC{Xu z6Nn*&CiL|fYbMiKrbNd~>oq$y7fRA=#k77~rrO7eHQd@Du@jSQHcG)PX|q(6Mk`iO zuT4>xwe+M!+#-tB>Ky-Atb#O=ogb&|v`wYPD)+k^X#NvV^b!gskJJSzj3sa5@g;0G zwd1rbYW)i*E%BtQdE-5j-UK?OLDGB%$|1ou?TC&R)&7^+iX-4TfPo{mgSkANf}1*S z6L1pNKxTnsCK=zG1k}*}w&0GjRcC3E<=d3RNfau5J>v*8m&uW7ek@Abb@Zdjb0pv< z!3n_1qp*xYNfmEmq9r|59L-!tnp43-hL}hA7)j@~`U@u)RQ?tr>tuo;p23J@?&iu* zm+s!)s;@4+yOaiCnJ>_P1t~XKIPS4o-+FUx<<8wL`Ns(N;51?coPSRufYS;_-YnZY3T$}>eN&g0}ytk=?`+Slm- cDWWXTKn_lKQMGgp0oBqCooKc`YtDT1KgQ7a7ytkO diff --git a/python/tests/__init__.pyc b/python/tests/__init__.pyc deleted file mode 100644 index 82c3bcd7c94cf7977b0342cdfb9aa6ff57c89382..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104 zcmZSn%*(YT=X`830~9aYnUiuL2;GxIV_ b;^XxSDoZ$kqBgntDWy57b|AeaK+FIDIjIp* diff --git a/python/tests/__pycache__/__init__.cpython-37.pyc b/python/tests/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 8404afaa88a2416b90f787f370bf9a099e780e76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmZ?b<>g`kf+acUV?p#|5CH>>K!yVl7qb9~6oz01O-8?!3`HPe1o6vQKeRZts93)! zJ+Y`NQQsxCOyA2lBCs^Is8YY6vLquvProF!xTIJ=K0Y%qvm`!Vub}c4hfQvNN@-52 L9mufHK+FID3ke{U diff --git a/python/tests/__pycache__/test_JMXQuery.cpython-37.pyc b/python/tests/__pycache__/test_JMXQuery.cpython-37.pyc deleted file mode 100644 index 20c267f56169b5217ecc4a5a9f29f74d1f4405f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4567 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 From 4afadadfe3d9f47697dc92ed3d11e494cba8d430 Mon Sep 17 00:00:00 2001 From: Robert Garza Date: Tue, 19 Nov 2019 19:54:31 -0600 Subject: [PATCH 8/9] Updated with recommendations. --- python/jmxquery/__init__.py | 99 ++++++++++++++++------------------- python/setup.py | 3 ++ python/tests/test_JMXQuery.py | 5 +- 3 files changed, 50 insertions(+), 57 deletions(-) diff --git a/python/jmxquery/__init__.py b/python/jmxquery/__init__.py index 3183bf2..1169c51 100644 --- a/python/jmxquery/__init__.py +++ b/python/jmxquery/__init__.py @@ -12,17 +12,15 @@ import logging # Full Path to Jar -JAR_PATH = "%s/%s" % ( +JAR_PATH = os.path.join( os.path.dirname(os.path.realpath(__file__)), - 'JMXQuery-0.1.8.jar') + 'JMXQuery-0.1.8.jar' + ) -# Default Java path +# Default Java path and default timeout in seconds DEFAULT_JAVA_PATH = 'java' - -# Default timeout for running jar in seconds DEFAULT_JAR_TIMEOUT = 10 -logging.basicConfig() log = logging.getLogger('jmxQuery') @@ -58,32 +56,34 @@ def __init__(self, self.value = value self.value_type = value_type self.metric_name = metric_name - self.metric_labels = metric_labels + self.metric_labels = metric_labels or {} def to_query_string(self): """ Build a query string to pass via command line to JMXQuery Jar :return: The query string to find the MBean in format: + {mBeanName}/{attribute}/{attributeKey} - Example: java.lang:type=Memory/HeapMemoryUsage/init + + Example: java.lang:type=Memory/HeapMemoryUsage/init """ query = [] if self.metric_name: query.append(self.metric_name) - - if self.metric_labels != None: - if len(self.metric_labels) > 0: - query.append("<") - keyCount = 0 - for key, value in self.metric_labels.items(): - query.append("%s = %s" % ( - key, - value - )) - keyCount += 1 - if keyCount < len(self.metric_labels): - query.append(",") - query.append(">") + if self.metric_labels: + query.append("<") + total_count = len(self.metric_labels) + for count, (key, value) in enumerate( + self.metric_labels.items(), + 1 + ): + query.append("{} = {}".format( + key, + value) + ) + if count < total_count: + query.append(",") + query.append(">") query.append("==") query.append(self.mBeanName) @@ -95,24 +95,20 @@ def to_query_string(self): return ''.join(query) def to_string(self): - string = [] if self.metric_name: string.append(self.metric_name) - - if self.metric_labels != None: - if len(self.metric_labels) > 0: - string.append(" {") - keyCount = 0 - for key, value in self.metric_labels.items(): - string.append("%s = %s" % ( - key, - value - )) - keyCount += 1 - if keyCount < len(self.metric_labels): - string.append(",") - string.append("}") + if self.metric_labels: + string.append(" {") + total_count = len(self.metric_labels) + for count, (key, value) in enumerate( + self.metric_labels.items(), + 1 + ): + string.append("{} = {}".format(key, value)) + if count < total_count: + string.append(",") + string.append("}") else: string.append(self.mBeanName) if self.attribute: @@ -121,7 +117,10 @@ def to_string(self): string.append("/%s" % self.attributeKey) string.append(" = ") - string.append("%s ( %s )") + string.append("%s ( %s )" % ( + self.value, + self.value_type + )) return ''.join(string) @@ -130,7 +129,11 @@ class JMXConnection(object): The main class that connects to the JMX endpoint via a local JAR to run queries """ - def __init__(self, uri=None, user=None, passwd=None, jpath=DEFAULT_JAVA_PATH): + def __init__(self, + uri=None, + user=None, + passwd=None, + jpath=DEFAULT_JAVA_PATH): """ Creates instance of JMXQuery set to a specific connection uri for the JMX endpoint. @@ -153,8 +156,8 @@ def run_jar(self, queries, timeout): """ Run the JAR and return the results - :param query: The query - :return: The full command array to run via subprocess32 + :param query: The query + :return: The full command array to run via subprocess32 """ command = [ @@ -177,8 +180,6 @@ def run_jar(self, queries, timeout): queryString += query.to_query_string() + ";" command.extend(["-q", queryString]) - log.debug("Running command: " + str(command)) - print("Running command: %s" % str(command)) jsonOutput = "[]" try: @@ -189,22 +190,10 @@ def run_jar(self, queries, timeout): check=True) jsonOutput = output.stdout.decode('utf-8') - except subprocess32.TimeoutExpired as err: - log.error("Timeout of %s Expired: %s" % ( - str(err.timeout), - err)) - - except subprocess32.CalledProcessError as err: - log.error("Error calling JMX: %s" % ( - err)) - - raise - except Exception as err: log.error("Exception: %s" % err) raise - log.debug("JSON Output Received: %s" % jsonOutput) metrics = self.load_from_json(jsonOutput) return metrics diff --git a/python/setup.py b/python/setup.py index f012212..9ffb4e2 100644 --- a/python/setup.py +++ b/python/setup.py @@ -21,6 +21,9 @@ setup( name = 'jmxquery', packages = ['jmxquery'], + install_requires = [ + 'subprocess32' + ], version = '0.6.0', description = 'A JMX Interface for Python to Query runtime metrics in a JVM', long_description=long_description, diff --git a/python/tests/test_JMXQuery.py b/python/tests/test_JMXQuery.py index 99b66b0..64678e3 100644 --- a/python/tests/test_JMXQuery.py +++ b/python/tests/test_JMXQuery.py @@ -5,6 +5,7 @@ docker-compose -f docker-compose-kafka.yaml up """ +from __future__ import print_function import logging, sys import threading from nose.tools import assert_greater_equal @@ -133,9 +134,9 @@ def printMetrics(metrics): )) else: print("{%s} ({%s}) = {%s}" % ( - metric.to_query_string, + metric.to_query_string(), metric.value_type, metric.value )) - print("===================\nTotal Metrics: " + str(len(metrics))) \ No newline at end of file + print("===================\nTotal Metrics: " + str(len(metrics))) From 7d7e4c94af78c1183521c796d8434203a30e9531 Mon Sep 17 00:00:00 2001 From: Robert Garza Date: Wed, 20 Nov 2019 11:08:22 -0600 Subject: [PATCH 9/9] setup.py updated with version specific requirements. __init__.py updated with import recommendation. --- python/jmxquery/__init__.py | 32 +++++++++++++++----------------- python/setup.py | 3 ++- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/python/jmxquery/__init__.py b/python/jmxquery/__init__.py index 1169c51..3e82538 100644 --- a/python/jmxquery/__init__.py +++ b/python/jmxquery/__init__.py @@ -4,8 +4,10 @@ Python interface to JMX. Uses local jar to pass commands to JMX. Results returned. """ - -import subprocess32 +try: + import subprocess32 as subprocess +except: + import subprocess import os import json from enum import Enum @@ -157,7 +159,7 @@ def run_jar(self, queries, timeout): Run the JAR and return the results :param query: The query - :return: The full command array to run via subprocess32 + :return: The full command array to run via subprocess """ command = [ @@ -175,24 +177,20 @@ def run_jar(self, queries, timeout): "-p", self.jmx_password]) - queryString = "" + queryString = [] for query in queries: - queryString += query.to_query_string() + ";" + queryString.append("%s;" % query.to_query_string()) - command.extend(["-q", queryString]) + command.extend(["-q", ''.join(queryString)]) jsonOutput = "[]" - try: - output = subprocess32.run(command, - stdout=subprocess32.PIPE, - stderr=subprocess32.PIPE, - timeout=timeout, - check=True) - - jsonOutput = output.stdout.decode('utf-8') - except Exception as err: - log.error("Exception: %s" % err) - raise + output = subprocess.run(command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + timeout=timeout, + check=True) + + jsonOutput = output.stdout.decode('utf-8') metrics = self.load_from_json(jsonOutput) diff --git a/python/setup.py b/python/setup.py index 9ffb4e2..423d103 100644 --- a/python/setup.py +++ b/python/setup.py @@ -22,7 +22,8 @@ name = 'jmxquery', packages = ['jmxquery'], install_requires = [ - 'subprocess32' + 'subprocess32; python_version < "3.5"', + 'enum34; python_version < "3.4"' ], version = '0.6.0', description = 'A JMX Interface for Python to Query runtime metrics in a JVM',