main.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import time
  2. import datetime
  3. import os
  4. import sys
  5. import logging
  6. from enum import Enum
  7. from influxdb_client import InfluxDBClient, Point
  8. from influxdb_client.client.write_api import SYNCHRONOUS
  9. from pihole import PiHole
  10. logger = logging.Logger('pihole-to-influxdb')
  11. logger.addHandler(logging.StreamHandler(sys.stdout))
  12. class AppMode(Enum):
  13. Live = 1
  14. Totals = 2
  15. Raw = 3
  16. try:
  17. # optional Logger Settings
  18. logging.basicConfig(level=os.getenv("LOG_LEVEL", "DEBUG"))
  19. # InfluxDB Settings
  20. DB_URL = os.environ['INFLUX_DB_URL']
  21. DB_ORG = os.environ['INFLUX_DB_ORG']
  22. DB_TOKEN = os.environ['INFLUX_DB_TOKEN']
  23. DB_BUCKET = os.environ['INFLUX_DB_BUCKET']
  24. # PiHole Settings
  25. PIHOLE_URL = str(os.environ['PIHOLE_URL'])
  26. QUERY_INTERVAL = int(os.environ['PIHOLE_INTERVAL'])
  27. # optional Pi-hole authentication
  28. AUTHENTICATION_TOKEN = os.getenv('PIHOLE_AUTHENTICATION', None)
  29. # optional App Mode
  30. APP_MODE = AppMode(os.getenv('APP_MODE', 'Totals'))
  31. except KeyError as e:
  32. logger.fatal('Missing environment variable: {}'.format(e))
  33. sys.exit(1)
  34. except ValueError as e:
  35. logger.fatal('Invalid environment variable: {}'.format(e))
  36. sys.exit(1)
  37. if APP_MODE != AppMode.Totals and not AUTHENTICATION_TOKEN:
  38. logger.fatal('Pi-hole authentication token is required for live data')
  39. sys.exit(1)
  40. influxdb_client = InfluxDBClient(DB_URL, DB_TOKEN, org=DB_ORG)
  41. pihole = PiHole(PIHOLE_URL, AUTHENTICATION_TOKEN)
  42. def main():
  43. write_api = influxdb_client.write_api(write_options=SYNCHRONOUS)
  44. next_update = time.monotonic()
  45. logger.info('Starting PiHole Data Logger to InfluxDB')
  46. logger.info('AppMode: {}'.format(APP_MODE))
  47. # Test Pi-hole connection
  48. try:
  49. pihole.request_summary()
  50. except Exception as e:
  51. logger.fatal('Unable to connect to Pi-hole: {}'.format(e))
  52. sys.exit(1)
  53. while True:
  54. try:
  55. if APP_MODE == AppMode.Live:
  56. timestamp = datetime.datetime.now()
  57. data = list(pihole.get_queries_for_influxdb(timestamp, QUERY_INTERVAL))
  58. elif APP_MODE == AppMode.Totals:
  59. data = list(pihole.get_totals_for_influxdb())
  60. elif APP_MODE == AppMode.Raw:
  61. data = list(pihole.get_query_logs_for_influxdb())
  62. logger.debug('Writing {} points to InfluxDB'.format(len(data)))
  63. write_api.write(bucket=DB_BUCKET, record=data)
  64. sleep_duration = QUERY_INTERVAL
  65. except Exception as e:
  66. logger.exception('Failed to get data from Pi-Hole to InfluxDB')
  67. # Sleep at most two minutes
  68. sleep_duration = min(QUERY_INTERVAL, 120)
  69. next_update = next_update + sleep_duration
  70. logger.debug("Now sleeping for {}".format(datetime.timedelta(seconds=sleep_duration)))
  71. time.sleep(max(0, next_update - time.monotonic()))
  72. if __name__ == '__main__':
  73. main()