Skip to content

Commit

Permalink
Clean up none used endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
thenodon committed Sep 4, 2019
1 parent cd5bfea commit 1e5a320
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 90 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ icinga2-exporter
The icinga2-exporter utilizes the [Icinga 2](https://icinga.com/) REST API to fetch service based performance
data and publish it in a way that lets [Prometheus](https://prometheus.io/) scrape the performance data as metrics.

The service is based on [Quart](https://pgjones.gitlab.io/quart/). Quart's is compatible with Flask but based
on Asyncio.

Benefits:

- Enable advanced queries and aggregation on timeseries
Expand Down Expand Up @@ -81,7 +84,7 @@ All configuration is made in the config.yml file.
Example:
```yaml
# Port can be overridden by using -p if running development flask
# Port can be overridden by using -p if running development quart
#port: 9638
icinga2:
Expand Down Expand Up @@ -189,21 +192,21 @@ scrape_configs:

# Running

## Development with flask built in webserver
## Development with quart built in webserver

python -m icinga2_exporter -f config.yml

The switch -p enable setting of the port.

## Production with gunicorn
## Production with gunicorn as ASGI continer

Running with default config.yml. The default location is current directory

gunicorn --access-logfile /dev/null -w 4 "wsgi:create_app()"
gunicorn --access-logfile /dev/null -w 4 -k uvicorn.workers.UvicornWorker "wsgi:create_app()"

Set the path to the configuration file.

gunicorn --access-logfile /dev/null -w 4 "wsgi:create_app('/etc/icinga2-exporter/config.yml')"
gunicorn --access-logfile /dev/null -w 4 -k uvicorn.workers.UvicornWorker "wsgi:create_app('/etc/icinga2-exporter/config.yml')"

> Port for gunicorn is default 8000, but can be set with -b, e.g. `-b localhost:9638`

Expand Down
25 changes: 14 additions & 11 deletions icinga2_exporter/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@
"""

import argparse
from quart import Quart
import icinga2_exporter.log as log
import icinga2_exporter.fileconfiguration as config
import icinga2_exporter.proxy as proxy

from quart import Quart
from icinga2_exporter.proxy import app as icinga2
import icinga2_exporter.monitorconnection as monitorconnection


Expand Down Expand Up @@ -57,14 +56,13 @@ def start():
port = args.port

log.configure_logger(configuration)
##

monitorconnection.MonitorConfig(configuration)
log.info('Starting web app on port: ' + str(port))

app = proxy.app #Quart(__name__)

#app.register_blueprint(proxy.app, url_prefix='/')
app = Quart(__name__)
app.register_blueprint(icinga2, url_prefix='')
list_routes(app)
app.run(host='0.0.0.0', port=port)


Expand All @@ -86,9 +84,14 @@ def create_app(config_path=None):
monitorconnection.MonitorConfig(configuration)
log.info('Starting web app')

app = proxy.app # Quart(__name__)

#app.register_blueprint(proxy.app, url_prefix='/')
#app.register_blueprint(proxy.app)
app = Quart(__name__)
app.register_blueprint(icinga2, url_prefix='')

return app

def list_routes(app):
import urllib
output = []
for rule in app.url_map.iter_rules():
print("route")
print (rule)
2 changes: 0 additions & 2 deletions icinga2_exporter/monitorconnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,6 @@ async def async_post(self, url, body):
'X-HTTP-Method-Override': 'GET'},
data=json.dumps(body)) as response:
re = await response.text()
print(re)
print(response.status)
return json.loads(re)
finally:
pass
48 changes: 3 additions & 45 deletions icinga2_exporter/perfdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,50 +42,7 @@ def __init__(self, monitor: Monitor, query_hostname: str):
self.perfname_to_label = monitor.get_perfname_to_label()
self.perfdatadict = {}

def get_perfdata(self) -> dict:
"""
Collect icinga2 data and parse it into prometheus metrics
:return:
"""

data_json = self.monitor.get_perfdata(self.query_hostname)
if 'results' in data_json:
for serivce_attrs in data_json['results']:
if 'attrs' in serivce_attrs and 'last_check_result' in serivce_attrs['attrs'] and 'performance_data' in \
serivce_attrs['attrs']['last_check_result']:
check_command = serivce_attrs['attrs']['check_command']
# Get default labels
labels = {'hostname': serivce_attrs['attrs']['host_name'],
'service': serivce_attrs['attrs']['display_name']}

# For all host custom vars add as label
labels.update(Perfdata.get_host_custom_vars(serivce_attrs))

for perf_string in serivce_attrs['attrs']['last_check_result']['performance_data']:
perf = Perfdata.parse_perfdata(perf_string)

# For each perfdata metrics
for perf_data_key, perf_data_value in perf.items():

if 'value' in perf_data_value:
prometheus_key = self.format_promethues_metrics_name(check_command, perf_data_key,
perf_data_value)

# Add more labels based on perfname
if check_command in self.perfname_to_label:
labels.update(
Perfdata.add_labels_by_items(
self.perfname_to_label[check_command]['label_name'],
perf_data_key))

prometheus_key_with_labels = Perfdata.concat_metrics_name_and_labels(labels,
prometheus_key)

self.perfdatadict.update({prometheus_key_with_labels: str(perf_data_value['value'])})

return self.perfdatadict

async def async_get_perfdata(self) -> dict:
async def get_perfdata(self) -> dict:
"""
Collect icinga2 data and parse it into prometheus metrics
:return:
Expand All @@ -95,7 +52,8 @@ async def async_get_perfdata(self) -> dict:
if 'results' in data_json:
for serivce_attrs in data_json['results']:
if 'attrs' in serivce_attrs and 'last_check_result' in serivce_attrs['attrs'] and 'performance_data' in \
serivce_attrs['attrs']['last_check_result']:
serivce_attrs['attrs']['last_check_result'] and \
serivce_attrs['attrs']['last_check_result']['performance_data'] is not None:
check_command = serivce_attrs['attrs']['check_command']
# Get default labels
labels = {'hostname': serivce_attrs['attrs']['host_name'],
Expand Down
28 changes: 4 additions & 24 deletions icinga2_exporter/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,44 +19,24 @@
"""
import asyncio
from quart import request, Response, jsonify, Quart
from quart import request, Response, jsonify, Quart, Blueprint

from prometheus_client import (CONTENT_TYPE_LATEST, Counter)

from icinga2_exporter.perfdata import Perfdata
import icinga2_exporter.monitorconnection as monitorconnection
import icinga2_exporter.log as log

app = Quart( __name__)
#app = Quart( __name__)
app = Blueprint( 'icinga2',__name__)
total_requests = Counter('requests', 'Total requests to monitor-exporter endpoint')

loop = asyncio.new_event_loop()

@app.route('/', methods=['GET'])
def hello_world():
return 'monitor-exporter alive'


@app.route("/metrics", methods=['GET'])
def get_metrics():
log.info(request.url)
target = request.args.get('target')

log.info('Collect metrics', {'target': target})

monitor_data = Perfdata(monitorconnection.MonitorConfig(), target)

# Fetch performance data from Monitor
monitor_data.get_perfdata()

target_metrics = monitor_data.prometheus_format()

resp = Response(target_metrics)
resp.headers['Content-Type'] = CONTENT_TYPE_LATEST

return resp

@app.route("/ametrics", methods=['GET'])
async def get_ametrics():
log.info(request.url)
target = request.args.get('target')
Expand All @@ -66,7 +46,7 @@ async def get_ametrics():
monitor_data = Perfdata(monitorconnection.MonitorConfig(), target)

# Fetch performance data from Monitor
await asyncio.get_event_loop().create_task(monitor_data.async_get_perfdata())
await asyncio.get_event_loop().create_task(monitor_data.get_perfdata())

target_metrics = monitor_data.prometheus_format()

Expand Down
27 changes: 24 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
aiofiles==0.4.0
aiohttp==3.5.4
async-timeout==3.0.1
asyncio==3.4.3
attrs==19.1.0
blinker==1.4
certifi==2019.6.16
chardet==3.0.4
Click==7.0
coverage==4.5.4
Flask==1.1.1
Flask-Ext==0.1
dataclasses==0.6
gunicorn==19.9.0
h11==0.8.1
h2==3.1.1
hpack==3.0.0
httptools==0.0.13
Hypercorn==0.5.4
hyperframe==5.2.0
idna==2.8
idna-ssl==1.1.0
itsdangerous==1.1.0
Jinja2==2.10.1
MarkupSafe==1.1.1
multidict==4.5.2
prometheus-client==0.7.1
python-json-logger==0.1.11
pytoml==0.1.21
PyYAML==5.1.2
Quart==0.6.14
requests==2.22.0
sortedcontainers==2.1.0
typing-extensions==3.7.4
urllib3==1.25.3
Werkzeug==0.15.5
uvicorn==0.8.6
uvloop==0.12.2
websockets==7.0
wsproto==0.15.0
yarl==1.3.0

0 comments on commit 1e5a320

Please sign in to comment.