backend.when_runrules.make_log_from_rule()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 7
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
'''
2
# listens for statistics updated and run rules on them
3
# some rules can run just from the last statistics
4
# other rules will need to be enforced from the history of the miner
5
'''
6
import datetime
7
import json
8
from colorama import Fore
9
from helpers.queuehelper import QueueName, QueueEntries
10
from domain.mining import MinerCommand
11
from domain.miningrules import MinerStatisticsRule
12
from domain.logging import MinerLog
13
from backend.fcmcomponent import ComponentName
14
from backend.fcmapp import Component
15
import backend.fcmutils as utils
16
17
class ComponentRunRules(Component):
18
    '''component for running rules'''
19
    def __init__(self):
20
        self.alertstext = ''
21
        super().__init__(componentname=ComponentName.rules, option='')
22
23
    def addalert(self, alertmsg):
24
        self.alertstext += alertmsg
25
        return alertmsg
26
27
RULES = ComponentRunRules()
28
29
def rules(miner, minerstats, minerpool):
30
    '''this runs the rules'''
31
    entries = QueueEntries()
32
    if miner is None or minerstats is None:
33
        return entries
34
    savedminer = RULES.app.getminer(miner)
35
    broken = gather_broken_rules(savedminer, minerstats)
36
    if broken:
37
        #TODO: could raise broken rule event???
38
        for rule in broken:
39
            RULES.app.log_mineractivity(make_log_from_rule(rule))
40
            add_entry_for_rule(entries, rule)
41
    return entries
42
43
def gather_broken_rules(savedminer, minerstats):
44
    broken = []
45
    for ruleparms in RULES.app.ruleparameters():
46
        rule = MinerStatisticsRule(savedminer, minerstats, ruleparms)
47
        if rule.isbroken():
48
            broken += rule.brokenrules
49
    return broken
50
51
def add_entry_for_rule(entries, rule):
52
    cmd_restart = MinerCommand('restart', '')
53
    if rule.action == 'alert':
54
        entries.addalert(RULES.addalert(RULES.app.stamp(rule.parameter)))
55
    elif rule.action == 'restart':
56
        entries.add(QueueName.Q_RESTART, RULES.app.createmessagecommand(rule.miner, cmd_restart))
57
        entries.addalert(RULES.addalert(RULES.app.stamp('Restarted {0}'.format(rule.miner.name))))
58
    else:
59
        RULES.app.logerror('did not process broken rule {0}'.format(rule.parameter))
60
61
def make_log_from_rule(rule):
62
    log = MinerLog()
63
    log.createdate = datetime.datetime.utcnow()
64
    log.minerid = rule.miner.key()
65
    log.minername = rule.miner.name
66
    log.action = rule.parameter
67
    return log
68
69
def when_statisticsupdated(channel, method, properties, body):
70
    '''when miner stats are pulled from miner...'''
71
    print("[{0}] Received miner stats".format(RULES.app.now()))
72
    try:
73
        msg = RULES.app.messagedecodeminerstats(body)
74
        entries = dorules(msg.miner, msg.minerstats, msg.minerpool)
75
        RULES.app.enqueue(entries)
76
    except json.decoder.JSONDecodeError as jex:
77
        RULES.app.logexception(jex)
78
        RULES.app.logdebug(RULES.app.exceptionmessage(jex))
79
        RULES.app.logdebug(utils.safestring(body))
80
    except BaseException as ex:
81
        RULES.app.logexception(ex)
82
        RULES.app.logdebug(RULES.app.exceptionmessage(ex))
83
        RULES.app.logdebug(utils.safestring(body))
84
85
def dorules(miner, minerstats, minerpool):
86
    '''run the rules on them'''
87
    RULES.alertstext = ''
88
    entries = rules(miner, minerstats, minerpool)
89
    if RULES.alertstext:
90
        print(Fore.RED + RULES.alertstext)
91
    print("Rules executed for {0}".format(miner.name))
92
    return entries
93
94
def main():
95
    if RULES.app.isrunnow:
96
        for (miner, stats, pool) in RULES.app.getminerstatscached():
97
            rules(miner, stats, pool)
98
        RULES.app.shutdown()
99
    else:
100
        RULES.listeningqueue = RULES.app.listen_to_broadcast(QueueName.Q_STATISTICSUPDATED, when_statisticsupdated)
101
102
if __name__ == "__main__":
103
    main()
104