Mini Shell
# vim: set ts=4 sw=4 expandtab syntax=python:
"""
ngxutil.influx
InfluxDB connector
@author J. Hipps <jacobh@inmotionhosting.com>
"""
import logging
import re
import json
import socket
from urllib.parse import urlparse
import arrow
import toml
from influxdb import InfluxDBClient
from ngxutil.util import *
logger = logging.getLogger('ngxutil')
def check_available():
"""
Checks if InfluxDB is available
"""
lconf = get_telegraf_config()
if not lconf:
logger.debug("InfluxDB is not available; no local Telegraf configuration found")
return False
try:
flux = InfluxDBClient(**lconf)
fluxver = flux.ping()
logger.debug("InfluxDB is available; version %s", fluxver)
except:
logger.debug("InfluxDB is not available; connection failed")
fluxver = False
return fluxver
def get_telegraf_config(confpath='/etc/telegraf/telegraf.conf'):
"""
Determine InfluxDB server and credentials from local Telegraf config
"""
oconf = {}
try:
with open(confpath) as f:
tconf = toml.load(f)
except Exception as e:
logger.debug("Unable to read local Telegraf configuration: %s", str(e))
return None
try:
# Determine InfluxDB server
sraw = tconf['outputs']['influxdb'][0]['urls']
if isinstance(sraw, list):
dburl = urlparse(sraw[0])
else:
dburl = urlparse(sraw)
oconf['host'] = dburl.hostname
oconf['port'] = dburl.port
oconf['ssl'] = dburl.scheme == 'https'
oconf['verify_ssl'] = bool(tconf['outputs']['influxdb'][0].get('insecure_skip_verify', False))
# Database, User, Password
oconf['database'] = tconf['outputs']['influxdb'][0]['database']
oconf['username'] = tconf['outputs']['influxdb'][0]['username']
oconf['password'] = tconf['outputs']['influxdb'][0]['password']
except Exception as e:
logger.error("Failed to parse Telegraf config: %s", str(e))
return None
return oconf
def fetch_all(domain, span, series='nginx_access'):
"""
Returns a list of all entries from InfluxDB for @domain
with @span hours
Compatible with the output from logparse.parse_log()
"""
tconf = get_telegraf_config()
if not tconf:
logger.error("Failed to read Telegraf config. Aborting InfluxDB query.")
return None
try:
flux = InfluxDBClient(**tconf)
except Exception as e:
logger.error("Failed to connect to InfluxDB: %s", str(e))
return None
if not span:
logger.info("No span defined, defaulting to 1 hour. Use --span to view a larger dataset.")
span = 1
# Construct query
if domain == '*':
thost = socket.getfqdn()
qq = 'SELECT * FROM {} WHERE (host = \'{}\') AND (time > now() - {}h)'.format(series, thost, span)
else:
qq = 'SELECT * FROM {} WHERE (vhost = \'{}\') AND (time > now() - {}h)'.format(series, domain, span)
# Run it
try:
logger.info("Fetching data from %s:%s...", tconf['host'], tconf['port'])
rez = list(flux.query(qq))[0]
logger.info("InfluxDB query returned %d results. Preparing report...", len(rez))
except Exception as e:
logger.error("InfluxDB query returned no results [%s]: %s", qq, str(e))
return None
return rez
Zerion Mini Shell 1.0