from datetime import datetime, timedelta from moira.graphite.evaluator import evaluateTarget from twisted.internet import defer from moira.checker import state from moira.checker import check from moira.checker.timeseries import TargetTimeSeries class Trigger(object): def __init__(self, id, db): self.id = id self.db = db @defer.inlineCallbacks def init(self, now, fromTime=None): self.maintenance = 0 json, self.struct = yield self.db.getTrigger(self.id) if json is None: defer.returnValue(False) self.is_simple = self.struct.get("is_simple_trigger", False) for tag in self.struct["tags"]: tag_data = yield self.db.getTag(tag) maintenance = tag_data.get('maintenance', 0) if maintenance > self.maintenance: self.maintenance = maintenance break self.ttl = self.struct.get("ttl") self.ttl_state = self.struct.get("ttl_state", state.NODATA) self.last_check = yield self.db.getTriggerLastCheck(self.id) begin = (fromTime or now) - 3600 if self.last_check is None: self.last_check = { "metrics": {}, "state": state.NODATA, "timestamp": begin } if self.last_check.get("timestamp") is None: self.last_check["timestamp"] = begin defer.returnValue(True) @defer.inlineCallbacks def get_timeseries(self, requestContext): targets = self.struct.get("targets", []) target_time_series = TargetTimeSeries() target_number = 1 for target in targets: time_series = yield evaluateTarget(requestContext, target) if target_number > 1: if len(time_series) == 1: target_time_series.other_targets_names["t%s" % target_number] = time_series[0].name elif not time_series: raise Exception("Target #%s has no timeseries" % target_number) else: raise Exception("Target #%s has more than one timeseries" % target_number) for time_serie in time_series: time_serie.last_state = self.last_check["metrics"].get( time_serie.name, { "state": state.NODATA, "timestamp": time_serie.start - 3600}) target_time_series[target_number] = time_series target_number += 1 defer.returnValue(target_time_series) @defer.inlineCallbacks def check(self, fromTime=None, now=None, cache_ttl=60): yield check.trigger(self, fromTime, now, cache_ttl) def isSchedAllows(self, ts): sched = self.struct.get('sched') if sched is None: return True timestamp = ts - ts % 60 - sched["tzOffset"] * 60 date = datetime.fromtimestamp(timestamp) if not sched['days'][date.weekday()]['enabled']: return False day_start = datetime.fromtimestamp(timestamp - timestamp % (24 * 3600)) start_datetime = day_start + timedelta(minutes=sched["startOffset"]) end_datetime = day_start + timedelta(minutes=sched["endOffset"]) if date < start_datetime: return False if date > end_datetime: return False return True