एक डॉकर एप्लिकेशन को स्टडआउट पर लिखें

मैं अनुपालन में एक 3-पार्टी एप्लिकेशन तैनात कर रहा हूं 12 कारक सलाहकार, और बिंदुओं में से एक बताता है कि एप्लिकेशन लॉग को स्टडआउट/स्टैडर पर मुद्रित किया जाना चाहिए: फिर क्लस्टरिंग सॉफ्टवेयर इसे एकत्र कर सकता है ।

हालांकि, एप्लिकेशन केवल फाइलों या सिसलॉग को लिख सकता है । मैं इसके बजाय इन लॉग को कैसे प्रिंट करूं?

में एक अद्भुत नुस्खा दिया गया है nginx Dockerfile:

# forward request and error logs to docker log collectorRUN ln -sf /dev/stdout /var/log/nginx/access.log \    && ln -sf /dev/stderr /var/log/nginx/error.log

बस, ऐप इसे एक फ़ाइल के रूप में लिखना जारी रख सकता है, लेकिन परिणामस्वरूप लाइनें यहां जाएंगी stdout & stderr!

एक डॉकर कंटेनर में पृष्ठभूमि प्रक्रिया के लिए, उदाहरण के लिए निष्पादन से /बिन/बैश से जुड़ना मैं उपयोग करने में सक्षम था ।

echo "test log1" >> /proc/1/fd/1

यह आउटपुट को पीआईडी 1 के स्टडआउट में भेजता है, जो कि एक डॉकर पिकअप है ।

एक अन्य प्रश्न में, माता-पिता के बाहर निकलने पर बच्चे की प्रक्रिया को मार डालो, मुझे प्रतिक्रिया मिली जिसने इसे सुलझाने में मदद की ।

इस तरह, हम एप्लिकेशन को कॉन्फ़िगर करते हैं ताकि यह एक फ़ाइल में लॉग हो, और लगातार tail -f यह. सौभाग्य से, tail स्वीकार कर सकते हैं --pid PID: निर्दिष्ट प्रक्रिया से बाहर निकलने पर यह बाहर निकल जाएगा । हम डाल दिया $$ वहां: वर्तमान खोल का पीआईडी।

अंतिम चरण के रूप में, लॉन्च किया गया एप्लिकेशन है exec'ईडी, जिसका अर्थ है कि वर्तमान शेल पूरी तरह से उस एप्लिकेशन से बदल गया है ।

धावक स्क्रिप्ट, run.sh, इस तरह दिखेगा:

#! /usr/bin/env bashset -eurm -rf /var/log/my-application.logtail --pid $$ -F /var/log/my-application.log &exec /path/to/my-application --logfile /var/log/my-application.log

नोट: का उपयोग करके tail -F हम फ़ाइल नामों को सूचीबद्ध करते हैं, और यह उन्हें बाद में दिखाई देने पर भी पढ़ेगा!

अंत में, न्यूनतर Dockerfile:

FROM ubuntuADD run.sh /root/run.shCMD ['/root/run.sh']

नोट: कुछ बेहद अजीब काम करने के लिए tail -f व्यवहार (जो कहता है "को दूरस्थ फ़ाइल से बदल दिया गया है । इस नाम को देते हुए") मैंने एक और दृष्टिकोण की कोशिश की: सभी ज्ञात लॉग फाइलें बनाई गई हैं और स्टार्ट अप पर काट दी गई हैं: इस तरह मैं सुनिश्चित करता हूं कि वे मौजूद हैं, और उसके बाद ही-उन्हें पूंछ दें:

#! /usr/bin/env bashset -euLOGS=/var/log/myapp/( umask 0 && truncate -s0 $LOGS/http.{access,error}.log )tail --pid $$ -n0 -F $LOGS/* &exec /usr/sbin/apache2 -DFOREGROUND

नग्नेक्स के लिए आपके पास हो सकता है nginx.conf की ओर इशारा करते हुए /dev/stderr और /dev/stdout इस तरह

user  nginx;worker_processes  4;error_log  /dev/stderr;http {    access_log  /dev/stdout  main;...

और अपने Dockerfile प्रवेश होना चाहिए

/usr/sbin/nginx -g 'daemon off;'

मेरे मामले में स्टडआउट के लिए एक प्रतीकात्मक लिंक बनाने से काम नहीं चला, इसलिए इसके बजाय मैं निम्नलिखित कमांड चलाता हूं

ln -sf /proc/self/fd/1 /var/log/main.log 

मुझे अपाचे 2 के साथ इस समस्या को हल करना पड़ा है, और कस्टमलॉग का उपयोग करके पुनः निर्देशित करने का प्रयास करने के लिए कुश्ती की है /proc/1/fd/1 लेकिन वह काम नहीं कर सका। मेरे कार्यान्वयन में, अपाचे के रूप में नहीं चल रहा था pid 1, इसलिए kolypto के जवाब जैसा है वैसा काम नहीं किया । पीटर का दृष्टिकोण सम्मोहक लग रहा था, इसलिए मैंने दोनों को मिला दिया और परिणाम आश्चर्यजनक रूप से काम करता है:

# Redirect apache log output to docker log collectorRUN ln -sf /proc/1/fd/1 /var/log/apache2/access.log \    && ln -sf /proc/1/fd/2 /var/log/apache2/error.log

तकनीकी रूप से यह अपाचे रखता है access.log और error.log जा रहे हैं stdout और stderr जहां तक डॉकर लॉग कलेक्टर का संबंध है, लेकिन यह बहुत अच्छा होगा यदि दोनों को अलग करने का कोई तरीका हो बाहर कंटेनर, के लिए एक स्विच की तरह docker logs यह केवल एक या दूसरे को दिखाएगा।..

आप एक डेमॉन प्रक्रिया का उपयोग कर सकते हैं और एक फ्रंट प्रक्रिया है जो प्रिंट करता है?

वे पहले से ही सिसलॉग जा रहे हैं । आप बस उन्हें वहां से उठा सकते हैं!

माइकलहैम्प्टन, ठीक लगता है, लेकिन डॉकर एक एकल प्रक्रिया चलाता है जो स्टडआउट को लिख सकता है, और यह उनमें से दो के संयोजन की तरह लगता है?

@qkrijger, अच्छी बात है! अब, अगर किसी को इसके साथ अनुभव है । … ?