Skip to content

Commit ea20de4

Browse files
authored
Merge pull request #199 from guydavis/develop
Improvements around Alerts.
2 parents 25bfca6 + e12439f commit ea20de4

21 files changed

+210
-162
lines changed

CREDITS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ A huge thank-you to the great teams/devs behind these projects, being used by Ma
1818
* [Other Icons](https://www.shareicon.net): Images and icons for web apps.
1919
* [Boostrap Sidebars](https://dev.to/codeply/bootstrap-5-sidebar-examples-38pb): Used for sidebar menu layout.
2020
* [Toplevel](https://github.com/and-semakin/marshmallow-toplevel): Used for list of objects sent to REST API.
21+
* [DataTables.js](https://datatables.net/): Filter/search/pagination of dynamic tables, as per [this tutorial](https://blog.miguelgrinberg.com/post/beautiful-interactive-tables-for-your-flask-templates).
2122

2223
## Blockchain Forks
2324
* [Flax](https://github.com/Flax-Network/flax-blockchain)

api/commands/chiadog_cli.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from flask import Flask, jsonify, abort, request, flash, g
1616
from subprocess import Popen, TimeoutExpired, PIPE
1717

18-
from api.models import chiadog
1918
from api import app
2019

2120
def load_config(blockchain):
@@ -46,10 +45,6 @@ def get_chiadog_pid(blockchain):
4645
return proc.info['pid']
4746
return None
4847

49-
def get_notifications(since):
50-
return chiadog.Notification.query.filter(chiadog.Notification.created_at >= since). \
51-
order_by(chiadog.Notification.created_at.desc()).limit(20).all()
52-
5348
def dispatch_action(job):
5449
service = job['service']
5550
if service != 'monitoring':

api/commands/log_parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def recent_challenges(blockchain):
3939
app.logger.debug(
4040
"Skipping challenges parsing as no such log file: {0}".format(log_file))
4141
return []
42-
proc = Popen("grep -i eligible {0} | tail -n {1}".format(log_file, CHALLENGES_TO_LOAD),
42+
proc = Popen("grep --text -i eligible {0} | tail -n {1}".format(log_file, CHALLENGES_TO_LOAD),
4343
stdout=PIPE, stderr=PIPE, shell=True)
4444
try:
4545
outs, errs = proc.communicate(timeout=90)

api/commands/plotman_cli.py

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,9 @@ def load_plotting_summary():
4141
except TimeoutExpired:
4242
proc.kill()
4343
proc.communicate()
44-
abort(500, description="The timeout is expired!")
44+
raise Exception("The timeout expired during plotman status.")
4545
if errs:
46-
app.logger.error(errs.decode('utf-8'))
47-
abort(500, description=errs.decode('utf-8'))
46+
raise Exception("Errors during plotman status:\n {0}".format(errs.decode('utf-8')))
4847
cli_stdout = outs.decode('utf-8')
4948
return plotman.PlottingSummary(cli_stdout.splitlines(), get_plotman_pid())
5049

@@ -76,14 +75,16 @@ def action_plots(job):
7675
#app.logger.info("About to {0} plots: {1}".format(action, plot_ids))
7776
for plot_id in plot_ids:
7877
try:
79-
suffix = ""
78+
param = ""
8079
if action == "kill":
81-
suffix = "--force"
80+
param = "--force"
8281
logfile = "/root/.chia/plotman/logs/plotman.log"
8382
log_fd = os.open(logfile, os.O_RDWR | os.O_CREAT)
8483
log_fo = os.fdopen(log_fd, "a+")
85-
proc = Popen("{0} {1} {2} {3}".format(PLOTMAN_SCRIPT, action, suffix, plot_id),
84+
proc = Popen("{0} {1} {2} {3}".format(PLOTMAN_SCRIPT, action, param, plot_id),
8685
shell=True, universal_newlines=True, stdout=log_fo, stderr=log_fo)
86+
# Plotman regressed on cleaning temp after kill so do it here:
87+
clean_tmp_dirs_after_kill(plot_id)
8788
except:
8889
app.logger.info('Failed to {0} selected plot {1}.'.format(action, plot_id))
8990
app.logger.info(traceback.format_exc())
@@ -98,16 +99,12 @@ def get_plotman_pid():
9899
def start_plotman():
99100
app.logger.info("Starting Plotman run...")
100101
check_config()
101-
try:
102-
if len(load_plotting_summary().rows) == 0: # No plots running
103-
clean_tmp_dirs_before_run()
104-
logfile = "/root/.chia/plotman/logs/plotman.log"
105-
proc = Popen("nohup {0} {1} < /dev/tty >> {2} 2>&1 &".format(PLOTMAN_SCRIPT, 'plot', logfile),
106-
shell=True, stdin=DEVNULL, stdout=None, stderr=None, close_fds=True)
107-
app.logger.info("Completed launch of plotman.")
108-
except:
109-
app.logger.info('Failed to start Plotman plotting run!')
110-
app.logger.info(traceback.format_exc())
102+
if len(load_plotting_summary().rows) == 0: # No plots running
103+
clean_tmp_dirs_before_run()
104+
logfile = "/root/.chia/plotman/logs/plotman.log"
105+
proc = Popen("nohup {0} {1} < /dev/tty >> {2} 2>&1 &".format(PLOTMAN_SCRIPT, 'plot', logfile),
106+
shell=True, stdin=DEVNULL, stdout=None, stderr=None, close_fds=True)
107+
app.logger.info("Completed launch of plotman.")
111108

112109
def clean_tmp_dirs_before_run():
113110
try:
@@ -126,15 +123,28 @@ def clean_tmp_dirs_before_run():
126123
p.unlink()
127124
except Exception as ex:
128125
app.logger.info("Skipping deletion of temp files due to {0}.".format(traceback.format_exc()))
129-
126+
127+
def clean_tmp_dirs_after_kill(plot_id):
128+
try:
129+
with open("/root/.chia/plotman/plotman.yaml") as f:
130+
config = yaml.safe_load(f)
131+
if 'directories' in config:
132+
if 'tmp' in config['directories']:
133+
for tmp_dir in config['directories']['tmp']:
134+
for p in pathlib.Path(tmp_dir).glob("*{0}*.tmp".format(plot_id)):
135+
app.logger.info("After kill, deleting stale tmp file: {0}".format(p))
136+
p.unlink()
137+
if 'tmp2' in config['directories']:
138+
tmp_dir = config['directories']['tmp2']
139+
for p in pathlib.Path(tmp_dir).glob("*{0}*.tmp".format(plot_id)):
140+
app.logger.info("After kill, deleting stale tmp file: {0}".format(p))
141+
p.unlink()
142+
except Exception as ex:
143+
app.logger.info("Skipping deletion of temp files due to {0}.".format(traceback.format_exc()))
130144

131145
def stop_plotman():
132146
app.logger.info("Stopping Plotman run...")
133-
try:
134-
os.kill(get_plotman_pid(), signal.SIGTERM)
135-
except:
136-
app.logger.info('Failed to stop Plotman plotting run!')
137-
app.logger.info(traceback.format_exc())
147+
os.kill(get_plotman_pid(), signal.SIGTERM)
138148

139149
def get_archiver_pid():
140150
for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
@@ -145,49 +155,39 @@ def get_archiver_pid():
145155
def start_archiver():
146156
app.logger.info("Starting archiver run...")
147157
check_config()
148-
try:
149-
logfile = "/root/.chia/plotman/logs/archiver.log"
150-
app.logger.info("About to start archiver...")
151-
proc = Popen("nohup {0} {1} < /dev/tty >> {2} 2>&1 &".format(PLOTMAN_SCRIPT, 'archive', logfile),
152-
shell=True, stdin=DEVNULL, stdout=None, stderr=None, close_fds=True)
153-
app.logger.info("Completed launch of archiver.")
154-
except:
155-
app.logger.info('Failed to start Plotman archiving run!')
156-
app.logger.info(traceback.format_exc())
158+
logfile = "/root/.chia/plotman/logs/archiver.log"
159+
app.logger.info("About to start archiver...")
160+
proc = Popen("nohup {0} {1} < /dev/tty >> {2} 2>&1 &".format(PLOTMAN_SCRIPT, 'archive', logfile),
161+
shell=True, stdin=DEVNULL, stdout=None, stderr=None, close_fds=True)
162+
app.logger.info("Completed launch of archiver.")
157163

158164
def stop_archiver():
159165
app.logger.info("Stopping Archiver run...")
160-
try:
161-
os.kill(get_archiver_pid(), signal.SIGTERM)
162-
except:
163-
app.logger.info('Failed to stop Plotman archiving run!')
164-
app.logger.info(traceback.format_exc())
166+
os.kill(get_archiver_pid(), signal.SIGTERM)
165167

166168
def load_config():
167169
return open('/root/.chia/plotman/plotman.yaml','r').read()
168170

169171
def save_config(config):
170-
try:
171-
# Validate the YAML first
172-
yaml.safe_load(config)
173-
# Save a copy of the old config file
174-
src = "/root/.chia/plotman/plotman.yaml"
175-
dst = "/root/.chia/plotman/plotman." + \
176-
time.strftime("%Y%m%d-%H%M%S")+".yaml"
177-
shutil.copy(src, dst)
178-
# Now save the new contents to main config file
179-
with open(src, 'w') as writer:
180-
writer.write(config)
181-
except Exception as ex:
182-
app.logger.info(traceback.format_exc())
183-
raise Exception('Updated plotman.yaml failed validation!\n' + str(ex))
184-
else: # Restart services if running
185-
if get_plotman_pid():
186-
stop_plotman()
187-
start_plotman()
188-
if get_archiver_pid():
189-
stop_archiver()
190-
start_archiver()
172+
# Validate the YAML first
173+
yaml.safe_load(config)
174+
# Save a copy of the old config file
175+
src = "/root/.chia/plotman/plotman.yaml"
176+
dst = "/root/.chia/plotman/plotman." + \
177+
time.strftime("%Y%m%d-%H%M%S")+".yaml"
178+
shutil.copy(src, dst)
179+
# Now save the new contents to main config file
180+
with open(src, 'w') as writer:
181+
writer.write(config)
182+
# Now try to validate config by calling plotman status
183+
load_plotting_summary()
184+
# Finally restart plotman and archiver if they are running
185+
if get_plotman_pid():
186+
stop_plotman()
187+
start_plotman()
188+
if get_archiver_pid():
189+
stop_archiver()
190+
start_archiver()
191191

192192
def find_plotting_job_log(plot_id):
193193
dir_path = '/root/.chia/plotman/logs'

api/default_settings.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ class DefaultConfig:
1313
SQLALCHEMY_TRACK_MODIFICATIONS = False
1414
SQLALCHEMY_DATABASE_URI = 'sqlite:////root/.chia/machinaris/dbs/machinaris.db'
1515
SQLALCHEMY_BINDS = {
16-
'stats': 'sqlite:////root/.chia/machinaris/dbs/stats.db',
17-
'chiadog': 'sqlite:////root/.chia/chiadog/dbs/chiadog.db',
16+
'stats': 'sqlite:////root/.chia/machinaris/dbs/stats.db'
1817
}
1918
SQLALCHEMY_ECHO = True if 'FLASK_ENV' in os.environ and os.environ['FLASK_ENV'] == "development" else False
2019
ETAG_DISABLED = True # https://flask-smorest.readthedocs.io/en/latest/etag.html

api/models/chiadog.py

Lines changed: 0 additions & 19 deletions
This file was deleted.

api/schedules/status_alerts.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414

1515
from flask import g
1616

17+
from common.models import alerts as a
1718
from common.config import globals
1819
from api.commands import chiadog_cli
19-
from api import app
20-
from api import utils
20+
from api import app, utils
2121

2222
first_run = True
2323

@@ -26,15 +26,19 @@ def update():
2626
if not globals.farming_enabled() and not globals.harvesting_enabled():
2727
#app.logger.info("Skipping alerts status collection on plotting-only instance.")
2828
return
29+
if globals.load()['is_controller']:
30+
#app.logger.info("Skipping alerts polling on fullnode are already placed in database directly via chiadog_notifier.sh script.")
31+
return
2932
with app.app_context():
3033
try:
34+
from api import db
3135
hostname = utils.get_hostname()
3236
if first_run: # On first launch, load last week of notifications
3337
since = (datetime.datetime.now() - datetime.timedelta(weeks=1)).strftime("%Y-%m-%d %H:%M:%S.000")
3438
first_run = False
3539
else: # On subsequent schedules, load only last 5 minutes.
3640
since = (datetime.datetime.now() - datetime.timedelta(minutes=5)).strftime("%Y-%m-%d %H:%M:%S.000")
37-
alerts = chiadog_cli.get_notifications(since)
41+
alerts = db.session.query(a.Alert).filter(a.Alert.created_at >= since).order_by(a.Alert.created_at.desc()).limit(20).all()
3842
payload = []
3943
for alert in alerts:
4044
payload.append({

api/views/actions/resources.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ def post(self):
5151
return make_response("Action completed.", 200)
5252
except Exception as ex:
5353
app.logger.info(traceback.format_exc())
54-
abort("Failed during {0} action.".format(service), 500)
54+
return str(ex), 400

api/views/configs/resources.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ def put(self, type):
5959
response = make_response("Successfully saved config.", 200)
6060
return response
6161
except Exception as ex:
62-
app.logger.error(traceback.format_exc())
63-
abort(400, str(ex))
62+
app.logger.info("Failed to save a validated Plotman config.")
63+
app.logger.info(traceback.format_exc())
64+
return str(ex), 400
6465

6566
def clean_config(self, req_data):
6667
# First decode the bytes

scripts/chiadog_notifier.sh

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@
66
event_priority_name="$1"
77
event_service_name="$2"
88
event_message="$3"
9+
hostname="$(hostname -s)"
10+
now="$(date +'%Y-%m-%d %H:%M:%S')"
11+
unique_id="${hostname}_chia_${now}"
12+
echo "Creating alert ${hostname}_chia_${now} ${event_service_name} ${event_priority_name}: ${event_message}"
913

10-
cd /root/.chia/chiadog/dbs
11-
sqlite3 chiadog.db <<EOF
12-
INSERT INTO notification (blockchain,priority,service,message,created_at) VALUES ('chia','${event_priority_name//\'/\'\'}','${event_service_name//\'/\'\'}','${event_message//\'/\'\'}', strftime('%Y-%m-%d %H:%M:%S','now'));
14+
cd /root/.chia/machinaris/dbs
15+
sqlite3 -cmd '.timeout 5000' machinaris.db <<EOF
16+
INSERT INTO alerts (unique_id,hostname,blockchain,priority,service,message,created_at) VALUES ('${unique_id}', '${hostname}', 'chia','${event_priority_name//\'/\'\'}','${event_service_name//\'/\'\'}','${event_message//\'/\'\'}', '${now}');
1317
EOF

0 commit comments

Comments
 (0)