import sys import asyncio import aionotify import yaml import os import tempfile import requests from yaml_include import Constructor def generateConfig(): Constructor.add_to_loader_class( loader_class=yaml.FullLoader, base_dir="/share/prometheus/" ) with open("prometheus.template") as f: data = yaml.load(f, Loader=yaml.FullLoader) data["scrape_configs"] = ( data[".scrape_configs_static"] + data[".scrape_configs_included"] ) del data[".scrape_configs_static"] del data[".scrape_configs_included"] return yaml.dump(data, default_flow_style=False, default_style="") def testConfig(config): tmp = None result = False try: tmp = tempfile.NamedTemporaryFile() with open(tmp.name, "w") as f: f.write(config) r = os.system("promtool check config " + tmp.name + "> /dev/null") result = r == 0 except: print("Failed to validate") raise if not result: raise Exception("validation error") return result def writeConfig(config, file): try: with open(file, "w") as f: f.write(config) r = requests.post(url="http://localhost:9090/-/reload", data={}) except: print("Exception") loop = asyncio.get_event_loop() paths_to_watch = ["/share/prometheus/targets/"] lock = asyncio.Lock() async def compile(): if lock.locked() == False: await lock.acquire() try: config = generateConfig() testConfig(config) writeConfig(config, "/etc/prometheus/prometheus.yml") print("Compiled") except: pass finally: lock.release() async def watcher(): asyncio.create_task(compile()) filewatch = aionotify.Watcher() for path in paths_to_watch: filewatch.watch( path, aionotify.Flags.MODIFY | aionotify.Flags.CREATE | aionotify.Flags.DELETE, ) print(path) await filewatch.setup(loop) while True: event = await filewatch.get_event() sys.stdout.write("Got event: %s\n" % repr(event)) asyncio.create_task(compile()) filewatch.close() def main(): try: loop.run_until_complete(watcher()) finally: # loop.close() pass if __name__ == "__main__": main()