improve tomcat chart
Wei, He committed
Jul 27, 2017 at 13:28 UTC
28979a20abff889fdba56720a8db927ffa0d0bc2
1 file changed
+108
-26
python.d/tomcat.chart.py
+108
-26
@@ -1,9 +1,11 @@
1
# -*- coding: utf-8 -*-
2
# Description: tomcat netdata python.d module
3
# Author: Pawel Krupa (paulfantom)
4
+# Update author: Wing924
5
6
from base import UrlService
7
from re import compile
8
+import xml.etree.ElementTree as ET
9
10
try:
11
from urlparse import urlparse
@@ -16,61 +18,141 @@ priority = 60000
18
retries = 60
19
20
# charts order (can be overridden if you want less charts, or different order)
19
-ORDER = ['accesses', 'volume', 'threads', 'jvm']
21
+ORDER = ['accesses', 'bandwidth', 'processing_time', 'threads', 'jvm', 'jvm_eden', 'jvm_survivor', 'jvm_tenured']
22
23
CHARTS = {
24
'accesses': {
25
'options': [None, "Requests", "requests/s", "statistics", "tomcat.accesses", "area"],
26
'lines': [
25
- ["requestCount", 'accesses', 'incremental']
27
+ ["requestCount", 'accesses', 'incremental'],
28
+ ["errorCount", 'errors', 'incremental'],
29
]},
27
- 'volume': {
28
- 'options': [None, "Volume", "KB/s", "volume", "tomcat.volume", "area"],
30
+ 'bandwidth': {
31
+ 'options': [None, "Bandwidth", "KB/s", "statistics", "tomcat.bandwidth", "area"],
32
'lines': [
30
- ["bytesSent", 'volume', 'incremental', 1, 1024]
33
+ ["bytesSent", 'sent', 'incremental', 1, 1024],
34
+ ["bytesReceived", 'received', 'incremental', 1, 1024],
35
+ ]},
36
+ 'processing_time': {
37
+ 'options': [None, "processing time", "seconds", "statistics", "tomcat.processing_time", "area"],
38
+ 'lines': [
39
+ ["processingTime", 'processing time', 'incremental', 1, 1000]
40
]},
41
'threads': {
33
- 'options': [None, "Threads", "current threads", "statistics", "tomcat.threads", "line"],
42
+ 'options': [None, "Threads", "current threads", "statistics", "tomcat.threads", "area"],
43
'lines': [
44
["currentThreadCount", 'current', "absolute"],
45
["currentThreadsBusy", 'busy', "absolute"]
46
]},
47
'jvm': {
39
- 'options': [None, "JVM Free Memory", "MB", "statistics", "tomcat.jvm", "area"],
48
+ 'options': [None, "JVM Memory Pool Usage", "MB", "memory", "tomcat.jvm", "stacked"],
49
'lines': [
41
- ["free", None, "absolute", 1, 1048576]
42
- ]}
50
+ ["free", 'free', "absolute", 1, 1048576],
51
+ ["eden_used", 'eden', "absolute", 1, 1048576],
52
+ ["survivor_used", 'survivor', "absolute", 1, 1048576],
53
+ ["tenured_used", 'tenured', "absolute", 1, 1048576],
54
+ ["code_cache_used", 'code cache', "absolute", 1, 1048576],
55
+ ["compressed_used", 'compressed', "absolute", 1, 1048576],
56
+ ["metaspace_used", 'metaspace', "absolute", 1, 1048576],
57
+ ]},
58
+ 'jvm_eden': {
59
+ 'options': [None, "Eden Memory Usage", "MB", "memory", "tomcat.jvm_eden", "area"],
60
+ 'lines': [
61
+ ["eden_used", 'used', "absolute", 1, 1048576],
62
+ ["eden_commited", 'commited', "absolute", 1, 1048576],
63
+ ["eden_max", 'max', "absolute", 1, 1048576]
64
+ ]},
65
+ 'jvm_survivor': {
66
+ 'options': [None, "Survivor Memory Usage", "MB", "memory", "tomcat.jvm_survivor", "area"],
67
+ 'lines': [
68
+ ["survivor_used", 'used', "absolute", 1, 1048576],
69
+ ["survivor_commited", 'commited', "absolute", 1, 1048576],
70
+ ["survivor_max", 'max', "absolute", 1, 1048576]
71
+ ]},
72
+ 'jvm_tenured': {
73
+ 'options': [None, "Tenured Memory Usage", "MB", "memory", "tomcat.jvm_tenured", "area"],
74
+ 'lines': [
75
+ ["tenured_used", 'used', "absolute", 1, 1048576],
76
+ ["tenured_commited", 'commited', "absolute", 1, 1048576],
77
+ ["tenured_max", 'max', "absolute", 1, 1048576]
78
+ ]},
79
}
80
45
-
81
class Service(UrlService):
82
def __init__(self, configuration=None, name=None):
83
UrlService.__init__(self, configuration=configuration, name=name)
84
self.url = self.configuration.get('url', "http://127.0.0.1:8080/manager/status?XML=true")
85
+ self.connector_name = self.configuration.get('connector_name', None)
86
self.order = ORDER
87
self.definitions = CHARTS
88
89
def check(self):
54
- netloc = urlparse(self.url).netloc.rpartition(':')
55
- if netloc[1] == ':': port = netloc[2]
56
- else: port = 80
57
-
58
- self.regex_jvm = compile(r'<jvm>.*?</jvm>')
59
- self.regex_connector = compile(r'[a-z-]+%s.*?/connector' % port)
60
- self.regex = compile(r'([\w]+)=\\?[\'\"](\d+)\\?[\'\"]')
61
-
62
- return UrlService.check(self)
90
+ return UrlService.check(self) and self._get_data() != None
91
92
def _get_data(self):
93
"""
94
Format data received from http request
95
:return: dict
96
"""
69
- data = self._get_raw_data()
70
- if data:
71
- jvm = self.regex_jvm.findall(data) or ['']
72
- connector = self.regex_connector.findall(data) or ['']
73
- data = dict(self.regex.findall(''.join([jvm[0], connector[0]])))
74
-
75
- return data or None
97
+ data = None
98
+ raw_data = self._get_raw_data()
99
+ if raw_data:
100
+ xml = ET.fromstring(raw_data)
101
+ data = {}
102
+
103
+ jvm = xml.find('jvm')
104
+
105
+ connector = None
106
+ if self.connector_name:
107
+ for conn in xml.findall('connector'):
108
+ if conn.get('name') == self.connector_name:
109
+ connector = conn
110
+ break
111
+ else:
112
+ connector = xml.find('connector')
113
+
114
+ memory = jvm.find('memory')
115
+ data['free'] = memory.get('free')
116
+ data['total'] = memory.get('total')
117
+ data['used'] = int(data['total']) - int(data['free'])
118
119
+ for pool in jvm.findall('memorypool'):
120
+ name = pool.get('name')
121
+ if name == 'Eden Space':
122
+ data['eden_used'] = pool.get('usageUsed')
123
+ data['eden_commited'] = pool.get('usageCommitted')
124
+ data['eden_max'] = pool.get('usageMax')
125
+ elif name == 'Survivor Space':
126
+ data['survivor_used'] = pool.get('usageUsed')
127
+ data['survivor_commited'] = pool.get('usageCommitted')
128
+ data['survivor_max'] = pool.get('usageMax')
129
+ elif name == 'Tenured Gen':
130
+ data['tenured_used'] = pool.get('usageUsed')
131
+ data['tenured_commited'] = pool.get('usageCommitted')
132
+ data['tenured_max'] = pool.get('usageMax')
133
+ elif name == 'Code Cache':
134
+ data['code_cache_used'] = pool.get('usageUsed')
135
+ data['code_cache_commited'] = pool.get('usageCommitted')
136
+ data['code_cache_max'] = pool.get('usageMax')
137
+ elif name == 'Compressed':
138
+ data['compressed_used'] = pool.get('usageUsed')
139
+ data['compressed_commited'] = pool.get('usageCommitted')
140
+ data['compressed_max'] = pool.get('usageMax')
141
+ elif name == 'Metaspace':
142
+ data['metaspace_used'] = pool.get('usageUsed')
143
+ data['metaspace_commited'] = pool.get('usageCommitted')
144
+ data['metaspace_max'] = pool.get('usageMax')
145
+
146
+ if connector:
147
+ thread_info = connector.find('threadInfo')
148
+ data['currentThreadsBusy'] = thread_info.get('currentThreadsBusy')
149
+ data['currentThreadCount'] = thread_info.get('currentThreadCount')
150
+
151
+ request_info = connector.find('requestInfo')
152
+ data['processingTime'] = request_info.get('processingTime')
153
+ data['requestCount'] = request_info.get('requestCount')
154
+ data['errorCount'] = request_info.get('errorCount')
155
+ data['bytesReceived'] = request_info.get('bytesReceived')
156
+ data['bytesSent'] = request_info.get('bytesSent')
157
+
158
+ return data or None