2012-02-18 10 views
6

मेरे पास कई अलग-अलग प्रक्रियाएं हैं और मैं उन्हें सभी को एक ही फ़ाइल में लॉग इन करना चाहता हूं। ये प्रक्रियाएं विंडोज 7 सिस्टम पर चल रही हैं। कुछ पाइथन स्क्रिप्ट हैं और अन्य cmd बैच फ़ाइलें हैं।आपने विंडोज के तहत लॉग फाइल कैसे साझा की हैं?

यूनिक्स के तहत आप बस सभी को एपेंड मोड में फ़ाइल खोलें और लिख लेंगे। जब तक प्रत्येक प्रक्रिया ने एक संदेश में PIPE_BUF बाइट्स से कम लिखा, तब तक प्रत्येक write कॉल किसी अन्य के साथ अंतःस्थापित नहीं होने की गारंटी दी जाएगी।

क्या यह विंडोज के तहत ऐसा करने का कोई तरीका है? बेवकूफ यूनिक्स-जैसे दृष्टिकोण विफल रहता है क्योंकि विंडोज़ एक से अधिक प्रक्रियाओं को पसंद नहीं करता है, जिसमें फ़ाइल को डिफ़ॉल्ट रूप से एक समय में लिखने के लिए खुली होती है। http://pypi.python.org/pypi/ConcurrentLogHandler

यह एक ड्रॉप-में प्रतिस्थापन RotatingFileHandler जो कई प्रक्रियाओं समवर्ती छोड़ने या लॉग ईवेंट clobbering के बिना एक एकल फाइल करने के लिए लॉग इन करने की अनुमति देता है प्रदान करता है:

उत्तर

9

एकाधिक बैच प्रक्रियाएं एक लॉग फ़ाइल को सुरक्षित रूप से लिखना संभव है। मुझे पायथन के बारे में कुछ नहीं पता, लेकिन मुझे लगता है कि इस जवाब में अवधारणाओं को पायथन के साथ एकीकृत किया जा सकता है।

विंडोज़ किसी एक समय पर किसी भी समय लेखन पहुंच के लिए एक विशिष्ट फ़ाइल खोलने की अनुमति देता है। इसका उपयोग फ़ाइल आधारित लॉक तंत्र को लागू करने के लिए किया जा सकता है जो गारंटी देता है कि कई प्रक्रियाओं में घटनाओं को क्रमबद्ध किया जाता है। कुछ उदाहरणों के लिए https://stackoverflow.com/a/9048097/1012053 और http://www.dostips.com/forum/viewtopic.php?p=12454 देखें।

के बाद से तुम सब करने की कोशिश कर रहे हैं एक लॉग में लिखने है, तो आप लॉग फ़ाइल में ही उपयोग कर सकते हैं ताला के रूप में। लॉग ऑपरेशन एक subroutine में encapsulated है जो लॉग फ़ाइल को संलग्न मोड में खोलने का प्रयास करता है। यदि खुला विफल रहता है, तो नियमित रूप से वापस आ जाता है और फिर कोशिश करता है। एक बार खुले सफल होने के बाद लॉग लिखा जाता है और फिर बंद हो जाता है, और दिनचर्या कॉलर को वापस आती है। दिनचर्या जो कुछ भी आदेश पास करता है उसे निष्पादित करता है, और नियमित रूप से stdout के लिए लिखी गई कुछ भी लॉग पर रीडायरेक्ट की जाती है।

यहाँ एक परीक्षण बैच स्क्रिप्ट है कि 5 बच्चे प्रक्रियाओं है कि प्रत्येक लॉग फ़ाइल को लिखने 20 बार बनाता है। लिखने सुरक्षित रूप से interleaved हैं।

@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 

आप देखना चाहते हैं कि राईट सुरक्षित रूप से interleaved किया गया है जिसके परिणामस्वरूप "myLog.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 
+0

जब आप विंडोज़ (CreateFile के साथ) पर एक फ़ाइल खोलते हैं तो आप यह चुनने के लिए चुनते हैं कि अन्य प्रक्रियाएं उसी फ़ाइल को पढ़ और/या लिख ​​सकती हैं, दूसरी प्रक्रिया को संगत शेयर झंडे निर्दिष्ट करना है ... – Anders

+0

पर्याप्त मेला। मैं ज्यादातर विंडोज बैच रीडायरेक्शन के साथ कैसे काम करता था - कोई विकल्प नहीं है जिसके बारे में मुझे पता है। एक प्रक्रिया लिखने के दौरान भी कई प्रक्रियाएं पढ़ सकती हैं। (मुझे यकीन नहीं है कि यह हमेशा सुरक्षित है)। लेकिन लिखने के लिए एक प्रक्रिया फिर कभी नहीं खुलती है। – dbenham

+0

@ डेबेनहम: इसके लिए आपको बहुत बहुत धन्यवाद। यह वास्तव में मेरे पास एक और बड़ी समस्या हल करता है। यह मेरी लॉगिंग समस्या को भी हल कर सकता है। क्या '>> फाइल (कमांड)' सिंटैक्स कहीं भी दस्तावेज है? – Omnifarious

2

आप इस पायथन मॉड्यूल एक कोशिश दे सकते हैं।

मैं इसे इस्तेमाल नहीं किया है, लेकिन मैं इसके बारे में अजगर में एक संबंधित बग (Issue 4749) पर पढ़ते समय पता चला।

आपको लगता है कि मॉड्यूल उपयोग करने के बजाय यह करने के लिए अपने खुद के कोड लागू करते हैं तो सुनिश्चित करें कि आप बग को पढ़ने बनाते हैं!

आप Windows पर output redirection का उपयोग जैसे आप बैश में कर सकते हैं। बैच फ़ाइलों के आउटपुट को पाइथन स्क्रिप्ट पर पाइप करें जो ConcurrentLogHandler के माध्यम से लॉग करता है।

+0

:

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

यहाँ "तोड़ने" के बाद कुछ नमूना परिणाम हैं। मुझे यकीन नहीं है कि बैच फ़ाइल लॉगिंग को कैसे संभालना है। अभी मैं इसे एक अलग फ़ाइल में लिखता हूं। – Omnifarious

+0

@ ओमनिफरीस मुझे लगता है कि आप [आउटपुट रीडायरेक्शन] (http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr का उपयोग करके कुछ अपनाने में सक्षम होना चाहिए। = सच)। '|' विंडोज़ पर काम करता है जैसे बैश में करता है। –