-
Notifications
You must be signed in to change notification settings - Fork 0
/
nmd
executable file
·154 lines (133 loc) · 4.98 KB
/
nmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env python3
import os, sys
import datetime
import time
import daemon
import daemon.pidfile
import argparse
import signal
import logging
import traceback
from appmonitor.appmonitor import AppMonitor
#TODO: move this to setup.py
__name__ = "netmicroscope-daemon"
__version__ = "1.0.3"
__author__ = "Guilherme Martins"
PROGNAME = 'appmonitor'
PATHCTRL = '/tmp/' #path to control files pid and lock
logpath = os.path.join(PATHCTRL, PROGNAME + ".log")
pidpath = os.path.join(PATHCTRL, PROGNAME + ".pid")
parser = argparse.ArgumentParser(prog = PROGNAME)
sp = parser.add_subparsers()
sp_start = sp.add_parser('start', help='Starts %(prog)s daemon.')
sp_stop = sp.add_parser('stop', help='Stops %(prog)s daemon.')
sp_status = sp.add_parser('status', help='Show the status of %(prog)s daemon.')
sp_restart = sp.add_parser('restart', help='Restarts %(prog)s daemon.')
sp_debug = sp.add_parser('debug', help='Starts %(prog)s daemon in debug mode.')
sp_kill = sp.add_parser('kill', help='Kill -9 %(prog)s daemon.')
sp_status.add_argument('-v', '--verbose', action='store_true', help='log extra informations')
sp_start.add_argument('-v', '--verbose', action='store_true', help='log extra informations')
sp_debug.add_argument('-v', '--verbose', action='store_true', help='log extra informations')
class MainCtrl:
thread_ctrl = {
'continue' : True,
}
mainctrl = MainCtrl()
def main_thread_stop(signum=None, frame=None):
mainctrl.thread_ctrl['continue'] = False
#print("continue:{0}".format(mainctrl.thread_ctrl['continue']))
mainctrl.thread_ctrl['app'].stop()
def main_thread(args, mainctrl, log):
verbose = False
if hasattr(args, 'verbose'):
verbose = args.verbose
if verbose:
log.info("ARGS:{0}".format(args))
try:
app = AppMonitor(mainctrl.thread_ctrl)
mainctrl.thread_ctrl['app'] = app
app.run()
except KeyboardInterrupt: # as ke:
if verbose:
log.warning("Interrupting...")
except Exception as e:
exc_type, _, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
log.error("Exception: ({0}) {1} {2} {3}".format(str(e), exc_type, fname, exc_tb.tb_lineno))
traceback.print_exc()
log.info("Exiting...")
def daemon_start(args=None):
print("INFO: {0} Starting ...".format(PROGNAME))
if os.path.exists(pidpath):
print("INFO: {0} already running (according to {1}).".format(PROGNAME, pidpath))
sys.exit(1)
else:
with daemon.DaemonContext(
stdout=sys.stdout,
stderr=sys.stderr,
signal_map={
signal.SIGTERM: main_thread_stop,
signal.SIGTSTP: main_thread_stop,
signal.SIGINT: main_thread_stop,
#signal.SIGKILL: daemon_stop, #SIGKILL is an Invalid argument
signal.SIGUSR1: daemon_status,
signal.SIGUSR2: daemon_status,
},
pidfile = daemon.pidfile.PIDLockFile(pidpath)
):
#**** when using python-daemon, initialize logging AFTER context creation ****
logging.basicConfig(format='%(asctime)s.%(msecs)03d %(levelname)s {%(module)s} [%(funcName)s] %(message)s',
datefmt='%Y-%m-%dT%H:%M:%S',
filename=logpath,
#filemode='w',
level=logging.INFO)
log = logging.getLogger(__name__)
main_thread(args, mainctrl, log)
def daemon_restart(args):
print("INFO: {0} Restarting...".format(PROGNAME))
daemon_stop()
time.sleep(1)
daemon_start(args)
def daemon_stop(args=None):
print("INFO: {0} Stopping with args {1}".format(PROGNAME, args))
if os.path.exists(pidpath):
with open(pidpath) as pid:
try:
os.kill(int(pid.readline()), signal.SIGINT)
except ProcessLookupError as ple:
os.remove(pidpath)
print("ERROR ProcessLookupError: {0}".format(ple))
else:
print("ERROR: process isn't running (according to the absence of {0}).".format(pidpath))
def daemon_debug(args):
print("INFO: running in debug mode.")
app = AppMonitor(mainctrl.thread_ctrl)
app.run()
mainctrl.thread_ctrl['app'] = app
def daemon_status(args):
if hasattr(args, 'verbose'):
if args.verbose:
print("INFO: pwd={}".format(os.getcwd()))
print("INFO: {0} Status arguments: {1}".format(PROGNAME, args))
if os.path.exists(pidpath):
print("INFO: Daemon is running")
else:
print("INFO: Daemon is NOT running.")
def daemon_kill(args):
if os.path.exists(pidpath):
with open(pidpath, "r") as f:
os.kill(int(f.readline()), signal.SIGKILL)
os.remove(pidpath)
else:
print("WARN: no process to kill")
sp_stop.set_defaults(callback=daemon_stop)
sp_status.set_defaults(callback=daemon_status)
sp_start.set_defaults(callback=daemon_start)
sp_restart.set_defaults(callback=daemon_restart)
sp_debug.set_defaults(callback=daemon_debug)
sp_kill.set_defaults(callback=daemon_kill)
args = parser.parse_args()
if hasattr(args, 'callback'):
args.callback(args)
else:
parser.print_help()