2009-08-18 11 views
17

मेरे पास एक लॉग फ़ाइल है जो लगातार बढ़ रही है। मैं रूबी स्क्रिप्ट के माध्यम से इसे कैसे देख और पार्स कर सकता हूं?एक बढ़ती लॉग फ़ाइल देखें/पढ़ें

स्क्रिप्ट प्रत्येक नई लाइन के रूप में यह स्क्रीन जब नई लाइन स्ट्रिंग 'त्रुटि'

उत्तर

8

आप निम्नलिखित तरीके से Kernel#select उपयोग कर सकते हैं करने के लिए फ़ाइल और आउटपुट कुछ करने के लिए लिखा है पार्स जाएगा:

def watch_for(file,pattern) 
    f = File.open(file,"r") 

    # Since this file exists and is growing, seek to the end of the most recent entry 
    f.seek(0,IO::SEEK_END) 

    while true 
     select([f]) 
     puts "Found it!" if f.gets =~ pattern 
    end 
end 

फिर इसे पसंद फोन:

watch_for("some_file", /ERROR/) 

मैं सभी त्रुटि जाँच elided है और इस तरह के - आपको लगता है कि करना चाहते हैं जाएगा और शायद कुछ मेचा लूप से बाहर निकलने के लिए नस्ल। लेकिन मूल विचार वहाँ है।

4

आप लिनक्स पर कर रहे हैं ...

tail -f log/development.log | grep "ERROR" 

जब तक आप वास्तव में इसे किसी कारण के लिए एक रूबी स्क्रिप्ट बनना चाहता था।

+0

रैपिंग एक स्क्रिप्ट में इस आप प्रतिक्रिया करने की क्षमता देता है ऐसा होने से यह एक और अर्थपूर्ण तरीके से एक त्रुटि के लिए हुआ। जब आप पोस्ट-प्रोसेस करना चाहते हैं तो grepping अच्छा है, लेकिन यह गतिशील व्यवहार का आह्वान करने की अपनी क्षमता में सीमित है। – ezpz

+0

"... स्क्रीन पर कुछ आउटपुट जब नई पंक्ति स्ट्रिंग 'ERROR' है, गतिशील व्यवहार नहीं है :) – cakeforcerberus

+1

यह मेरे लिए सबसे अच्छा काम करता है। त्रुटि लॉग के आसपास मेटा-प्रोग्रामिंग कहीं और बेहतर खर्च करने की तरह लगता है। – MattC

17
def watch_for(file, pattern) 
    f = File.open(file,"r") 
    f.seek(0,IO::SEEK_END) 
    while true do 
    select([f]) 
    line = f.gets 
    puts "Found it! #{line}" if line=~pattern 
    end 
end 

watch_for("g.txt",/ERROR/) 

ezpz के विचार के लिए धन्यवाद, चयन विधि का उपयोग करके आप जो चाहते हैं उसे प्राप्त करें। चुनिंदा विधि आईओ की स्ट्रीम सुन रही है, 'देर से' बाइट्स को पढ़ें।

+2

नोट: फ़ाइल चयन पर उपयोग किए जाने पर हमेशा 'चयन करें' तुरंत लौटाता है: आप हमेशा उस फ़ाइल स्ट्रीम से ईओएफ पढ़ सकते हैं, इसलिए आपकी रूबी प्रक्रिया कताई समाप्त होती है जबकि यह फ़ाइल को अपडेट करने की प्रतीक्षा करता है। विभिन्न ऑपरेटिंग सिस्टम फाइलों पर इंतजार करने के लिए विभिन्न टूल्स पेश करते हैं, लिनक्स में इनोटिफाइफा है और ओएस एक्स में फिसेंट हैं - वहां सुविधाजनक रूबी रत्न भी हैं जो उन्हें लपेटते हैं। – antifuchs

+1

-1 मूर्खतापूर्ण समाधान जो 100% CPU का उपयोग करता है। –

+0

मुझे लगता है कि यह 100% सीपीयू का उपयोग करने का कारण है क्योंकि यदि आप लाइन को हटाते हैं जो 'if line = ~ pattern' कहता है तो यह कोई नया अपडेट नहीं होने पर भी रिक्त रेखाएं लौटाता रहता है। मुझे यकीन नहीं है कि इसे स्वयं कैसे ठीक करें, क्योंकि मैं उस मुद्दे पर भी ठोकर खा रहा हूं। – Pred

3

बाहर की जांच file-tail मणि त्वरित सामान के लिए

3

गरीब आदमी का दृष्टिकोण:

  1. एक रूबी स्क्रिप्ट के साथ

    ARGF.each do |line| 
        ... 
    
  2. चल रहा है स्क्रीन करता है:

    tail -f file | ruby script 
    
5

दो दृष्टिकोण हैं:

  • चुनाव अनंत लूप में फ़ाइल (Qianjigui के जवाब में की तरह है, लेकिन यह कुछ sleep अनंत लूप के अंदर डाल करने के लिए अच्छा है)
  • उपयोग ओएस घटना सबसिस्टम: kqueue बीएसडी पर, लिनक्स

यहां एक लेख है जिसके बारे में मैंने लिखा है: Ruby for Admins: Reading Growing Files। तो दोनों घटना सबसिस्टम और मतदान के संयोजन कार्यक्रम इस प्रकार है:

def tail_dash_f(filename) 
    open(ARGV.first) do |file| 
    file.read   
    case RUBY_PLATFORM # string with OS name, like "amd64-freebsd8" 
    when /bsd/, /darwin/ 
     require 'rb-kqueue' 
     queue = KQueue::Queue.new  
     queue.watch_file(ARGV.first, :extend) do 
     yield file.read    
     end 
     queue.run      
    when /linux/ 
     require 'rb-inotify' 
     queue = INotify::Notifier.new 
     queue.watch(ARGV.first, :modify) do 
     yield file.read    
     end 
     queue.run      
    else 
     loop do   
     changes = file.read 
     unless changes.empty? 
      yield changes 
     end 
     sleep 1.0  
     end 
    end 
    end 
end 

tail_dash_f ARGV.first do |data| 
    print data 
    if data =~ /error/i 
    # do something else, for example send an email to administrator 
    end 
end 
1

@Qianjigui के विचार पर काम कर रहे है, लेकिन 100% सीपीयू का उपयोग नहीं:

def watch_for(file, pattern) 
    # Replace -n0 with -n+1 if you want to read from the beginning of file 
    f = IO.popen(%W[tail -f -n0 #{file}]) 
    loop do 
    select([f]) 
    while line = f.gets 
     puts "Found it! #{line}" if line =~ pattern 
    end 
    end 
end 

watch_for('g.txt', /ERROR/) 
संबंधित मुद्दे