-
Notifications
You must be signed in to change notification settings - Fork 600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bind collector: Adding support for new some v3 XML bind9 stats and JSON v1 #562
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,11 @@ publish | resolver, server, zonemgmt, sockets, memory, | Available stats:<br> | |
| list | ||
publish_view_bind | False | | bool | ||
publish_view_meta | False | | bool | ||
data_format | xml_v2 | Bind stats version:<br> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The table gets messed up, not sure whats the best way to handle it though |
||
- xml_v2 (Original bind stats version from 9.5)<br> | ||
- xml_v3 (New xml version)<br> | ||
- json_v1 (JSON replacement for XML)<br> | ||
| str | ||
|
||
#### Example Output | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,10 @@ def get_default_config_help(self): | |
" - memory (Global memory usage)\n", | ||
'publish_view_bind': "", | ||
'publish_view_meta': "", | ||
'data_format': "Bind stats version:\n" + | ||
" - xml_v2 (Original bind stats version from 9.5)\n" + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should pick There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like this was corrected, thanks! |
||
" - xml_v3 (New xml version)\n" + | ||
" - json_v1 (JSON replacement for XML)\n", | ||
}) | ||
return config_help | ||
|
||
|
@@ -63,6 +67,7 @@ def get_default_config(self): | |
# By default we don't publish these special views | ||
'publish_view_bind': False, | ||
'publish_view_meta': False, | ||
'data_format': 'xml_v2', | ||
}) | ||
return config | ||
|
||
|
@@ -73,7 +78,62 @@ def clean_counter(self, name, value): | |
self.publish(name, value) | ||
|
||
def collect(self): | ||
if self.config['data_format'] == 'json_v1': | ||
return self.collect_json_v1() | ||
if self.config['data_format'] == 'xml_v3': | ||
return self.collect_xml_v3() | ||
if self.config['data_format'] == 'xml_v2': | ||
return self.collect_xml_v2() | ||
|
||
def collect_json_v1(self): | ||
try: | ||
# Try newest interface first (JSON has least impact) | ||
import json | ||
req = urllib2.urlopen('http://%s:%d/json/v1/status' % ( | ||
self.config['host'], int(self.config['port']))) | ||
except Exception, e: | ||
self.log.error('JSON v1 not supported: %s', e) | ||
return {} | ||
|
||
if 'server' in self.config['publish']: | ||
try: | ||
req = urllib2.urlopen('http://%s:%d/json/v1/server' % ( | ||
self.config['host'], int(self.config['port']))) | ||
except Exception, e: | ||
self.log.error('Couldnt connect to bind: %s', e) | ||
return {} | ||
|
||
response = json.load(req) | ||
self.parse_json_v1_server(response) | ||
|
||
def collect_xml_v3(self): | ||
try: | ||
# Try newer interface first | ||
req = urllib2.urlopen('http://%s:%d/xml/v3/status' % ( | ||
self.config['host'], int(self.config['port']))) | ||
except Exception, e: | ||
self.log.error('XML v3 not supported: %s', e) | ||
return {} | ||
|
||
if 'server' in self.config['publish']: | ||
try: | ||
req = urllib2.urlopen('http://%s:%d/xml/v3/server' % ( | ||
self.config['host'], int(self.config['port']))) | ||
except Exception, e: | ||
self.log.error('Couldnt connect to bind: %s', e) | ||
return {} | ||
# Proceed with v3 parsing | ||
tree = ElementTree.parse(req) | ||
|
||
if not tree: | ||
raise ValueError("Corrupt XML file, no statistics found") | ||
|
||
self.parse_xml_v3_server(tree) | ||
|
||
def collect_xml_v2(self): | ||
try: | ||
# NOTE: Querying this node on a large server can impact bind | ||
# answering queriesfor sometimes hundreds of milliseconds. | ||
req = urllib2.urlopen('http://%s:%d/' % ( | ||
self.config['host'], int(self.config['port']))) | ||
except Exception, e: | ||
|
@@ -87,6 +147,10 @@ def collect(self): | |
|
||
root = tree.find('bind/statistics') | ||
|
||
if not root: | ||
raise ValueError( | ||
"Missing bind/statistics tree - Wrong data_format?") | ||
|
||
if 'resolver' in self.config['publish']: | ||
for view in root.findall('views/view'): | ||
name = view.find('name').text | ||
|
@@ -153,3 +217,45 @@ def collect(self): | |
'memory.%s' % counter.tag, | ||
int(counter.text) | ||
) | ||
|
||
def parse_xml_v3_server(self, root): | ||
for counters in root.findall('server/counters'): | ||
for counter in counters: | ||
self.clean_counter( | ||
'server.counters.%s.%s' % (counters.attrib['type'], | ||
counter.attrib['name']), | ||
int(counter.text) | ||
) | ||
|
||
for view in root.findall('views/view'): | ||
for counters in view.iter('counters'): | ||
for counter in counters: | ||
self.clean_counter( | ||
'views.%s.counters.%s.%s' % (view.attrib['name'], | ||
counters.attrib['type'], | ||
counter.attrib['name']), | ||
int(counter.text) | ||
) | ||
|
||
def parse_json_v1_server(self, response): | ||
for counter_metric_name in [ | ||
'nsstat', 'opcode', 'qtype', 'rcode', 'zonestat' | ||
]: | ||
for counter in response[counter_metric_name+'s']: | ||
self.clean_counter( | ||
'server.counters.%s.%s' % (counter_metric_name, counter), | ||
int(response[counter_metric_name+'s'][counter]) | ||
) | ||
|
||
for view in response['views']: | ||
for counters in response['views'][view]: | ||
# This mapping maps from XML v3 layout to JSON v1 | ||
for section_name in response['views'][view]['resolver']: | ||
for counter in \ | ||
response['views'][view]['resolver'][section_name]: | ||
self.clean_counter( | ||
'views.%s.counters.%s.%s' % | ||
(view, section_name, counter), | ||
int(response['views'][view]['resolver'] | ||
[section_name][counter]) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mode change?
100644 → 100755