2012-02-18 14 views
6

私はいくつかの異なるプロセスを持っており、すべて同じファイルにログするようにしたいと思います。これらのプロセスはWindows 7システム上で実行されています。いくつかはPythonスクリプトであり、その他はcmdバッチファイルです。Windowsではどのようにログファイルを共有していますか?

Unixでは、誰もがファイルを追加モードで開いて書き留めておきます。各プロセスが1つのメッセージでPIPE_BUFバイト未満を書いている限り、各writeコールは他のメッセージとインターリーブしないことが保証されます。

Windowsでこれを行う方法はありますか? Unixライクなアプローチは失敗します。なぜならWindowsは、デフォルトで一度に書き込み用にファイルを開いているプロセスが複数あるのが好きではないからです。これは、ドロップイン置換複数のプロセスが同時に落下やログイベントをつかうことなく、単一のファイルにログを記録することができますRotatingFileHandlerを提供 http://pypi.python.org/pypi/ConcurrentLogHandler

答えて

9

複数のバッチプロセスで1つのログファイルに安全に書き込むことができます。私はPythonについて何も知らないが、私はこの答えの概念がPythonと統合できると想像している。

Windowsでは、最大で1つのプロセスで、任意の時点で特定のファイルを書き込みアクセス用に開くことができます。これは、イベントが複数のプロセスにわたって直列化されることを保証するファイルベースのロックメカニズムを実装するために使用できます。いくつかの例については、https://stackoverflow.com/a/9048097/1012053およびhttp://www.dostips.com/forum/viewtopic.php?p=12454を参照してください。

ログに書き込むだけで、ログファイル自体をロックとして使用できます。ログ操作は、追加モードでログファイルを開こうとするサブルーチンにカプセル化されます。オープンに失敗した場合、ルーチンはループバックして再試行します。オープンに成功すると、ログが書き込まれて閉じられ、ルーチンは呼び出し元に戻ります。ルーチンはそれに渡されるコマンドを実行し、ルーチン内のstdoutに書き込まれたものはログにリダイレクトされます。

ここには、それぞれがログファイルに20回書き込む5つの子プロセスを作成するテストバッチスクリプトがあります。書き込みは安全にインターリーブされます。ここで

@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 

いくつかのサンプルの結果は「破壊」した後、次のとおりです。便利に見えるそのルーチン

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 
+0

WindowsでCreateFileを使ってファイルを開くと、他のプロセスが同じファイルを読み書きできるかどうかを選択できます.2番目のプロセスは互換性のある共有フラグを指定する必要があります。 – Anders

+0

十分に公正です。私は主に、Windowsのバッチがリダイレクトでどのように動作するのかを話していました。私が知っているオプションはありません。 1つのプロセスが書き込みを行っている間でも、複数のプロセスが読み取ることができます。 (私はそれがいつも安全かどうか分からない)。しかし、決してそれ以上のプロセスを書くことはできません。 – dbenham

+0

@dbenham:ありがとうございます。それは実際に私が持っている別の大きな問題を解決します。私のロギングの問題を解決するかもしれません。 '' file(commands) 'の構文は文書化されていますか? – Omnifarious

2

あなたはこのPythonモジュールを試してみることができます。

私はそれを使っていませんが、Pythonの関連するバグ(Issue 4749)を読んでいるうちに見つけました。

このモジュールを使用する代わりに独自のコードを実装している場合は、バグを読んでください。

Windowsでoutput redirectionを使用することは、Bashの場合と同様です。バッチファイルの出力を、ConcurrentLogHandlerをログに記録するPythonスクリプトにパイプします。

+0

を記録。私はどのようにバッチファイルがログを処理するか分からない。今は別のファイルに書き込むだけです。 – Omnifarious

+0

@Omnifarious [出力リダイレクト]を使用して何かをリグにすることができるはずです(http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr =真)。 '|'はBashと同様にWindows上で動作します。 –

関連する問題