भारी उत्पादन के साथ लॉग फ़ाइल पार्स


1

मैं अपने vsftpd लॉग की निगरानी करना चाहता हूं और अपलोड की गई फ़ाइलों को संसाधित करने के लिए लॉग से जानकारी खींच सकता हूं। अब तक सब कुछ बहुत अच्छा था और ठीक काम किया:

tail -n0 -F /var/log/vsftpd.log | while read line; do
    if echo "$line" | grep -q 'OK UPLOAD:'; then
        #do a bunch of processing stuff - this takes some time
    fi
done

मैंने कुछ पैमाने पर परीक्षण करना शुरू किया और एक साथ 500 फाइलें अपलोड कीं। किसी कारण से लॉग लाइनें गायब हैं या जब आप इतनी सारी चीजें अपलोड करते हैं तो वे कट जाते हैं। उदाहरण के लिए एक विशिष्ट रेखा इस तरह दिखती है:

Sun Apr 7 09:08:51 2013 [pid 25409] [cam02430] OK UPLOAD: Client "206.132.183.201", "/20130407/09/20130407_090842D.avi", 531792 bytes, 426.14Kbyte/sec

लेकिन कभी-कभी लाइन इस तरह दिखती है (यदि पूरी तरह से गायब नहीं है):

:08:51 2013 [pid 25409] [cam02430] OK UPLOAD: Client "206.132.183.201", "/20130407/09/20130407_090842D.avi", 531792 bytes, 426.14Kbyte/sec

यह लॉग के पहले कुछ अक्षरों को काट रहा है। यह हर लाइन के लिए नहीं है, लेकिन सबसे ज्यादा है। साथ ही कई लाइनें अभी गायब हैं। मुझे लगता है कि मैं अपने प्रसंस्करण की एक दौड़ हालत है समय में खत्म नहीं। मैं इसके आसपास कैसे पहुंच सकता हूं?

संपादित करें मुझे लगता है कि मेरे पास 3 विकल्प हैं:

  1. पूंछ का उपयोग न करें और एक नई प्रविष्टि के लिए लॉग की जांच करने के लिए क्रोन जॉब / grep जैसी चीजों के संयोजन का उपयोग करने का प्रयास करें। मुझे लगता है कि यह मुश्किल हो सकता है। मैं कैसे बताऊं कि उस लॉग में नया क्या है?

  2. मॉनेट या समकक्ष के साथ फ़ाइल परिवर्तन की निगरानी करें। मेरा मानना ​​है कि यह एक विकल्प नहीं है। फ़ाइलें कुछ नामांकित फ़ाइलों के साथ कुछ यादृच्छिक निर्देशिकाओं में संग्रहित हो जाती हैं, जिन पर समय की मुहर लगती है।

  3. लॉगस्टैश या समकक्ष। मुझे नहीं लगता कि ये कार्यक्रम मेरी आवश्यकताओं के अनुरूप हैं। लेकिन शायद किसी और को जानता हो।

अभी मैं # 1 पर ध्यान दे रहा हूं जिसमें कोई अच्छा लीड नहीं है। तो इस पर किसी भी विचार की सराहना की जाएगी।


मुझे vsftpd के लॉगिंग व्यवहार के बारे में कुछ भी नहीं पता है, लेकिन आप (यदि कोई नया उपनिर्देशिका डायरेक्ट्री ट्री के भीतर नियमित आधार पर नहीं मिलता है जिसे आप ftp प्रक्रिया का उपयोग करके पॉपुलेट करते हैं) inotifywait का उपयोग for-loop के साथ करने के लिए करते हैं पूर्ण की गई फ़ाइलें (अच्छी तरह से लिखें / लिखी गई घटनाएँ ।_
tink

गहन लॉग प्रोसेसिंग को शेल स्क्रिप्ट का उपयोग नहीं किया जाना चाहिए, मैं JSON लॉग प्रारूप + लॉगस्टैश / इलास्टिसर्च / किबाना / स्टेटसड / ग्रेफाइट के लिए
जाऊंगा

@ इस पर मैंने विचार किया कि जब मैंने इस परियोजना को शुरू किया था, लेकिन यह स्पष्ट नहीं था कि यह कितनी अच्छी तरह से करीबी घटनाओं (सफल अपलोड) को संभाल लेगी और फाइलें नए उपनिर्देशिकाओं में संग्रहीत हो जाती हैं जो हमेशा तिथि के अनुसार बदलती रहती हैं। वह हिस्सा मेरे नियंत्रण से बाहर है।
टॉम

@Tom जब चरित्र कट जाता है, तो क्या आप यह सत्यापित कर सकते हैं कि यह केवल उस विशेष पंक्ति के वर्णों को काटता है या आप वास्तव में बीच में कई पंक्तियों को याद कर रहे हैं।
जॉन सिउ

@ जॉनसनू दरअसल यह लाइनों के रूप में अच्छी तरह से याद आ रही है।
टॉम

जवाबों:


1

आप इस तरह से अपने कोड को फिर से लिखकर लॉग में हर लाइन के लिए "grep" प्रक्रिया को रोकने के लिए शुरू कर सकते हैं :

tail -n0 -F /var/log/vsftpd.log | grep 'OK UPLOAD:' | while read line ; do
        #do a bunch of processing stuff - this takes some time
done

लेकिन मैं अन्य पोस्टरों से सहमत हूं, शेल वास्तव में भारी पाठ / स्ट्रिंग हेरफेर के लिए उपयुक्त नहीं है। आपको दूसरे स्क्रिप्टिंग इंजन का उपयोग करने पर विचार करना चाहिए (कम से कम awk, या बेहतर पर्ल या अजगर)


धन्यवाद, यह आशाजनक लग रहा था लेकिन वही समस्या ग्रस्त है। मैं अन्य विकल्प तलाश रहा हूं।
टॉम

1

मुझे फ़ाइल ओपन '<' विकल्पों का उपयोग करके पर्ल के साथ अच्छा अनुभव था, यदि आप केवल शेल स्क्रिप्ट्स के लिए अपनी सीमा को आराम करने के लिए तैयार हैं।

उदा। https://stackoverflow.com/questions/1425223/how-do-i-read-a-file-which-is-constantly-updating


1

जैसा कि @epoon ने सुझाव दिया , पर्ल एक अच्छा विकल्प हो सकता है:

#!/usr/bin/env perl

open(FH,'<',$ARGV[0]) || die("Could not open file $ARGV[0]\n");
for (;;) {
    while (<FH>) {
    if (/OK UPLOAD/) { ## this is where you do your processing. As an example, 
                       ## I am collecting the file's info
        /^(.+?)\s*\[pid\s*(\d+).+?\"([\d\.]+).+?\"(.+?)\".+?(\d+).+?\s([^\s]+)/;
        my ($date,$pid,$client,$filename,$size,$rate) = ($1,$2,$3,$4,$5,$6);
        print "On $date, process $pid uploaded file \"$filename\" of $size bytes from $client at $rate\n"

    }
    }
    # eof reached on FH, but wait a second and maybe there will be more output
    sleep 1;
    seek FH, 0, 1;      # this clears the eof flag on FH
}

इस स्क्रिप्ट को चलाने पर /var/log/vsftpd.logआउटपुट देना चाहिए

On Sat Apr 20 16:30:05 CEST 2013, process 25409 uploaded file "/20130407/09/20130407_090842D.avi" of 531792 bytes from 206.132.183.201 at 426.14Kbyte/sec

मुझे यह अपडेट करने में खुशी होगी यदि आप निर्दिष्ट करते हैं कि आप लॉग जानकारी के साथ क्या करना चाहते हैं।


मुझे लगता है कि यह काम कर सकता है, लेकिन किसी भी दर पर मैं एक अलग मार्ग से नीचे चला गया। मैंने vsftpd में एक अधिसूचना एपीआई लिखा है। यह पूरा होने की गारंटी देता है। विवरण के लिए +1। धन्यवाद।
टॉम

0

क्या आपने --line-bufferedविकल्प का उपयोग करने की कोशिश की grep?

tail -f /var/log/vsftpd.log | grep --line-buffered 'OK UPLOAD:' | while read line ; do
        #do a bunch of processing stuff - this takes some time
done

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