Compare commits
No commits in common. "a802f2ee27696a0271bec386b468ad72eb66fc8f" and "658fbdf83cdea320d35c8c5b7f5797ccf1ed4b14" have entirely different histories.
a802f2ee27
...
658fbdf83c
5
app.py
5
app.py
|
@ -2,16 +2,13 @@ import fcntl
|
||||||
import hmac
|
import hmac
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import logging.config
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from flask import (Flask, request, jsonify, abort, render_template)
|
from flask import (Flask, request, jsonify, abort, render_template)
|
||||||
|
|
||||||
from ltsdb_json import LTS
|
from ltsdb_json import LTS
|
||||||
|
|
||||||
import config
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
logging.config.dictConfig(config.logging)
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import time
|
||||||
|
|
||||||
class LTS:
|
class LTS:
|
||||||
base_dir = "data"
|
base_dir = "data"
|
||||||
queue_dir = "queue"
|
|
||||||
limit = 1000
|
limit = 1000
|
||||||
|
|
||||||
def __init__(self, description=None, id=None):
|
def __init__(self, description=None, id=None):
|
||||||
|
@ -21,7 +20,6 @@ class LTS:
|
||||||
m.update(bytes(serialized_description, encoding="UTF-8"))
|
m.update(bytes(serialized_description, encoding="UTF-8"))
|
||||||
id = m.hexdigest()
|
id = m.hexdigest()
|
||||||
self.filename = self.base_dir + "/" + id
|
self.filename = self.base_dir + "/" + id
|
||||||
self.id = id
|
|
||||||
try:
|
try:
|
||||||
with open(self.filename, "r") as fh:
|
with open(self.filename, "r") as fh:
|
||||||
fcntl.flock(fh, fcntl.LOCK_SH)
|
fcntl.flock(fh, fcntl.LOCK_SH)
|
||||||
|
@ -59,8 +57,6 @@ class LTS:
|
||||||
fcntl.flock(fh, fcntl.LOCK_EX)
|
fcntl.flock(fh, fcntl.LOCK_EX)
|
||||||
json.dump({"description": self.description, "data": self.data}, fh)
|
json.dump({"description": self.description, "data": self.data}, fh)
|
||||||
fh.truncate()
|
fh.truncate()
|
||||||
with open(self.queue_dir + "/" + self.id, "w") as fh:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def rebuild_index(self):
|
def rebuild_index(self):
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
import os
|
|
||||||
import socket
|
|
||||||
import time
|
|
||||||
|
|
||||||
from ltsdb_json import LTS
|
|
||||||
|
|
||||||
node = socket.gethostbyaddr(socket.gethostname())[0]
|
|
||||||
|
|
||||||
class DiskFullPredictor:
|
|
||||||
def match(self, lts):
|
|
||||||
# measure=bytes_used, mountpoint=*
|
|
||||||
if "measure" not in lts.description:
|
|
||||||
return False
|
|
||||||
if lts.description["measure"] != "bytes_used":
|
|
||||||
return False
|
|
||||||
if "mountpoint" not in lts.description:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def run(self, lts):
|
|
||||||
# find matching bytes_usable series
|
|
||||||
desc = {**lts.description, "measure": "bytes_usable"}
|
|
||||||
usable_lts = LTS(description=desc)
|
|
||||||
# The two timeseries are always updated together, so the
|
|
||||||
# timestamps should match exactly. But just in case we decide to
|
|
||||||
# change that in the future accept a difference of up to an
|
|
||||||
# hour.
|
|
||||||
now = lts.data[-1][0]
|
|
||||||
if abs(now - usable_lts.data[-1][0]) > 3600:
|
|
||||||
log.warning("Timeseries %s and %s have different end times: %s vs %s",
|
|
||||||
lts.id, usable_lts.id,
|
|
||||||
now, usable_lts.data[-1][0])
|
|
||||||
return
|
|
||||||
current_used_bytes = lts.data[-1][1]
|
|
||||||
current_usable_bytes = usable_lts.data[-1][1]
|
|
||||||
tuf = float('inf')
|
|
||||||
for d in reversed(lts.data):
|
|
||||||
if d[1] < current_usable_bytes * 0.1:
|
|
||||||
continue # for sanity
|
|
||||||
if current_used_bytes ** 2 / d[1] > current_usable_bytes:
|
|
||||||
tuf = now - d[0]
|
|
||||||
break
|
|
||||||
desc = {**lts.description,
|
|
||||||
"measure": "time_until_disk_full",
|
|
||||||
"node": node,
|
|
||||||
"unit": "s",
|
|
||||||
"remote_addr": "",
|
|
||||||
}
|
|
||||||
lts = LTS(desc)
|
|
||||||
lts.add(now, tuf)
|
|
||||||
lts.save()
|
|
||||||
|
|
||||||
processors = [
|
|
||||||
DiskFullPredictor(),
|
|
||||||
]
|
|
||||||
|
|
||||||
def process(lts):
|
|
||||||
for processor in processors:
|
|
||||||
if processor.match(lts):
|
|
||||||
processor.run(lts)
|
|
||||||
|
|
||||||
while True:
|
|
||||||
for id in os.listdir("queue"):
|
|
||||||
lts = LTS(id=id)
|
|
||||||
os.remove("queue/" + id)
|
|
||||||
process(lts)
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue