Python 如何在Windows下共享日志文件?

Python 如何在Windows下共享日志文件?,python,windows,logging,batch-file,locking,Python,Windows,Logging,Batch File,Locking,我有几个不同的进程,我希望它们都记录到同一个文件。这些进程在Windows 7系统上运行。有些是python脚本,有些是cmd批处理文件 在Unix下,您只需让所有人以附加模式打开文件并进行写操作。只要每个进程在单个消息中写入的字节数少于PIPE\u BUF字节,就可以保证每个write调用不会与任何其他调用交错 有没有办法在Windows下实现这一点?简单的类Unix方法失败了,因为Windows不喜欢在默认情况下一次打开一个以上的文件进行写入。您可以尝试一下此Python模块: 它提供了一

我有几个不同的进程,我希望它们都记录到同一个文件。这些进程在Windows 7系统上运行。有些是python脚本,有些是
cmd
批处理文件

在Unix下,您只需让所有人以附加模式打开文件并进行写操作。只要每个进程在单个消息中写入的字节数少于
PIPE\u BUF
字节,就可以保证每个
write
调用不会与任何其他调用交错


有没有办法在Windows下实现这一点?简单的类Unix方法失败了,因为Windows不喜欢在默认情况下一次打开一个以上的文件进行写入。

您可以尝试一下此Python模块:

它提供了一个drop-in替换
RotatingFileHandler
,它允许多个进程同时记录到一个文件,而不会删除或关闭日志事件

我没有使用过它,但我在阅读Python中的一个相关bug()时发现了它

如果您实现了自己的代码而不是使用该模块,请确保您已经阅读了错误


您可以像在Bash中一样在Windows上使用。通过管道将批处理文件的输出传输到Python脚本,该脚本通过
ConcurrentLogHandler

进行日志记录。可以让多个批处理过程安全地写入单个日志文件。我对Python一无所知,但我认为这个答案中的概念可以与Python集成

Windows最多允许一个进程在任何时间点打开特定文件进行写访问。这可用于实现基于文件的锁定机制,以确保跨多个进程序列化事件。有关一些示例,请参见和

由于您所要做的只是写入日志,因此可以使用日志文件本身作为锁。日志操作封装在一个子例程中,该子例程尝试以追加模式打开日志文件。如果打开失败,例程将返回并重试。一旦打开成功,日志将被写入,然后关闭,例程将返回给调用者。例程执行传递给它的任何命令,例程中写入stdout的任何内容都会重定向到日志

下面是一个测试批处理脚本,它创建5个子进程,每个子进程向日志文件写入20次。写入操作是安全地交叉进行的

@echo off
setlocal
if "%~1" neq "" goto :test

:: Initialize
set log="myLog.log"
2>nul del %log%
2>nul del "test*.marker"
set procCount=5
set testCount=10

:: Launch %procCount% processes that write to the same log
for /l %%n in (1 1 %procCount%) do start "" /b "%~f0" %%n

:wait for child processes to finish
2>nul dir /b "test*.marker" | find /c "test" | >nul findstr /x "%procCount%" || goto :wait

:: Verify log results
for /l %%n in (1 1 %procCount%) do (
  <nul set /p "=Proc %%n log count = "
  find /c "Proc %%n: " <%log%
)

:: Cleanup
del "test*.marker"
exit /b

==============================================================================
:: code below is the process that writes to the log file

:test
set instance=%1
for /l %%n in (1 1 %testCount%) do (
  call :log echo Proc %instance% says hello!
  call :log dir "%~f0"
)
echo done >"test%1.marker"
exit

:log command args...
2>nul (
  >>%log% (
    echo ***********************************************************
    echo Proc %instance%: %date% %time%
    %*
    (call ) %= This odd syntax guarantees the inner block ends with success  =%
            %= We only want to loop back and try again if redirection failed =%
  )
) || goto :log
exit /b
您可以打开生成的“myLog.log”文件,查看写入操作是如何安全地交错的。但是输出太大,无法在这里发布

通过修改:log例程,使其不会在失败时重试,可以很容易地证明来自多个进程的同时写入可能会失败

:log command args...
>>%log% (
  echo ***********************************************************
  echo Proc %instance%: %date% %time%
  %*
)
exit /b
以下是“中断”日志例程后的一些示例结果

The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
Proc 1 log count = 12
Proc 2 log count = 16
Proc 3 log count = 13
Proc 4 log count = 18
Proc 5 log count = 14

这看起来很有用。我不知道如何处理批处理文件的日志记录。现在我只是让它写入一个不同的文件。@Omnifarious我想你应该可以用它来装配一些东西<代码>|在Windows上的工作方式与在Bash中的工作方式非常相似。该包当前在此处维护:。而且它工作得非常好!在windows上打开文件(使用CreateFile)时,您可以选择其他进程是否可以读取和/或写入同一文件,第二个进程必须指定兼容的共享标志…足够公平。我主要讲的是Windows批处理如何与重定向一起工作——我不知道有什么选项。多个进程可以读取,即使一个进程正在写入。(我不确定这是否总是安全的)。但决不能有超过一个进程打开进行写操作。@dbenham:非常感谢。它实际上解决了我的另一个大问题。它还可以解决我的日志记录问题。
>>文件(命令)
语法是否在任何地方记录在案?@Omnifarious它只是在附加模式下的标准重定向,应用于括号中的复合语句。下面是一些@dbenham:从1991年左右开始,我就没有认真处理过Windows或MS-DOS批处理文件。因此,任何类型的文档都是好的。:-)谢谢我完全知道在Linux系统中是如何做到这一点的。:-)
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
Proc 1 log count = 12
Proc 2 log count = 16
Proc 3 log count = 13
Proc 4 log count = 18
Proc 5 log count = 14