2009-12-09 16 views
7

मैं एकाधिक धागे से लॉगिंग के लिए एक साधारण वर्ग को कार्यान्वित करना चाहता हूं। विचार यह है कि, प्रत्येक ऑब्जेक्ट जो सामान लॉग करना चाहता है, एक ओस्ट्रीम-ऑब्जेक्ट प्राप्त करता है कि यह सामान्य ऑपरेटरों का उपयोग करने के लिए संदेश लिख सकता है। वांछित व्यवहार यह है कि स्ट्रीम फ़्लश होने पर संदेशों को लॉग में जोड़ा जाता है। इस तरह, संदेशों को अन्य धागे से संदेशों द्वारा बाधित नहीं किया जाएगा। मैं संदेश को संग्रहीत करने के लिए एक अस्थायी स्ट्रिंगस्ट्रीम का उपयोग करना टालना चाहता हूं, क्योंकि इससे कम से कम twoliners अधिक संदेश होंगे। जैसा कि मैंने इसे देखा, इसे प्राप्त करने का मानक तरीका मेरे स्वयं के स्ट्रीमबफर को लागू करना होगा, लेकिन यह बहुत बोझिल और त्रुटि-प्रवण प्रतीत होता है। क्या ऐसा करने का कोई आसान तरीका है? यदि नहीं, तो क्या आप कस्टम स्ट्रीमबफ पर एक अच्छा लेख/कैसे/गाइड जानते हैं?थ्रेडसेफ लॉगिंग

अग्रिम धन्यवाद,

Space_C0wbo0y

अद्यतन:

चूंकि यह काम करने के लिए मैं अपने खुद के जवाब जोड़ा लगता है।

+0

एक अच्छा समाधान की तरह लगता है! शायद इसे अपने उत्तर के रूप में जोड़ें? –

उत्तर

1

तो, मैं Boost.IOstreams पर एक नज़र लिया और यहाँ है कि मैं क्या लेकर आए हैं:

class TestSink : public boost::iostreams::sink { 
public: 
    std::streamsize write(const char * s, std::streamsize n) { 
     std::string message(s, n); 
      /* This would add a message to the log instead of cout. 
       The log implementation is threadsafe. */ 
     std::cout << message << std::endl; 
     return n; 
    } 
}; 

TestSink एक धारा-बफर (stream_buffer-template देखें) बनाने के लिए इस्तेमाल किया जा सकता है। प्रत्येक थ्रेड को TestSink का अपना उदाहरण प्राप्त होगा, लेकिन सभी TestSinks उसी लॉग पर लिखेंगे। TestSink इस प्रकार प्रयोग किया जाता है:

TestSink sink; 
boost::iostreams::stream_buffer<TestSink> testbuf(sink, 50000); 
std::ostream out(&testbuf); 

for (int i = 0; i < 10000; i++) 
    out << "test" << i; 

out << std::endl; 

महत्वपूर्ण तथ्य यह है यहाँ, है कि TestSink.write केवल जब stream_buffer उदाहरण के आंतरिक बफर भरा हुआ है (डिफ़ॉल्ट बफर जब धारा प्लावित है (std::endl या std::flush) कहा जाता है, या आकार 40000 वर्ण नहीं रख सकता है, इसलिए मैं इसे 50000 में निष्क्रिय करता हूं)। इस कार्यक्रम में, TestSink.write बिल्कुल एक बार कहा जाता है (आउटपुट यहां पोस्ट करने में बहुत लंबा है)। इस तरह मैं किसी भी अस्थायी चर के बिना सामान्य स्वरूपित स्ट्रीम-आईओ का उपयोग करके लॉगमेसेज लिख सकता हूं और सुनिश्चित कर सकता हूं कि जब मैं धारा को फ्लश करता हूं तो संदेश को एक टुकड़े में लॉग पर पोस्ट किया जाता है।

यदि मैं अलग-अलग सुझाव/समस्याएं नहीं मानता हूं तो मैं एक और दिन खुला प्रश्न छोड़ दूंगा।

5

log4cpp पर एक नज़र डालें; उनके पास बहु-थ्रेड समर्थन है। यह आपका समय बचा सकता है।

+0

आपके उत्तर के लिए धन्यवाद। हालांकि, मेरे कामकाजी माहौल के प्रतिबंध के कारण मैं एक नई पुस्तकालय पेश नहीं कर सकता। इसके अलावा, मेरे मौजूदा उद्देश्यों के लिए अधिकांश मौजूदा लॉगिंग लाइब्रेरी बहुत भारी हैं। –

+0

यदि अधिक उदार लाइसेंस की तलाश है, तो Apache द्वारा Log4cxx देखें। http://logging.apache.org/log4cxx/index.html –

0

पुन:। आपकी अपनी प्रतिक्रिया यदि आप त्रुटि लॉगिंग के लिए इसका उपयोग कर रहे हैं और आप अपनी स्ट्रीम को फ्लश करने से पहले प्रोग्राम क्रैश करते हैं तो आप लॉगिंग थोड़ा बेकार है, है ना?

+1

मुझे लगता है कि किसी भी लॉगिंग दृष्टिकोण के साथ एक समस्या होगी। –

+0

ईटीडब्लू जैसे लॉगिंग सिस्टम को छोड़कर, जिसमें बाहरी सहायता है। – VoidStar

1

आपको लगता है कि log4cpp बहुत भारी है और आप इसके बजाय Boost.IOStreams तक पहुंचते हैं? है ना?

आप logog पर विचार करना चाहेंगे। यह पॉज़िक्स, विन 32 और विन 64 के लिए थ्रेड-सुरक्षित है।

+0

यदि बूस्ट पहले से ही पुस्तकालयों के सेट में है, तो यह भारी वजन नहीं है।अन्यथा, पूरी तरह से आपसे सहमत हैं। – John

संबंधित मुद्दे