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

标签 python windows logging batch-file locking

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

在 Unix 下,您只需让每个人以追加模式打开文件并写入即可。只要每个进程在单个消息中写入少于 PIPE_BUF 字节,每个 write 调用将保证不会与任何其他调用交错。

有没有办法在 Windows 下实现这一点?朴素的类 Unix 方法失败了,因为默认情况下,Windows 不喜欢多个进程同时打开一个文件进行写入。

最佳答案

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

Windows 最多允许一个进程在任何时间点打开特定文件进行写访问。这可用于实现基于文件的锁定机制,以保证事件在多个进程中序列化。参见 https://stackoverflow.com/a/9048097/1012053http://www.dostips.com/forum/viewtopic.php?p=12454举一些例子。

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

这是一个测试批处理脚本,它创建了 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

这是证明每个进程的所有 20 次写入都成功的输出

Proc 1 log count = 20
Proc 2 log count = 20
Proc 3 log count = 20
Proc 4 log count = 20
Proc 5 log count = 20

您可以打开生成的“myLog.log”文件以查看写入是如何安全交错的。但是输出太大,无法张贴在这里。

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

:log command args...
>>%log% (
  echo ***********************************************************
  echo Proc %instance%: %date% %time%
  %*
)
exit /b

以下是“打破”:log 例程后的一些示例结果

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

关于python - 在 Windows 下如何共享日志文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9337415/

相关文章:

python - 按对象从 QuerySet 中获取下一个和上一个对象

Python 3 : What am I doing wrong here?

c - 如何在Windows中使用系统调用从C打开图像?

java - 在tomcat日志消息中,是否可以在日志消息中添加文件名

Python APScheduler 如何禁用日志记录

python - 如何使用 Swift 从 iOS 运行 .py 文件

php xsl 扩展缺少 magento 就绪检查

windows - 适用于Windows的Github-可以使用git shell推/pull -Github GUI给出错误

java - RollingFileAppender 如何与 log4j2 一起工作?

c# - 为每个单独的线程记录到单独的日志文件