解决:
问题已解决。不是多个电话的问题。与错误初始化导致的重复日志记录处理程序有关。
更新模块module_2run.py检查日志记录FileHandler只有一个:
import logging, os
from logging import FileHandler
# LOGGING
def log_init():
# Check FileHandler is NOT already in logging handlers
for h_ in logging.getLogger().handlers:
if isinstance(h_, FileHandler):
return logging.getLogger(__name__)
# Set initial logging level
logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.DEBUG)
# Add FileHandler
l2f_ = logging.FileHandler(os.path.splitext(os.path.basename(__file__))[0] + ".log")
l2f_.setLevel(logging.INFO)
l2f_.setFormatter(logging.Formatter("%(levelname)s: %(asctime)s %(message)s"))
logging.getLogger().addHandler(l2f_)
return logging.getLogger(__name__)
_log = log_init()
# MAIN
def main():
_log.info("Do main job")
if __name__ == '__main__':
main()
感谢所有看过的人!
初步问题:
我一直遇到问题。也许有人已经遇到过类似的人,可以帮助我。 我在python上编写了一个非常简单的Windows服务。它工作,一切都很好看。 每次迭代只有一个奇怪的效果,主要作业的模块调用次数增加1。 在第一次迭代模块被调用一次,第二次 - 两次,第三次 - 三次,依此类推...... 我在Windows模块内部进行了一些日志记录 - 在主模块调用之前和之后进行日志记录。 我还将记录放在主模块中 - 主模块调用了多少次。下面的屏幕截图。
windows_service.py
import win32event, win32service, win32serviceutil
import os, sys, time, subprocess, importlib
import servicemanager, traceback
from win32api import CloseHandle, GetLastError, SetConsoleCtrlHandler
'''
http://www.chrisumbel.com/article/windows_services_in_python
'''
class WindowsService(win32serviceutil.ServiceFramework):
# you can NET START/STOP the service by the following name
_svc_name_ = "WindowsService"
# this text shows up as the service name in the Service
# Control Manager (SCM)
_svc_display_name_ = "Windows Service"
# this text shows up as the description in the SCM
_svc_description_ = "Windows service example"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self,args)
SetConsoleCtrlHandler(lambda x: True, True)
# create an event to listen for stop requests on
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self.module_2run = None
# core logic of the service
def SvcDoRun(self):
# Go to module install directory
os.chdir(os.path.dirname(__file__))
servicemanager.LogMsg (
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,'')
)
try: # try main
rc_ = None
# if the stop event hasn't been fired keep looping
while rc_ != win32event.WAIT_OBJECT_0:
# Log message before module run
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
0xF000, ("Call module_2run", '')
)
# Import of reload module to run
if not self.module_2run: self.module_2run = importlib.import_module('module_2run')
else: importlib.reload(self.module_2run)
# Call module main function
self.module_2run.main()
# Log message after module run
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
0xF000, ("Exit module_2run", '')
)
# block for 20 seconds and listen for a stop event every 5 seconds
wt_ = 20000
ct_ = 5000
ic_ = wt_ / ct_
while ic_ >= 0:
ic_ -= 1
rc_ = win32event.WaitForSingleObject(self.hWaitStop, ct_)
if rc_ == win32event.WAIT_OBJECT_0: break
except:
servicemanager.LogErrorMsg(traceback.format_exc()) # if error print it to event log
os._exit(-1) # return some value other than 0 to OS so that service knows to restart
# called when we're being shut down
def SvcStop(self):
# tell the SCM we're shutting down
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
# fire the stop event
win32event.SetEvent(self.hWaitStop)
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(WindowsService)
module_2run.py
import logging, os, sys, importlib
# LOGGING
# Set initial logging level
logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.DEBUG)
# Add logging to file
l2f_ = logging.FileHandler(os.path.splitext(os.path.basename(__file__))[0] + ".log")
l2f_.setLevel(logging.INFO)
l2f_.setFormatter(logging.Formatter("%(levelname)s: %(asctime)s %(message)s"))
logging.getLogger().addHandler(l2f_)
_log = logging.getLogger(__name__)
# MAIN
def main():
_log.info("Do main job")
In event log I can see two messages for each call - before and after: