forked from jamesoff/simplemonitor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwinmonitor.py
executable file
·109 lines (84 loc) · 3.56 KB
/
winmonitor.py
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
import win32serviceutil
import win32service
import win32event
import socket
import os
import logging
import sys
import multiprocessing as mp
r"""
Notes:
This service expects the 'monitor.ini' file to exist in the same directory.
If you receive an error "The service did not respond to the start
or control request in a timely fashion", it is likely/possible you need to
include the python and pywin32 binaries in your path:
e.g. (from an administrator prompt)
setx /M PATH "%PATH%;c:\Python;c:\Python\scripts;c:\Python\Lib\site-packages\pywin32_system32;c:\Python\Lib\site-packages\win32"
"""
# Change this to the location of your config file, if required
APP_PATH = os.path.realpath(os.path.dirname(__file__))
CONFIG = os.path.join(APP_PATH, 'monitor.ini')
LOGFILE = os.path.join(APP_PATH, 'simplemonitor.log')
# Setup Logging
def configure_logger(logger, level=logging.DEBUG):
logger.setLevel(level)
fh = logging.FileHandler(LOGFILE)
fh.setLevel(level)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
return logger
def setup_logger(level=logging.DEBUG):
return configure_logger(mp.get_logger(), level)
LOGGER = setup_logger(logging.INFO)
class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "SimpleMonitor"
_svc_display_name_ = "SimpleMonitor"
_svc_description_ = "A service wrapper for the python SimpleMonitor program"
def __init__(self, args):
# Initialise service
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
# Setup logger
self.logger = LOGGER
self.logger.info("Initialised {} service".format(self._svc_display_name_))
def SvcStop(self):
self.logger.info("Stopping {} service".format(self._svc_display_name_))
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
self.logger.info("Starting {} service".format(self._svc_display_name_))
import servicemanager
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name, ''))
# Start monitor
p_mon = mp.Process(target=run_monitor)
p_mon.start()
self.logger.info("Started {} service".format(self._svc_display_name_))
# Wait for Monitor to finish
while True:
try:
# Watch monitor process for 2 seconds
p_mon.join(timeout=2)
if not p_mon.is_alive():
self.logger.warning("Service stopped prematurely.")
self.SvcStop()
# Check if we've received a stop command
rc = win32event.WaitForSingleObject(self.hWaitStop, 500)
if rc == win32event.WAIT_OBJECT_0:
p_mon.terminate()
p_mon.join()
break
self.logger.debug("Still running...")
except KeyboardInterrupt:
self.logger.warning("Interrupted {} service".format(self._svc_display_name_))
break
self.logger.info("Stopped {} service".format(self._svc_display_name_))
def run_monitor():
import monitor
sys.argv = ['monitor.py', "-vH", "--config={}".format(CONFIG)]
monitor.main()
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)