2010-01-06 9 views
6

में कॉलर का मॉड्यूल प्राप्त करना हमारे पास हमारे रूबी 1.8.6 वेब एप्लिकेशन में डेटा लॉग करने के लिए कोड है। आप इसे मोटे तौर पर फोन इस प्रकार है:रूबी

$log.info("Some text here") 

अब, लॉग इन उत्पादन में, मैं मॉड्यूल जहां कि लाइन दिखाई दिया शामिल करना चाहते हैं। मुझे पता है कि Kernel#caller मुझे एक सरणी देगा जहां मैं लॉग लाइन होने वाली फ़ाइल और लाइन नंबर खींच सकता हूं, लेकिन मुझे वह नहीं चाहिए। मैं मॉड्यूल चाहता हूं, फाइल का नाम नहीं। स्पष्ट समाधान लॉग लाइन को संशोधित करना है ताकि यह पढ़ सके:

$log.info("Some text here", self.class.name) 

और फिर परिणाम का विश्लेषण करें। यह काम नहीं करेगा, हालांकि, क्योंकि मैं इस जानकारी को डिफ़ॉल्ट मामले में निकालने की कोशिश कर रहा हूं। यही है, अगर प्रोग्रामर मॉड्यूल निर्दिष्ट करने के लिए भूल गया है, तो लॉग लाइन के लिए दूसरा पैरामीटर, मुझे काम करने के लिए समाधान की आवश्यकता है।

क्या ऐसा करने का कोई तरीका है? यदि नहीं, तो मुझे बस caller सरणी के साथ करना होगा; हमारे अधिकांश मॉड्यूल अलग निर्देशिका में हैं, इसलिए यह 80% समाधान होगा। फ़ाइल foo.rb में

module Log 
    class Logger 
    def info(msg, mod = '') 
     puts "Module: #{mod} Msg: #{msg}" 
    end 
    end # class Logger 
end # module Log 
$log = Log::Logger.new 

: फ़ाइल log.rb में

:

अधिक पूर्ण उदाहरण के लिए, कृपया नाबालिग वाक्यविन्यास त्रुटियों बहाना

module Foo 
    class Bar 
    def do_something 
     # Do not pass in self.class.name. 
     # We want the output to look like: 
     # Module: Foo Msg: I did something! 
     $log.info "I did something!" 
    end 
    end # class Bar 
end #module Foo 
+0

मुझे नहीं लगता कि आप इसे कैसे कर सकते हैं, जब तक कि लॉगर ऑब्जेक्ट में 'self' या' बाध्यकारी 'पास न हो। आपको फ़ाइल को 'कॉलर' से जानकारी के साथ पार्स करना होगा, जो मुझे यकीन है कि आप नहीं करना चाहते हैं। –

उत्तर

3

उपयोग call_stack

पहले RubyGems के साथ इसे स्थापित: मेरे लिए

require 'rubygems' 
require 'call_stack' 

call_stack_on 

module Log 
    class Logger 
    def info(msg, mod = '') 
     mod = call_stack(2)[0][0] if mod == '' 
     puts "Module: #{mod} Msg: #{msg}" 
    end 
    end # class Logger 
end # module Log 
$log = Log::Logger.new 

काम करता है (रूबी 1.8.7):

gem install call_stack 

तब को log.rb बदल जाते हैं।

$ ruby foo.rb 
Module: Foo::Bar Msg: I did something! 
+0

उनकी साइट के अनुसार, हम बदले में रूबी-डीबग का उपयोग करना चाहते हैं, हालांकि लिंक टूटे हुए हैं। यह भी नोट करता है कि इसमें काफी धीमी गति शामिल है। वास्तव में, यह भी काम नहीं कर सकता है। फिर भी, अब तक का सबसे अच्छा समाधान है, इसलिए मैं इस जवाब को +1 कर रहा हूं। धन्यवाद। – ChrisInEdmonton

+0

यहां रूबी-डीबग है: http://rubyforge.org/projects/ruby-debug/, और हाँ, यह धीमा होगा। कॉलस्टैक निरीक्षण के लिए रूबी का डिफ़ॉल्ट समर्थन दयनीय है और इसे सुधारने के लिए कई सुझाव दिए गए हैं, इसलिए आपको कर्नेल # कॉलर मिलता है। किसी भी समाधान में या तो सी एपीआई के साथ ट्रेसिंग या काम करना शामिल होगा, इसलिए मैंने सबसे सरल प्रतीत होता है। मेरा सुझाव है कि यदि आपको वास्तव में इस कार्यक्षमता की आवश्यकता है तो आप कोडिंग सम्मेलन को लागू करते हैं और हमेशा प्रोग्रामर मॉड्यूल निर्दिष्ट करते समय मॉड्यूल निर्दिष्ट करते हैं (कोई डिफ़ॉल्ट मान नहीं)। असुविधाजनक, लेकिन तेज़। या डीबगिंग नहीं करते समय आप कॉल_स्टैक बंद कर सकते हैं। –

2

मेरे अपने उद्देश्यों के लिए उत्तर की तलाश करते हुए इस पोस्ट में आया।

उपयुक्त नहीं मिला, इसलिए मैंने रूबी स्रोत के माध्यम से खोला और एक साथ विस्तार किया। मैं एक gem- किसी भी समस्या के बिना स्थापित करना चाहिए के रूप में यह बंडल किया है जब तक कि आप रूबी 1.9.1 का उपयोग कर रहे हैं:

sudo मणि

स्थापित इस इस रूबी 1.8 के साथ काम नहीं करेगा , फ्रेम के ट्रैकिंग के लिए 1.8 के पास एक अलग मॉडल है।

http://rubygems.org/gems/sender

3

एक mixin ओपी के विशिष्ट आवश्यकताओं को हल करती है (इस बीच, सामान्य मामले "जो मुझे बुलाया" को सुलझाने के लिए आशेर करने के लिए +1!)।

module Log 
    module Logger 
    def info(msg) 
     puts "Module: #{self} Msg: #{msg}" 
    end 
    end # class Logger 
end # module Log 

module Foo 
    class Bar 
    include Log::Logger 
    def do_something 
     # Do not pass in self.class.name. 
     # We want the output to look like: 
     # Module: Foo Msg: I did something! 
     info "I did something!" 
    end 
    end # class Bar 
end # module Foo 

foobar = Foo::Bar.new 
foobar.do_something