101 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
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()
 |