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


49

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

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


वे पहले से ही sloglog में जा रहे हैं। आप बस उन्हें वहां से उठा सकते हैं!
माइकल हैम्पटन

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

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

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

जवाबों:


107

एक अद्भुत नुस्खा नग्नेक्स डॉकरीफाइल में दिया गया है :

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

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


2
इस। है। बस। प्रतिभाशाली। और बहुमुखी।
बीते

11
इसके साथ एक समस्या यह है कि जब आप जिस चीज को चला रहे होते हैं, वह पृष्ठभूमि को एक गैर-रूट प्रक्रिया के रूप में देखने के लिए जोर देती है। मैं इस के साथ कर रहा हूँ squid3, और यह तो पर अनुमति के साथ परेशानी है /dev/stdout
mikepurvis

4
यह हमेशा काम नहीं करता है - उदाहरण के लिए यदि एप्लिकेशन फ़ाइल की तलाश करने का प्रयास करता है, तो यह विधि आम तौर पर काम नहीं करेगी।
मिक्सजा

लिंक नीचे है ...
बबकेन वर्दयान

4
सब कुछ जीत के लिए एक फ़ाइल है।
रबरडक

16

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

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

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

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

#! /usr/bin/env bash
set -eu

rm -rf /var/log/my-application.log
tail --pid $$ -F /var/log/my-application.log &

exec /path/to/my-application --logfile /var/log/my-application.log

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

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

FROM ubuntu
ADD run.sh /root/run.sh
CMD ['/root/run.sh']

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

#! /usr/bin/env bash
set -eu

LOGS=/var/log/myapp/

( umask 0 && truncate -s0 $LOGS/http.{access,error}.log )
tail --pid $$ -n0 -F $LOGS/* &

exec /usr/sbin/apache2 -DFOREGROUND

विशेष रूप से अपाचे सर्वर के लिए मैं पाइप्ड लॉग ( httpd.apache.org/docs/2.4/logs.html#piped ) का उपयोग कर रहा हूं और लगता है कि यह काम करता है।
php-

अल्पाइन के साथ इसी तरह के मुद्दों को हल करता है और tailबिना thepid विकल्प के बिजीबॉक्स पर ठीक काम करता है ।
रयान

मेरे लिए काम करने का तरीका। अत्यधिक उपयोगी, धन्यवाद।
तामस कलमन

8

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

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

यह आउटपुट को pid ​​1 के स्टडआउट पर भेजता है, जो कि एक docker पिकअप है।


1
यह सही जवाब है। लॉग PID1 के लिए stdout के लिए भेजा जाना चाहिए और यदि आपके आवेदन एक और पीआईडी के तहत चल रहा है, यह द्वारा नहीं देखा जाएगा docker logsया kubectl logs। मेरे पास एक कंटेनर है जो क्राउस्टैब के माध्यम से कार्य करता है जो PID1 के रूप में नहीं चल रहा है।
लेमन

6

nginx के लिए आप इस 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;'

जब मास्टर प्रक्रिया के रूप में नहीं चल रहा है काम नहीं करता हैroot
Peedee
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.