Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

रूबी में अपवाद होने पर स्थानीय और आवृत्ति चर लॉग करना

क्या आपके पास कभी कोई बग है जिसे आप आसानी से पुन:उत्पन्न नहीं कर सकते हैं? ऐसा तभी होता है जब लोगों ने आपके ऐप को कुछ समय के लिए इस्तेमाल किया हो। और त्रुटि संदेश और बैकट्रेस आश्चर्यजनक रूप से अनुपयोगी हैं।

यह ऐसा समय है जब आप अपवाद होने से ठीक पहले ऐप की स्थिति का एक स्नैपशॉट ले सकते हैं तो यह वास्तव में आसान होगा। यदि आपके पास, उदाहरण के लिए, सभी स्थानीय चर और उनके मूल्यों की एक सूची हो सकती है। ठीक है, आप कर सकते हैं - और यह इतना कठिन भी नहीं है!

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

पेश है बाइंडिंग_ऑफ़_कॉलर

बाइंडिंग_ऑफ_कॉलर रत्न आपको मौजूदा स्टैक के किसी भी स्तर के लिए बाइंडिंग एक्सेस करने देता है। सू ..... इसका वास्तव में क्या मतलब है?

"स्टैक" वर्तमान में "प्रगति में" विधियों की एक सूची है। आप caller . का उपयोग कर सकते हैं वर्तमान स्टैक की जांच करने की विधि। यहां एक सरल उदाहरण दिया गया है:

def a
  puts caller.inspect # ["caller.rb:20:in `<main>'"]
  b()
end

def b
  puts caller.inspect # ["caller.rb:4:in `a'", "caller.rb:20:in `<main>'"]
  c()
end

def c
  puts caller.inspect # ["caller.rb:11:in `b'", "caller.rb:4:in `a'", "caller.rb:20:in `<main>'"]
end

a()

बाइंडिंग वर्तमान निष्पादन संदर्भ का एक स्नैपशॉट है। नीचे दिए गए उदाहरण में, मैं एक विधि के बंधन को कैप्चर करता हूं, फिर इसका उपयोग विधि के स्थानीय चरों तक पहुंचने के लिए करता हूं।

def get_binding
  a = "marco"
  b = "polo"
  return binding
end

my_binding = get_binding

puts my_binding.local_variable_get(:a) # "marco"
puts my_binding.local_variable_get(:b) # "polo"

बाइंडिंग_ऑफ_कॉलर रत्न आपको मौजूदा निष्पादन स्टैक के किसी भी स्तर के लिए बाइंडिंग तक पहुंच प्रदान करता है। उदाहरण के लिए, मैं इसका उपयोग c . को अनुमति देने के लिए कर सकता था a . तक विधि पहुंच विधि के स्थानीय चर।

require "rubygems"
require "binding_of_caller"

def a
  fruit = "orange"
  b()
end

def b
  fruit = "apple"
  c()
end

def c
  fruit = "pear"

  # Get the binding "two levels up" and ask it for its local variable "fruit"
  puts binding.of_caller(2).local_variable_get(:fruit) 
end

a() # prints "orange"

इस समय, आप शायद दो परस्पर विरोधी भावनाओं को महसूस कर रहे हैं। उत्साह, क्योंकि यह वास्तव में अच्छा है। और घृणा, क्योंकि यह निर्भरता की एक बदसूरत गड़बड़ी में तेजी से पतित हो सकता है, जितना कि आप डीएचएच कह सकते हैं।

अपवाद के समय स्थानीय लोगों को लॉग करना

अब जब हमने बाइंडिंग_ऑफ_कॉलर में महारत हासिल कर ली है, तो अपवाद के समय सभी स्थानीय चरों को लॉग करना केक का एक टुकड़ा है। नीचे दिए गए उदाहरण में मैं raise विधि को ओवरराइड कर रहा हूं। मेरी नई वृद्धि विधि जो भी विधि कहलाती है उसका बंधन प्राप्त करती है। फिर यह सभी स्थानीय लोगों के माध्यम से पुनरावृति करता है और उन्हें प्रिंट करता है।

require "rubygems"
require "binding_of_caller"

module LogLocalsOnRaise
  def raise(*args)
    b = binding.of_caller(1)
    b.eval("local_variables").each do |k|
      puts "Local variable #{ k }: #{ b.local_variable_get(k) }"
    end
    super
  end
end

class Object
  include LogLocalsOnRaise
end

def buggy
  s = "hello world"
  raise RuntimeError
end

buggy()

यहां बताया गया है कि यह क्रिया में कैसा दिखता है:

रूबी में अपवाद होने पर स्थानीय और आवृत्ति चर लॉग करना

व्यायाम:लॉग इंस्टेंस वैरिएबल

मैं इसे आपके लिए स्थानीय लोगों के साथ इंस्टेंस वेरिएबल लॉग करने के लिए एक अभ्यास के रूप में छोड़ दूँगा। यहां एक संकेत दिया गया है:आप my_binding.eval("instance_variables") का उपयोग कर सकते हैं और my_binding.instance_variable_get ठीक उसी तरह जैसे आप my_binding.eval("local_variables") का उपयोग करेंगे और my_binding.instance_variable_get

आसान तरीका

यह काफी मस्त ट्रिक है। लेकिन लॉग फ़ाइलों के इर्द-गिर्द टटोलना बग्स को ठीक करने का सबसे सुविधाजनक तरीका नहीं है, खासकर यदि आपका ऐप स्टेजिंग पर है और आपके पास इसका उपयोग करने वाले कई लोग हैं। साथ ही, यह और कोड है जिसे आपको बनाए रखना है।

यदि आप त्रुटियों के लिए अपने ऐप की निगरानी के लिए हनीबैगर का उपयोग करते हैं, तो हम स्थानीय लोगों को स्वचालित रूप से पकड़ सकते हैं। आपको बस अपने जेमफाइल में बाइंडिंग_ऑफ_कॉलर रत्न जोड़ना है:

# Gemfile

group :development, :staging do
  # Including this gem enables local variable capture via Honeybadger
  gem "binding_of_caller"
  ...
end

अब, जब भी कोई अपवाद होता है, तो आपको बैकट्रेस, पैराम्स आदि के साथ सभी स्थानीय लोगों की रिपोर्ट मिल जाएगी।

रूबी में अपवाद होने पर स्थानीय और आवृत्ति चर लॉग करना


  1. लॉगर और लॉगरेज के साथ रूबी में लॉगिंग

    रूबी में लॉग के साथ कार्य करना लॉगिंग उन प्राथमिक कार्यों में से एक है जिसे एक एप्लिकेशन आमतौर पर संबोधित करता है। लॉग का उपयोग तब किया जाता है जब आपको आवश्यकता होती है, उदाहरण के लिए, देखें कि आपके ऐप्स के अंदर क्या हो रहा है, उन पर नज़र रखें, या कुछ विशिष्ट डेटा के लिए मीट्रिक एकत्र करें। एक न

  1. रूबी में पर्यावरण चर का उपयोग कैसे करें?

    पर्यावरण चर एक कुंजी/मान युग्म है, यह इस तरह दिखता है: KEY=VALUE हम आपके कंप्यूटर के सभी प्रोग्रामों के बीच कॉन्फ़िगरेशन विकल्पों को साझा करने के लिए इन चरों का उपयोग करते हैं। इसलिए यह सीखना महत्वपूर्ण है कि वे कैसे काम करते हैं और ENV का उपयोग करके अपने रूबी कार्यक्रमों से उन्हें कैसे एक्सेस क

  1. रूबी केस स्टेटमेंट के कई उपयोग

    जब भी आपको कुछ if / elsif . का उपयोग करने की आवश्यकता हो आप इसके बजाय रूबी केस स्टेटमेंट का उपयोग करने पर विचार कर सकते हैं। इस पोस्ट में, आप कुछ अलग उपयोग के मामलों के बारे में जानेंगे और यह सब वास्तव में हुड के तहत कैसे काम करता है। नोट:अन्य प्रोग्रामिंग भाषाओं में इसे स्विच . के रूप में जाना