python - Python Windows 服务 - 日志记录不起作用
问题描述
使用 Python 3.7、Windows 10 专业版、Pywin32
我有一个测试脚本,它启动服务并在发出不同命令时将一些基本行推送到日志文件中。代码如下:
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import logging
class AppServerSvc(win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
_svc_description_ = "New Test Service"
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Class opened')
def __init__(self, args):
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Init')
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Stop')
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Run')
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.main()
def main(self):
print("running")
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Main')
if __name__ == '__main__':
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Calling Handle Command Line')
win32serviceutil.HandleCommandLine(AppServerSvc)
我已经完成了基本的故障排除,服务正在安装、启动、重新启动和被删除,没有任何错误。但是,我希望日志文件能够接收基本输出以显示功能被击中,但事实并非如此。
我在管理员命令提示符下进行的调用:
C:\PythonScripts\SearchServer>python servicetest.py install
Installing service TestService
Service installed
C:\PythonScripts\SearchServer>python servicetest.py start
Starting service TestService
C:\PythonScripts\SearchServer>python servicetest.py restart
Restarting service TestService
C:\PythonScripts\SearchServer>python servicetest.py remove
Removing service TestService
Service removed
C:\PythonScripts\SearchServer>
日志文件内容:
INFO:root:Class opened
INFO:root:Calling Handle Command Line
INFO:root:Class opened
INFO:root:Calling Handle Command Line
INFO:root:Class opened
INFO:root:Calling Handle Command Line
INFO:root:Class opened
INFO:root:Calling Handle Command Line
正如您所看到的,每次发出命令时都会触发该服务,但是我希望也会调用内部函数。作为服务和 Python 的新手,我想知道我是否遗漏了什么?我假设函数名称是预定义的,不需要我设置委托来访问它们。这不是我在遇到的任何问题中看到的。
我当然假设这些功能应该被击中并且它们被击中并且能够创建日志?
感激地收到任何帮助。
解决方案
代码有几个问题:
- logging.basicConfig() 应该只调用一次,如果再次调用它不会有任何效果。
if __name__ == '__main__':
由于代码的自然流动,类定义将首先在您的代码中调用,甚至在块之前。因此,您在类定义中的 logging.basicConfig() 中设置的任何内容都将成为整个脚本的最终版本。它不是这种设置的理想位置,因此应该移动到其他地方(在顶部,最好在课堂外)。- logging.basicConfig 中传入的 filename 参数应该是绝对文件路径,因为一旦服务开始运行,它的当前路径就不会和脚本一样,所以 logging 将无法找到日志文件。(服务的当前工作目录将变为 C:\Python37\lib\site-packages\win32)。
- (可选):尽量不要使用 root 日志配置,最好有一个 logger 实例供自己使用。
在所有这些更改之后,脚本将如下所示:
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import logging.handlers
log_file_path = "" # mention full path here
mylogger = logging.getLogger("TestLogger")
mylogger.setLevel(logging.INFO)
handler = logging.handlers.RotatingFileHandler(log_file_path)
mylogger.addHandler(handler)
class AppServerSvc(win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
_svc_description_ = "New Test Service"
mylogger.info('Class opened')
def __init__(self, args):
mylogger.info('Init')
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
mylogger.info('Stop')
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
mylogger.info('Run')
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.main()
def main(self):
print("running")
mylogger.info('Main')
if __name__ == '__main__':
mylogger.info('Calling Handle Command Line')
win32serviceutil.HandleCommandLine(AppServerSvc)
输出:
Class opened Init Run Main Class opened Calling Handle Command Line
推荐阅读
- migration - MS-Access 报告忽略了一些但不是所有 Win-10 PC 的标准
- angular - 通过服务器的 Angular 通用 API 调用
- r - 加入标记回到句子
- javascript - 拖动选定的文本以在网页内复制/移动它?
- sql - 如何列出所有由杰夫·高布伦主演但不包括布鲁斯·威利斯的电影?
- python - 将图像合并到 z-stack 中并在 Python 中进行最大投影 /
- javascript - 如何将数据导入到 gatbsy-config.js
- python - 如何修复所需的位置参数?
- php - 在 WP Shortcode 中显示来自 mySQL 的数据字段
- r - 'Sum' 函数返回 TRUE 或 FALSE 值而不是数字?