2009-12-30 11 views
6

के माध्यम से जेएनआई सी stderr/stdout भेजें मेरा जावा ऐप सी में लिखी गई लाइब्रेरी को आमंत्रित करने के लिए जेएनआई का उपयोग करता है। यह मूल पुस्तकालय stderr में त्रुटियों को लॉग करता है लेकिन मैं किसी भी तरह से लॉग 4j लॉगर के माध्यम से त्रुटि स्ट्रीम को रीडायरेक्ट करना चाहता हूं। क्या यह संभव है?लॉग 4j

सी पुस्तकालय बाहरी है - मेरे पास स्रोत नहीं है, इसलिए इसे बदल नहीं सकता है।

धन्यवाद

+0

क्या आपके आवेदन का जेएनआई परत हिस्सा या बाहरी टूलकिट का हिस्सा है? – PSpeed

+0

यह बाहरी टूलकिट का हिस्सा भी है। – dogbane

+0

क्या आप ग्रैन्युलरिटी के साथ बाहरी कोड कहते हैं और कितना डेटा आगे और आगे पारित किया जाता है? दूसरे शब्दों में, क्या आप काम को बाल प्रक्रिया के रूप में उभारा सकते हैं? सी कोड के stdout या stderr को पुनर्निर्देशित करना जिसे आप नियंत्रित नहीं करते हैं, बहुत मुश्किल है। मैंने सोचा कि मैंने इसे पहले किया होगा लेकिन कम से कम 10 साल हो चुके हैं क्योंकि मैंने उस तरह का सी कोड लिखा था और जो कुछ मैं ऑनलाइन खोज सकता हूं वह इसे फाइल पर रीडायरेक्ट करने के बारे में है। – PSpeed

उत्तर

3

नोट:: यह सी के भीतर से stdout में hooking के साथ मदद कर सकता है मैं इस सवाल का जवाब प्रयास नहीं किया है; YMMV।

POSIX विधि freopen स्ट्रीम से जुड़े अंतर्निहित फ़ाइल को बदल देगा। चूंकि मैनपेज कहता है: "फ्रीपेन() फ़ंक्शन का प्राथमिक उपयोग मानक टेक्स्ट स्ट्रीम (stderr, stdin, या stdout) से जुड़ी फ़ाइल को बदलना है"।

तो, आप अपनी खुद की जेएनआई लाइब्रेरी बना सकते हैं जो स्ट्रीम को केवल फाइल में रीडायरेक्ट करता है।

  1. आप सुनिश्चित करें कि आपके जावा कार्यक्रम में ही मानक धाराओं का उपयोग नहीं करता की आवश्यकता होगी, क्योंकि वे जा भी पुनः निर्देशित करेंगे: हालांकि, इस काम बनाने के लिए कई गंभीर बाधाओं रहे हैं। के लिए एक वर्कअराउंड यह आपके प्रोग्राम शुरू होने पर System.out एट अल को बदलने के लिए है।
  2. ऐसा नहीं है कि तृतीय-पक्ष लाइब्रेरी मानक पाठ धाराओं नजरअंदाज संभव है, और अंतर्निहित फ़ाइल वर्णनकर्ता के लिए सीधे लिखते हैं। यह असंभव लेकिन संभव है। मैं नहीं कर सकता कि क्या फ्रीपेन() बस द्वारा बफर किए गए फ़ाइल डिस्क्रिप्टर को संशोधित करता है, या वास्तव में अंतर्निहित fd को फिर से खोलता है।
  3. आप को अभी भी को लॉगर में "फ़ाइल" में जोड़ने की समस्या होगी।

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

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

या कॉन्फ़िगर करने योग्य लॉगिंग जोड़ने के लिए लाइब्रेरी लिखने वाले लोगों से बात करें।

-1

मेरे सी कुछ पुरानी है, लेकिन जब से तुम JNI के माध्यम से एक सी के भीतर से PrinStream तरीकों आह्वान कर सकते हैं यह संभव हो सकता है। लेकिन स्ट्रीम को लिखे जाने पर आपको हुक करने का एक तरीका खोजना होगा।

अद्यतन:

http://www.gnu.org/software/hello/manual/libc/Hook-Functions.html

+0

धन्यवाद, लेकिन दुर्भाग्य से मैं सी लाइब्रेरी को नहीं बदल सकता क्योंकि यह मेरा नहीं है। – dogbane

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