当 python 代码从 windows 服务启动时,记录器文件轮换不起作用
Logger file rotation not working when python code started from windows service
我正在从 windows 服务(在 python 中创建,使用 pyinstaller 转换为 exe 并使用 sc 安装)启动一个 python 应用程序(使用 pyInstaller 创建的 exe 版本)但是我的应用程序生成的日志文件没有轮换。
所以我实际上使用了一个 logger.conf 文件,该文件具有带有 rotatingFileHandler 的记录器配置,以在每 10KB 后旋转文件(用于测试目的)。 conf 文件中的配置如下所示:
...
[handler_fileRotationHandler]
class=logging.handlers.RotatingFileHandler
level=NOTSET
formatter=simpleFormatter
args=('<absolute path of log file>','a',10240,5)
...
在 python 代码中,我使用此配置来创建和轮换日志文件。
以下是正确的日志文件轮换有效的案例列表:
1- python 版本开始使用 python 命令
2- exe 版本(使用 PyInstaller 创建)在直接双击启动时工作正常
3- 从 windows 服务启动时的 exe 版本也在 python 中创建,如果使用 python 命令安装服务,如下所示:
MyService.py install
现在这是它不起作用的时候:
我正在将 windows 服务代码转换为 exe(再次使用 pyInstaller)并使用以下命令通过 sc 安装服务:
sc create MyService binPath= "<absolute path of service exe file>"
当开始使用这个服务时,应用程序工作正常,也会生成日志文件,但是在达到 fileHandler 中为日志定义的最大大小后,它不会创建另一个日志文件,因此在日志方面卡住只有那里。该应用程序继续正常运行,只是没有记录日志。
这是我尝试和观察到的:
1- 在这两种情况下,我都使用 subprocess.Popen() 命令启动了我的应用程序 exe 版本,并且我的应用程序没有任何 UI 元素,因此它在后台的 windows 会话 0 中完美运行.仅供参考,以防相关。
2- 如果我删除现有的日志语句和空日志文件,日志将开始记录到文件中,并在达到最大大小时再次停止。
3-我已经使用 os.getcwd() 命令获取我的应用程序在启动时运行的目录,在两种情况下我都在以下目录中找到:
in python service installed using python case, app runs in "C:\Users\AppData\Local\Programs\Python\Python36\lib\site-packages\win32"
而在使用 sc 案例安装的服务启动的 exe 版本中,应用程序在 "C:\Windows\system32"
中运行
虽然在这两种情况下,logging.conf 文件都提供了日志文件创建路径,所以我假设这应该不是任何问题(事实上,日志文件确实在预期位置创建,只是文件轮换不起作用,所以我猜这不相关)
我只需要使用sc安装的exe版本,而不是python服务版本。如何解决这个问题,任何帮助或指导或方向表示赞赏。
[任何有兴趣了解解决方案的人]
所以,我面临的问题是 RotationFileHandler 中的一个常见问题,它是两个处理程序同时处理同一文件的问题,因此阻碍了 RotationFileHandler 重命名填充的日志文件。
为了详细说明,我将异常处理放在 handler.py 中的 RotationFileHandler 源代码中,并在文件中打印异常。从那里我得到的问题是:
...
[WinError 32] The process cannot access the file because it is being used by another process: 'C:\Users\<path to log>\test.log' -> 'C:\Users\<path to log>\test.log.1'
...
在搜索更多内容时,我发现在 windows 的记录器中使用 FileRotationHandler 是一种常见的情况,有时由于多种可能的原因,多个句柄打开同一个日志文件,因此轮换文件处理程序无法使用重命名文件。
stumbled upon this thread explaining many possible scenarios
我使用 procexp 工具检查我的日志文件是否有多个句柄(由其他应用程序打开)。我发现,因为我对服务代码和应用程序代码使用了相同的 logging.conf,所以它们都有打开的句柄来记录两者的文件。我为服务代码创建了一个单独的配置文件,问题就消失了。 :)
我唯一不知道的是为什么这只发生在服务和应用程序的 exe 版本中而不是 python 版本中,因为理想情况下问题应该发生在 运行也作为 python 代码。
我正在从 windows 服务(在 python 中创建,使用 pyinstaller 转换为 exe 并使用 sc 安装)启动一个 python 应用程序(使用 pyInstaller 创建的 exe 版本)但是我的应用程序生成的日志文件没有轮换。
所以我实际上使用了一个 logger.conf 文件,该文件具有带有 rotatingFileHandler 的记录器配置,以在每 10KB 后旋转文件(用于测试目的)。 conf 文件中的配置如下所示:
...
[handler_fileRotationHandler]
class=logging.handlers.RotatingFileHandler
level=NOTSET
formatter=simpleFormatter
args=('<absolute path of log file>','a',10240,5)
...
在 python 代码中,我使用此配置来创建和轮换日志文件。
以下是正确的日志文件轮换有效的案例列表:
1- python 版本开始使用 python 命令
2- exe 版本(使用 PyInstaller 创建)在直接双击启动时工作正常
3- 从 windows 服务启动时的 exe 版本也在 python 中创建,如果使用 python 命令安装服务,如下所示:
MyService.py install
现在这是它不起作用的时候:
我正在将 windows 服务代码转换为 exe(再次使用 pyInstaller)并使用以下命令通过 sc 安装服务:
sc create MyService binPath= "<absolute path of service exe file>"
当开始使用这个服务时,应用程序工作正常,也会生成日志文件,但是在达到 fileHandler 中为日志定义的最大大小后,它不会创建另一个日志文件,因此在日志方面卡住只有那里。该应用程序继续正常运行,只是没有记录日志。
这是我尝试和观察到的:
1- 在这两种情况下,我都使用 subprocess.Popen() 命令启动了我的应用程序 exe 版本,并且我的应用程序没有任何 UI 元素,因此它在后台的 windows 会话 0 中完美运行.仅供参考,以防相关。
2- 如果我删除现有的日志语句和空日志文件,日志将开始记录到文件中,并在达到最大大小时再次停止。
3-我已经使用 os.getcwd() 命令获取我的应用程序在启动时运行的目录,在两种情况下我都在以下目录中找到:
in python service installed using python case, app runs in "C:\Users\AppData\Local\Programs\Python\Python36\lib\site-packages\win32"
而在使用 sc 案例安装的服务启动的 exe 版本中,应用程序在 "C:\Windows\system32"
中运行虽然在这两种情况下,logging.conf 文件都提供了日志文件创建路径,所以我假设这应该不是任何问题(事实上,日志文件确实在预期位置创建,只是文件轮换不起作用,所以我猜这不相关)
我只需要使用sc安装的exe版本,而不是python服务版本。如何解决这个问题,任何帮助或指导或方向表示赞赏。
[任何有兴趣了解解决方案的人]
所以,我面临的问题是 RotationFileHandler 中的一个常见问题,它是两个处理程序同时处理同一文件的问题,因此阻碍了 RotationFileHandler 重命名填充的日志文件。
为了详细说明,我将异常处理放在 handler.py 中的 RotationFileHandler 源代码中,并在文件中打印异常。从那里我得到的问题是:
...
[WinError 32] The process cannot access the file because it is being used by another process: 'C:\Users\<path to log>\test.log' -> 'C:\Users\<path to log>\test.log.1'
...
在搜索更多内容时,我发现在 windows 的记录器中使用 FileRotationHandler 是一种常见的情况,有时由于多种可能的原因,多个句柄打开同一个日志文件,因此轮换文件处理程序无法使用重命名文件。
stumbled upon this thread explaining many possible scenarios
我使用 procexp 工具检查我的日志文件是否有多个句柄(由其他应用程序打开)。我发现,因为我对服务代码和应用程序代码使用了相同的 logging.conf,所以它们都有打开的句柄来记录两者的文件。我为服务代码创建了一个单独的配置文件,问题就消失了。 :)
我唯一不知道的是为什么这只发生在服务和应用程序的 exe 版本中而不是 python 版本中,因为理想情况下问题应该发生在 运行也作为 python 代码。