2016-01-21 12 views
15

में एक विशिष्ट नियंत्रक के लिए लॉगर आउटपुट को रीडायरेक्ट करें मैंने रेल के लिए अपने पिछले प्रश्न Redirect logger output for a specific controller in Rails 3 में उत्तर के आधार पर एक समाधान बनाया है। हालांकि यह बहुत अच्छा काम करता है, हालांकि अब मैं रेलवे के समान मध्यवर्ती आधारित समाधान को लागू करने की कोशिश कर रहा हूं 4 प्रोजेक्ट लेकिन काम करने से एक ही समाधान को रखने में कुछ मतभेद हैं।रेल 4

रेल 3 समाधान:

module MyApp 
    class LoggerMiddleware 

    REPORTS_API_CONTROLLER_PATH = %r|\A/api/v.*/reports.*| 
    REPORTS_API_CONTROLLER_LOGFILE = "reports_controller.log" 

    def initialize(app) 
     @app = app 
     @logger = Rails::logger 
      .instance_variable_get(:@logger) 
      .instance_variable_get(:@log) 
     @reports_api_controller_logger = Logger.new(
      Rails.root.join('log', REPORTS_API_CONTROLLER_LOGFILE), 
      10, 1000000) 
    end 

    def call(env) 
     Rails::logger 
      .instance_variable_get(:@logger) 
      .instance_variable_set(:@log, 
       case env['PATH_INFO'] 
       when REPORTS_API_CONTROLLER_PATH then 
       @reports_api_controller_logger 
       else 
       @logger 
       end 
      ) 
     @app.call(env) 
    end 
    end 
end 

Rails.application.middleware.insert_before Rails::Rack::Logger, MyApp::LoggerMiddleware 
ऊपर में

:

रेल Rails.logger = Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log)

रेल 3 Rails.logger के लिए सेटर के लिए 3 गेटर (स्थापित करने @my_logger पर) = Rails::logger.instance_variable_get(:@logger).instance_variable_set(:@log,@my_logger)

एक बात जो मैंने अभी देखी है वह है कि रेल 4 में Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log) शून्य लौटाता है।

रेल 4 कंसोल में जाँच हो रही है, मुझे लगता है कि Rails.instance_variable_get(:@logger) रिटर्न #<ActiveSupport::Logger:0x007f84ff503a08 ....>

मैं Rails.instance_variable_get(:@logger) साथ गेटर और Rails.instance_variable_set(:@logger,my_logger) साथ सेटर की जगह की कोशिश की है और यह लगभग काम करने लगता है है। गतिविधि का पहला भाग, "प्रारंभ ..." नई लॉग फ़ाइल पर जाता है लेकिन उसके बाद सबकुछ डिफ़ॉल्ट लॉग फ़ाइल पर जाता है (मध्यवर्ती से पहले Rails.logger इसे बदल देता है)।

या तो Rails.instance_variable_get(:@logger)/रेल 4 में सबसे कम स्तर बराबर रेल 3 Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log)के लिए हो रही करने के लिए नहीं है की स्थापना Rails.logger या वहाँ है कि उसके बाद मैं इस सेट को अधिलेखित मेरी मिडलवेयर के बाद प्रक्रिया में बाद में कुछ और ही है यह।

कोई सुराग?

अद्यतन:

स्पष्ट करने के लिए समाधान काम करता है ऊपर तैनात रेल 3. में अपेक्षा के अनुरूप किसी भी सीमाओं यह या विशेष वातावरण (जैसे अगर समाधान सर्वर वातावरण सूत्रण में काम नहीं कर सकता के रूप में में नहीं हो सकता है हो सकता है यदि यह मामला है) इस समय ठीक है और इस समय बाधाओं के रूप में अनुभव नहीं किया गया है इसलिए इस प्रश्न के लिए रेल 4 समाधान में भी यही सीमाएं ठीक हैं।

+0

अफैक एक ही लॉगर इंस्टेंस थ्रेड के बीच साझा किया जाता है, इसलिए यदि आप थ्रेडिंग सर्वर का उपयोग करते हैं, या भविष्य में ऐसा करने का अवसर चाहते हैं तो सुनिश्चित करें कि "विशेष" के प्रसंस्करण के दौरान समानांतर अनुरोधों को आउटपुट न करें नियंत्रक "(प्यूमा + सी रूबी थ्रेड को अबोकू तैनाती रणनीति पसंद है इसलिए तर्क केवल अकादमिक नहीं है) – bbozo

+0

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

+0

हाय @Streamline, रेल 4 अनुप्रयोग डिफ़ॉल्ट रूप से थ्रेड किए जाते हैं। यह परिवर्तन रेल 4 के साथ पेश किया गया था। रेल 3 में आपको स्पष्ट रूप से 'config.threadsafe' के साथ बहु थ्रेड समर्थन सक्षम करना था। मुझे लगता है कि आपके रेल 4 एप्लिकेशन समवर्ती धागे चलाते हैं जो Rails.logger सेटिंग को एक गैर-निर्धारक तरीके से ओवरराइड कर रहे हैं। यह समझाएगा कि यह थोड़ी देर के बाद काम करने के लिए बंद हो जाता है। – Tawan

उत्तर

-1

1 नियंत्रक के लिए एक अलग प्रवेश वर्ग का उपयोग करने का दृष्टिकोण नकारात्मक पक्ष यह है कि यह एक सूत्रण सर्वर जो फैशन में सिर्फ JRuby के साथ इन दिनों नहीं है पर काम नहीं करेगी, लेकिन मैं एमआरआई भी thanks to Heroku

केवल विचार इसे एक हफ्ते का विचार देने के बाद अब तक syslog पर लॉग पाइप करना है और अलग फ़ाइलों में विभाजित करने के लिए syslog की सुविधाओं का उपयोग करना है।

यह अभी भी तार (इस तरह के एक के #caller का पता लगाने से लॉग फाइल करने के लिए कतार में खड़े स्वरूपित जोड़ना) कि बंटवारे के लिए अनुमति होगी शामिल करने के लिए Logger पैचिंग की आवश्यकता होगी।

प्लान बी मेरा खुद का लॉगर पेश करना होगा और उस नियंत्रक में मुझे जो चाहिए उसे लॉग ऑन करना होगा।उदाहरण के लिए यदि आप पर्याप्त

+0

हाय @ बबोजो, जिस मुद्दे पर आप थ्रेडिंग सर्वर से निपटने का वर्णन कर रहे हैं वह अभी तक एक जैसा नहीं है जहां तक ​​मुझे पता है। इस बिंदु पर और इस विशेष एसओ सवाल के लिए, मैं रेल 4 में एक ही काम करने में सक्षम होना चाहता हूं कि हम पहले से ही हमारे सर्वर पर रेल 3 में कर रहे हैं, भले ही कोई नया थ्रेडिंग सर्वर तब तक लाए जब तक आप यह कह रहे हों थ्रेडिंग सर्वर हमारे सर्वर के सेटअप से स्वतंत्र रेल 4 का एक अभिन्न हिस्सा है और यह एक नहीं है जिसे हम रेल 3 के साथ देखेंगे ..? हम हरोकू/प्यूमा का उपयोग नहीं करते हैं। हम एक डॉकर कंटेनर में उबंटू सर्वर पर Nginx/यात्री का उपयोग करते हैं। – Streamline

+0

आपकी योजना बी ऊपर उल्लिखित है, आप "मेरा खुद का लॉगर पेश करें" भाग कैसे करेंगे, क्योंकि यह एक चुनौती के लिए संभव है (हालांकि बहुत अधिक कठोर) समाधान है, भले ही थ्रेडिंग सर्वर का कोई मुद्दा हो या नहीं। क्या आप Rails :: रैक :: लॉगर और स्टैक में अपना स्वयं का संस्करण डालने से रेलवे :: रैक :: लॉगर मिडलवेयर को अपने स्वयं के मिडलवेयर के साथ बदल देंगे?क्या बंदर पैच रेल के लिए संभव है :: रैक :: पूरे मिडलवेयर को बिना किसी अलग से बदलकर लॉगर करें ताकि आपके परिवर्तनों के साथ अपडेट का उपयोग किया जा सके? – Streamline

+0

नहीं, मैं केवल init स्क्रिप्ट में एक फ़ाइल खोलूंगा और नियंत्रक में आउटपुट करूँगा :) – bbozo

5

एक दिन के लिए रेल कोड के आसपास हैकिंग करने के बाद, मुझे लगता है कि मुझे हैक-आईएस आपकी समस्या का समाधान मिला है।

आप इस प्रकार call विधि और initialize विधि संपादित करने की जरूरत:

def initialize(app) 
    @app = app 
    @logger = Rails.instance_variable_get(:@logger) 
    @reports_api_controller_logger = Logger.new(
     Rails.root.join('log', REPORTS_API_CONTROLLER_LOGFILE), 
     10, 1000000) 
end 

def call(env) 
    if env['PATH_INFO'] =~ /api\/v.*\/reports.*/ 
    Rails.instance_variable_set(:@logger, @reports_api_controller_logger) 
    ActionController::Base.logger = @reports_api_controller_logger 
    ActiveRecord::Base.logger = @reports_api_controller_logger 
    ActionView::Base.logger = @reports_api_controller_logger 
    else 
    Rails.instance_variable_set(:@logger, @logger) 
    ActionController::Base.logger = @logger 
    ActiveRecord::Base.logger = @logger 
    ActionView::Base.logger = @logger 
    end 
    @app.call(env) 
end 

यह वास्तव में एक हैक-ish समाधान है और अपनी आवश्यकताओं के अनुसार regex संशोधित करते हैं।

मुझे बताएं कि यह आपके लिए काम नहीं करता है या नहीं।

+0

बिल्कुल कई विकल्प नहीं हैं !! : डी –

+0

हाय @ जगियत-सिंह, आशाजनक लग रहा है क्योंकि मैंने कुछ मिनट पहले अपने रेल 4 ऐप के सीमित सेटअप के साथ एक संक्षिप्त परीक्षण किया था और ऐसा लगता है कि यह काम कर रहा है। मुझे आश्चर्य है कि कोई भी स्पष्टीकरण प्रदान कर सकता है कि क्यों रेल 4 में हमें रेल 3 से एक कदम पीछे की ओर ले जाने की आवश्यकता है और प्रत्येक बेस लॉगर को अलग-अलग बनाम सभी को रेल 3 में इस्तेमाल करने की आवश्यकता है? या फिर भी वहां एक जगह है जहां यह सभी एक ही स्रोत से प्राप्त होती है और हमें अभी तक यह नहीं मिला है? मैं इस सप्ताह के बाद और अधिक जांच करूँगा जब मुझे अपने रेल 4 ऐप के पूर्ण सेटअप के साथ मौका मिलता है यह देखने के लिए कि क्या यह सब उम्मीद के अनुसार काम कर रहा है। – Streamline

+0

@Streamline Rails 3 को डिफ़ॉल्ट रूप से Log4r या डिफ़ॉल्ट रूबी लॉगर प्राप्त होता है लेकिन यह रेल 4 के साथ समान नहीं होता है। रेल 4 में 'एम (ActiveRecord) V (ActionView) C (ActionController)' में प्रत्येक भाग के लिए अलग-अलग लॉगर्स होते हैं। मैंने ActiveSupport :: LogSubscriber के लॉगर को ओवरराइड करने का प्रयास किया है जो उपरोक्त सभी वर्गों द्वारा विरासत में मिलता है। लेकिन वह विधि सफल नहीं थी। इसलिए मैंने परिणाम प्राप्त करने के लिए मैन्युअल रूप से प्रत्येक लॉगर को संशोधित किया। –

0

मुझे यकीन नहीं है कि आपको रेलवे 3 में किए गए तरीके से समाधान करने की आवश्यकता है या नहीं। ऐसा लगता है कि आपका अंतिम लक्ष्य पूरा करने के अन्य तरीके हो सकते हैं। क्या आपने इनमें से कोई दृष्टिकोण या रत्न माना है?

https://github.com/TwP/logging

How to log something in Rails in an independent log file?

कभी कभी कुछ क्या आप आज़मा चुके हैं उपयोगी IMHO हो सकता है की तुलना में पूरी तरह से अलग कोशिश कर रहा।

यह अनुमान का एक सा है, लेकिन इस वजह से आपके गेटर setters अपेक्षा के अनुरूप काम नहीं कर रहे हो सकता है: https://github.com/rails/rails/commit/6329d9fa8b2f86a178151be264cccdb805bfaaac

Jagjot के समाधान के बारे में और MVC कार्रवाई कक्षा से प्रत्येक के लिए आधार लॉग सेट करने के लिए की आवश्यकता होगी,, 4 सेट रेल डिफ़ॉल्ट रूप से ये अलग-अलग होते हैं जो टर्न में बॉक्स के बाहर अधिक लचीलापन प्रदान करते हैं। http://guides.rubyonrails.org/configuring.html#initializers