मुझे एक मालिकाना विरासत सेवा (डेबियन 10 पर चल रही) से निपटना पड़ रहा है जो विभिन्न (मोटे तौर पर) जानकारी और नोटिस स्तर की चीजों को स्टडआउट में लॉग करता है, और (मोटे तौर पर) चेतावनी और त्रुटि स्तर की चीजों को stderr में लॉग करता है। दोनों को --stdout <path>
और --stderr <path>
कमांड लाइन पैरामीटर का उपयोग करके फाइलों में लिखा जा सकता है। इस डेमॉन के लिए हमारी सिस्टमड यूनिट फाइल कुछ इस तरह दिखती है (जरूरी चीजों को काटकर):
[Unit]
Description=Some legacy proprietary thing
After=network.target
[Service]
ExecStart=/usr/local/bin/thing \
--stdout /var/log/thing/stdout.log \
--stderr /var/log/thing/stderr.log
[Install]
WantedBy=multi-user.target
समस्या यह है कि stdout.log और stderr.log को लिखी गई पंक्तियों में टाइमस्टैम्प नहीं है, जिसकी हमें अब आवश्यकता है। एप्लिकेशन हमारे लिए एक ब्लैक बॉक्स है, और टाइमस्टैम्प को शामिल करने के लिए इसके लॉगिंग आउटपुट को संशोधित करना संभव नहीं है।
अपने शोध में, मुझे दो विकल्प मिले हैं जो यहाँ काम कर सकते हैं। यदि आपके पास अन्य हैं, तो मैं उन्हें सुनने के लिए उत्सुक हूं।
विकल्प 1
Stdout और stderr दोनों के लिए mkfifo
के साथ नामित पाइप बनाएं, और लीगेसी एप्लिकेशन को --stdout
और --stderr
लक्ष्यों के रूप में उपयोग करें। फिर, उन पाइपों को पढ़ने के लिए एक प्रक्रिया सेट करें, प्रत्येक पंक्ति को ts
कमांड में पाइप करें, जो एक अच्छा टाइमस्टैम्प जोड़ता है, जैसे:
$ echo foo | ts '[%Y-%m-%d %H.%M.%.S]'
[2021-08-10 16.16.21.506571] foo
यह टाइमस्टैम्प वाली लाइनें हैं जो तब लॉग फाइलों के लिए लिखी जाएंगी, एक स्टडआउट के लिए और एक स्टैडर के लिए, शायद पाइपिंग के माध्यम से।
विकल्प 2
सिस्टमड यूनिट फ़ाइल में, हम StandardOutput
और StandardError
को syslog
पर सेट करने में सक्षम हो सकते हैं, और फिर SyslogIdentifier
को कुछ स्ट्रिंग पर सेट कर सकते हैं जिसका उपयोग हम rsyslog के साथ कर सकते हैं, एक जोड़कर टाइमस्टैम्प और अंतिम पंक्ति को लॉग फ़ाइल में लिखना।
दुर्भाग्य से, मुझे सिस्टमड को स्टडआउट और स्टैडर में अंतर करने का कोई तरीका नहीं मिला है: वे दोनों बिना किसी जानकारी के rsyslog पर भेजे जाएंगे, जिसके बारे में मूल था। (मुझे SyslogLevelPrefix
के बारे में पता है, लेकिन इसके लिए हमारे ब्लैक बॉक्स एप्लिकेशन से आने वाले लॉग संदेशों में sd-daemon(3)
शैली उपसर्ग शामिल होना चाहिए, और यह वर्तमान में संभव नहीं है।)
विवरण
विकल्प 2 में निहित समस्याओं के कारण, मैं विकल्प 1 पर आगे चर्चा करूँगा। यदि आप syslog दृष्टिकोण के समाधान के बारे में जानते हैं, तो फिर भी साझा करें।
तो, नामित पाइप महान हैं, लेकिन मुझे नहीं पता कि उन्हें सिस्टमड यूनिट फ़ाइल में कैसे कार्यान्वित किया जाए। मुझे लगता है कि मेरे पास दो अलग-अलग पाठक प्रक्रियाएं होंगी, एक स्टडआउट पाइप के लिए और एक स्टैडर पाइप के लिए, और इसलिए दो नई यूनिट फाइलें। कुछ और नोट्स:
- लेखक आवेदन शुरू होने से पहले नामित पाइप मौजूद होना चाहिए। मैं उन्हें पहले से
mkfifo
के साथ बना सकता हूं, इसलिए यह कोई समस्या नहीं होनी चाहिए। सिस्टमड के साथ पाइप के अस्तित्व को प्रबंधित करना आवश्यक नहीं होना चाहिए, जब तक कि यह यूनिट फ़ाइल को किसी भी तरह से सरल या अधिक मजबूत न बना दे। - पाठक प्रक्रियाएं जो टाइमस्टैम्प वृद्धि और लॉग फ़ाइल लेखन करती हैं, लेखक एप्लिकेशन शुरू होने से पहले ऊपर और चलनी चाहिए, जो कि यूनिट फाइलों में
Before/After
औरRequires/Wants
के लिए एक नौकरी है, मेरा मानना है। - पूरे उपकरण को लेखक अनुप्रयोग या पाठक प्रक्रियाओं के पुनरारंभ होने से बचना चाहिए। जैसे यदि
cat
का उपयोग पाठक प्रक्रिया में किया जाता है, लेखक छोड़ देता है औरcat
EOF देखता है और छोड़ देता है, तो पाठक प्रक्रिया वापस आ जानी चाहिए और लेखक प्रक्रिया के वापस आने पर तैयार रहना चाहिए। - संबंधित पाठक प्रक्रियाओं के डाउन होने पर एप्लिकेशन द्वारा नामित पाइपों को लिखी गई कोई भी लॉग पंक्तियाँ खो जाती हैं, लेकिन यह स्वीकार्य है।
लेखक प्रक्रिया में पैरामीटर --stdout /path/to/outfifo --stderr /path/to/errfifo
होने के कारण, पाठक प्रक्रियाएं, सिद्धांत रूप में, इस तरह सरल हो सकती हैं:
cat /path/to/outfifo | ts '[%Y-%m-%d %H.%M.%.S]' > /var/log/thing/stdout_ts.log
cat /path/to/errfifo | ts '[%Y-%m-%d %H.%M.%.S]' > /var/log/thing/stderr_ts.log
उसमें logrotate
नियम जोड़ें copytruncate
के साथ, और हम सुनहरे हैं! सिवाय इसके कि मैं यह नहीं जानता कि उपरोक्त पुनरारंभ करने योग्य आवश्यकताओं को पूरा करते हुए, सिस्टमड यूनिट फ़ाइल में यह कैसे करना है।
यदि आप यूनिट फ़ाइल निर्माण में मदद कर सकते हैं, या कोई वैकल्पिक तरीका सुझा सकते हैं, तो मैं आभारी रहूंगा।
1 उत्तर
journald
आपके लिए टाइमस्टैम्प आदि जोड़ सकता है।
एक आसान उपाय यह होगा कि systemd-cat
का इस्तेमाल किया जाए :
ExecStart=/bin/systemd-cat \
--priority=info \
--stderr-priority=warning \
--identifier=thing \
/usr/local/bin/thing
यदि आपका thing
प्राथमिकता स्तरों के लिए लकड़हारा उपसर्गों का उत्सर्जन करता है (उदाहरण के लिए warning
संदेशों के लिए लाइन <4>
से शुरू होती है) तो आप प्राथमिकताएं मैन्युअल रूप से सेट करने के बजाय --level-prefix
ध्वज का उपयोग कर सकते हैं .
कुछ अन्य विचारों में शामिल हैं:
- अपनी इकाई में स्ट्रीम लॉगिंग का उपयोग करना .
- लॉग में पढ़ने के लिए एक कस्टम स्प्लिटर लिखना और उन्हें सही स्तरों के साथ
systemd-cat
पर पाइप करना। आप इसे एक ऐसी सेवा के रूप में चलाएंगे जिससेthing
बात करेगा। - प्रकार: एक कस्टम पार्सर लिखें और पार्स किए गए लॉग को सीधे
sd_journal_send(3)
के माध्यम से जर्नल में भेजें। आपthing
के आउटपुट कोparser
तक पहुंचाने के लिए systemd का उपयोग करेंगे। - एक सॉकेट इकाई पर stdout और stderr लिखने के लिए systemd का उपयोग करें
StandardOutput=
औरStandardError=
के माध्यम से।
संबंधित सवाल
नए सवाल
logging
कंप्यूटर डेटा लॉगिंग एक कंप्यूटर प्रोग्राम या कंप्यूटर सिस्टम में रिकॉर्डिंग की प्रक्रिया है, आमतौर पर एक निश्चित दायरे के साथ, ऑडिट ट्रेल प्रदान करने के लिए जिसका उपयोग सिस्टम की गतिविधि को समझने और समस्याओं का निदान करने के लिए किया जा सकता है। इस टैग के अलावा उपयुक्त सॉफ़्टवेयर या हार्डवेयर टैग शामिल करना सुनिश्चित करें।
systemd-cat
के बारे में नहीं सुना। यहां बेहद उपयोगी लगता है। मेरी ओर से कुछ और काम करने की जरूरत है, लेकिन यहां अन्य विचारों के साथ काफी अच्छा है। स्वीकृत और इनाम से सम्मानित किया गया।