@cryptotaxi247 / netdata-1 / commits / dd1ddace1

Tomcat status invalid XML fix (#6345)

* Fix Tomcat status invalid XML due to attributes with single quote content

Danamir committed Jun 26, 2019 at 21:42 UTC dd1ddace10d790bc3a164fcda63fa245c82b84f7
1 file changed +36 -5
collectors/python.d.plugin/tomcat/tomcat.chart.py
+36 -5
@@ -5,11 +5,17 @@
5 # SPDX-License-Identifier: GPL-3.0-or-later
6
7 import xml.etree.ElementTree as ET
8 +import re
9
10 from bases.FrameworkServices.UrlService import UrlService
11
12 MiB = 1 << 20
13
14 +# Regex fix for Tomcat single quote XML attributes
15 +# affecting Tomcat < 8.5.24 & 9.0.2 running with Java > 9
16 +# cf. https://bz.apache.org/bugzilla/show_bug.cgi?id=61603
17 +single_quote_regex = re.compile(r"='([^']+)'([^']+)''")
18 +
19 ORDER = [
20 'accesses',
21 'bandwidth',
@@ -95,6 +101,32 @@ class Service(UrlService):
101 self.definitions = CHARTS
102 self.url = self.configuration.get('url', 'http://127.0.0.1:8080/manager/status?XML=true')
103 self.connector_name = self.configuration.get('connector_name', None)
104 + self.parse = self.xml_parse
105 +
106 + def xml_parse(self, data):
107 + try:
108 + return ET.fromstring(data)
109 + except ET.ParseError:
110 + self.debug('%s is not a valid XML page. Please add "?XML=true" to tomcat status page.' % self.url)
111 + return None
112 +
113 + def xml_single_quote_fix_parse(self, data):
114 + data = single_quote_regex.sub(r"='\g<1>\g<2>'", data)
115 + return self.xml_parse(data)
116 +
117 + def check(self):
118 + self._manager = self._build_manager()
119 +
120 + raw_data = self._get_raw_data()
121 + if not raw_data:
122 + return False
123 +
124 + if single_quote_regex.search(raw_data):
125 + self.warning('Tomcat status page is returning invalid single quote XML, please consider upgrading '
126 + 'your Tomcat installation. See https://bz.apache.org/bugzilla/show_bug.cgi?id=61603')
127 + self.parse = self.xml_single_quote_fix_parse
128 +
129 + return self.parse(raw_data) is not None
130
131 def _get_data(self):
132 """
@@ -104,11 +136,10 @@ class Service(UrlService):
136 data = None
137 raw_data = self._get_raw_data()
138 if raw_data:
107 - try:
108 - xml = ET.fromstring(raw_data)
109 - except ET.ParseError:
110 - self.debug('%s is not a vaild XML page. Please add "?XML=true" to tomcat status page.' % self.url)
139 + xml = self.parse(raw_data)
140 + if xml is None:
141 return None
142 +
143 data = {}
144
145 jvm = xml.find('jvm')
@@ -153,7 +184,7 @@ class Service(UrlService):
184 data['metaspace_committed'] = pool.get('usageCommitted')
185 data['metaspace_max'] = pool.get('usageMax')
186
156 - if connector:
187 + if connector is not None:
188 thread_info = connector.find('threadInfo')
189 data['currentThreadsBusy'] = thread_info.get('currentThreadsBusy')
190 data['currentThreadCount'] = thread_info.get('currentThreadCount')