Skip to content
This repository has been archived by the owner on Mar 5, 2024. It is now read-only.

Commit

Permalink
Add IPv6 listen compatibility code (#4)
Browse files Browse the repository at this point in the history
* Add IPv6 listen compatibility code

* Update README with the requirements to use Py3

* Fix old -l code to be able to parse ipv6 as parameters

* Make pycodestyle happy

Co-authored-by: Stefan Safar <[email protected]>
  • Loading branch information
zloo and Stefan Safar authored Sep 2, 2020
1 parent f22909a commit 89d3496
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 7 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ daemon.
You can either use this as a standalone exporter that listens on an HTTP port, or use it to save data
on disk in a .prom file either periodically or just once, and run it from cron or something similar.

Warning: since 0.3.0, the code relies on Python3 specific code. If you need to use Python2, use
the 0.2.6 version.
# Usage
```
usage: ethtool-exporter.py [-h] (-f TEXTFILE_NAME | -l LISTEN) [-i INTERVAL]
Expand Down
54 changes: 47 additions & 7 deletions ethtool-exporter.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#!/usr/bin/env python
"""Collect ethtool metrics,publish them via http or save them to a file."""
import argparse
from http.server import HTTPServer
import logging
import os
import re
import socket
import socketserver
import subprocess
import sys
import time
Expand All @@ -13,6 +16,7 @@
import prometheus_client
from prometheus_client.core import GaugeMetricFamily


class EthtoolCollector(object):
"""Collect ethtool metrics,publish them via http or save them to a file."""

Expand All @@ -39,7 +43,22 @@ def _parse_args(self, args):
'-l',
'--listen',
dest='listen',
help='Listen host:port, i.e. 0.0.0.0:9417'
help=('OBSOLETE. Use -L/-p instead. '
'Listen host:port, i.e. 0.0.0.0:9417')
)
group.add_argument(
'-p',
'--port',
dest='port',
type=int,
help='Port to listen on, i.e. 9417'
)
parser.add_argument(
'-L',
'--listen-address',
dest='listen_address',
default='0.0.0.0',
help='IP address to listen on'
)
parser.add_argument(
'-i',
Expand Down Expand Up @@ -120,7 +139,8 @@ def update_ethtool_stats(self, iface, gauge):
"""Update gauge with statistics from ethtool for interface iface."""
command = [self.ethtool, '-S', iface]
try:
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc = subprocess.Popen(command, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except FileNotFoundError:
logging.critical(self.ethtool + ' not found. Giving up')
sys.exit(1)
Expand All @@ -131,7 +151,8 @@ def update_ethtool_stats(self, iface, gauge):
data, err = proc.communicate()
if proc.returncode != 0:
logging.critical('Ethtool returned non-zero return '
'code for interface {}, the message was: {}'.format(iface, err))
'code for interface {}, the message'
'was: {}'.format(iface, err))
return
data = data.decode('utf-8').split('\n')
key_set = set()
Expand Down Expand Up @@ -181,6 +202,11 @@ def find_physical_interfaces(self):
if re.match(self.args['interface_regex'], file):
yield file


class IPv6HTTPServer(HTTPServer):
address_family = socket.AF_INET6


if __name__ == '__main__':
path = os.getenv("PATH", "")
path = os.pathsep.join([path, "/usr/sbin", "/sbin"])
Expand All @@ -192,11 +218,25 @@ def find_physical_interfaces(self):
collector.ethtool = ethtool
registry = prometheus_client.CollectorRegistry()
registry.register(collector)
EthtoolMetricsHandler = prometheus_client.MetricsHandler.factory(registry)
args = collector.args
if args['listen']:
(ip, port) = args['listen'].split(':')
prometheus_client.start_http_server(port=int(port),
addr=ip, registry=registry)
if args['listen'] or args['port']:
if args['listen']:
logging.warning(('You are using obsolete argument -l.'
'Please switch to -L and -p'))
(ip, port) = args['listen'].rsplit(':', 1)
else:
ip = args['listen_address']
port = args['port']
# Remove optional IPv6 braces if present, i.e. [::1] => ::1
ip = ip.replace('[', '').replace(']', '')
port = int(port)
if ':' in ip:
server_class = IPv6HTTPServer
else:
server_class = HTTPServer
httpd = server_class((ip, port), EthtoolMetricsHandler)
httpd.serve_forever()
while True:
time.sleep(3600)
if args['textfile_name']:
Expand Down

0 comments on commit 89d3496

Please sign in to comment.