सवाल Stdout पर एक डॉकर एप्लिकेशन लिखें


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

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


40
2018-05-28 13:32


मूल


वे पहले से ही syslog जा रहे हैं। आप उन्हें वहां से उठा सकते हैं! - Michael Hampton♦
@ माइकल हैम्पटन, ठीक लगता है, लेकिन डॉकर एक ऐसी प्रक्रिया चलाता है जो स्टडआउट पर लिख सकता है, और यह उनमें से दो संयोजनों की तरह लगता है? - kolypto
आप एक डिमन प्रक्रिया syslog उपयोग कर सकते हैं और एक सामने की प्रक्रिया है जो प्रिंट करता है? - qkrijger
@qkrijger, अच्छा बिंदु! अब, अगर किसी के साथ इसका अनुभव है ...? - kolypto


जवाब:


एक अद्भुत नुस्खा दिया जाता है nginx Dockerfile:

# 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!


88
2017-10-07 21:57



इस। है। बस। प्रतिभाशाली। और बहुमुखी। - spacediver
एक बात यह है कि इसके साथ कोई समस्या है जब आप जो चीज चला रहे हैं वह पृष्ठभूमि में गैर-रूट प्रक्रिया के रूप में खुद को मजबूर करने पर जोर देती है। मैं इसके साथ कर रहा हूँ squid3, और उसके बाद अनुमतियों के साथ परेशानी है /dev/stdout। - mikepurvis
यह हमेशा काम नहीं करता है - उदाहरण के लिए यदि एप्लिकेशन फ़ाइल की तलाश करने का प्रयास करता है, तो यह विधि आम तौर पर काम नहीं करेगी। - mixja
लिंक नीचे है ... - Babken Vardanyan
सब कुछ जीत के लिए एक फाइल है। - RubberDuck


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

इस तरह, हम एप्लिकेशन को कॉन्फ़िगर करते हैं ताकि यह फ़ाइल पर लॉग ऑन हो और लगातार 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 हम फ़ाइल नाम सूचीबद्ध करते हैं, और अगर वे बाद में दिखाई देते हैं तो भी उन्हें पढ़ा जाएगा!

अंत में, minimalistic 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

14
2018-05-28 19:46



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


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;'

5
2017-08-01 17:40





एक डॉकर कंटेनर में पृष्ठभूमि प्रक्रिया के लिए, उदा। निष्पादन / bin / bash के साथ कनेक्ट करने के लिए मैं उपयोग करने में सक्षम था।

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

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


0
2017-09-27 06:16