2010-02-10 14 views
26

में कॉमनलॉगर मेरे पास एक छोटा वेब-सर्वर है जिसे मैंने सिनात्रा के साथ लिखा था। मैं लॉग फ़ाइल में संदेशों को लॉग इन करने में सक्षम होना चाहता हूं। मैंने http://www.sinatrarb.com/api/index.html और www.sinatrarb.com/intro.html के माध्यम से पढ़ा है, और मुझे लगता है कि रैक में रैक :: कॉमनलॉगर नामक कुछ है, लेकिन मुझे कोई उदाहरण नहीं मिल रहा है कि इसे कैसे एक्सेस किया जा सकता है और संदेशों को लॉग इन करने के लिए उपयोग किया जा सकता है। मेरा ऐप सरल है इसलिए मैंने इसे शीर्ष-स्तरीय डीएसएल के रूप में लिखा है, लेकिन यदि मैं आवश्यक चीज़ों का हिस्सा हूं तो मैं इसे सिनात्राबेस से उप-वर्गीकृत करने के लिए स्विच कर सकता हूं।रैक का उपयोग करें :: सिनात्रा

require 'rubygems' 
require 'sinatra' 

disable :run 
set :env, :production 
set :raise_errors, true 
set :views, File.dirname(__FILE__) + '/views' 
set :public, File.dirname(__FILE__) + '/public' 
set :app_file, __FILE__ 

log = File.new("log/sinatra.log", "a") 
STDOUT.reopen(log) 
STDERR.reopen(log) 

require 'app' 
run Sinatra.application 

नीचे कुछ अंश तो puts या print का उपयोग करें -

उत्तर

41

Rack::CommonLogger आपके मुख्य ऐप पर लॉगर प्रदान नहीं करेगा, यह केवल अपाचे जैसे अनुरोध को लॉग करेगा।

चेक खुद के द्वारा कोड: अगर आप इस इस मिडलवेयर की कॉल विधि जाँच https://github.com/rack/rack/blob/master/lib/rack/common_logger.rb

सभी Rack क्षुधा, कॉल विधि हो कि HTTP अनुरोध env के साथ आमंत्रण रहा है क्या होता है:

def call(env) 
    began_at = Time.now 
    status, header, body = @app.call(env) 
    header = Utils::HeaderHash.new(header) 
    log(env, status, header, began_at) 
    [status, header, body] 
end 

इस मामले में @app मुख्य ऐप है, मिडलवेयर सिर्फ अनुरोध के समय को पंजीकृत कर रहा है, फिर यह आपके मिडलवेयर को [स्थिति, शीर्षलेख, शरीर] ट्रिपल प्राप्त कर रहा है, और फिर उन पैरामीटर के साथ एक निजी लॉग विधि का आह्वान करता है , एक ही ट्रिपल लौट रहा है कि आपका ए पीपी पहले स्थान पर लौट आया।

logger विधि प्रकार है:

def log(env, status, header, began_at) 
    now = Time.now 
    length = extract_content_length(header) 

    logger = @logger || env['rack.errors'] 
    logger.write FORMAT % [ 
    env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-", 
    env["REMOTE_USER"] || "-", 
    now.strftime("%d/%b/%Y %H:%M:%S"), 
    env["REQUEST_METHOD"], 
    env["PATH_INFO"], 
    env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"], 
    env["HTTP_VERSION"], 
    status.to_s[0..3], 
    length, 
    now - began_at ] 
end 

आपको बता सकता है के रूप में, log विधि सिर्फ अनुरोध env से कुछ जानकारी पकड़ लेता है, और एक लकड़हारा कि निर्माता फोन पर निर्दिष्ट किया जाता है पर में लॉग करता है, अगर वहाँ है कोई लकड़हारा उदाहरण तो यह rack.errors लकड़हारा को जाता है (ऐसा लगता है वहाँ डिफ़ॉल्ट रूप से एक है)

जिस तरह से यह (अपने config.ru में) का उपयोग करने के लिए:

logger = Logger.new('log/app.log') 

use Rack::CommonLogger, logger 
run YourApp 

आप अपने सभी एप्लिकेशन में एक आम लकड़हारा करना चाहते हैं, तो आप एक साधारण लकड़हारा मिडलवेयर बना सकते हैं:

class MyLoggerMiddleware 

    def initialize(app, logger) 
    @app, @logger = app, logger 
    end 

    def call(env) 
    env['mylogger'] = @logger 
    @app.call(env) 
    end 

end 

इसका इस्तेमाल करने के लिए अपने config.ru पर,:

logger = Logger.new('log/app.log') 
use Rack::CommonLogger, logger 
use MyLoggerMiddleware, logger 
run MyApp 

आशा इस मदद करता है।

+4

MyLoggerMiddleware # कॉल (एनवी) की पहली पंक्ति नहीं होनी चाहिए: env ['rack.errors'] = @logger ? –

+0

इसके अलावा, मैं हर अनुरोध, केवल चेतावनियां और त्रुटि संदेशों को लॉग इन नहीं करना चाहता हूं। लेकिन मैं इसे विन्यास योग्य बनाना चाहता हूं ताकि मैं "डीबग", "जानकारी", "चेतावनियां", "त्रुटियों" के रूप में लॉगिंग का स्तर निर्धारित कर सकूं, ... बीटीडब्ल्यू - मेरा ऐप रेल नहीं है एप्लिकेशन। कोई config.ru फ़ाइल नहीं है। यह एक साधारण सिनात्रा ऐप है। मैं मौजूदा मानक का उपयोग करने की उम्मीद कर रहा था, लेकिन यह पता नहीं लगा सकता कि क्या है। हो सकता है कि मुझे कॉमनलॉगर लेना पड़े, आपने मुझे दिखाया और इसे अपने आप पर विंग कर दिया? –

+0

'config.ru' रैक के लिए कॉन्फ़िगरेशन फ़ाइल है, न कि रेल के लिए। सिनात्रा और रेल दोनों रैक आधारित हैं, इसलिए आप सिनात्रा अनुप्रयोगों में 'config.ru' का भी उपयोग कर सकते हैं। – jafrog

2

मैं क्या मैं इस blog पोस्ट पर पाया पीछा किया। यह मेरे लिए काम किया।

+1

काम करता है यही कारण है, लेकिन मैं वास्तव में timestamps के साथ स्वरूपित संदेश भेजने के लिए रैक :: CommonLogger उपयोग करने के लिए कैसे पता लगाने के लिए चाहते हैं। –

15

अपने config.ru में:

root = ::File.dirname(__FILE__) 
logfile = ::File.join(root,'logs','requests.log') 

require 'logger' 
class ::Logger; alias_method :write, :<<; end 
logger = ::Logger.new(logfile,'weekly') 

use Rack::CommonLogger, logger 

require ::File.join(root,'myapp') 
run MySinatraApp.new # Subclassed from Sinatra::Application 
+0

मैं आपके समाधान का प्रयास करता हूं, और यह काम करता है। मुझे आश्चर्य है कि इसे config.ru में क्यों होना है? – Chamnap

+0

एक फाइल चीजें जो मैं वहां 100% नहीं हूं, क्या आप इस बात पर टिप्पणी करेंगे कि कृपया कुछ पंक्तियां क्यों हैं? –

1
class ErrorLogger 
    def initialize(file) 
    @file = ::File.new(file, "a+") 
    @file.sync = true 
    end 

    def puts(msg) 
    @file.puts 
    @file.write("-- ERROR -- #{Time.now.strftime("%d %b %Y %H:%M:%S %z")}: ") 
    @file.puts(msg) 
    end 
end 


class App < Sinatra::Base 

    if production? 
    error_logger = ErrorLogger.new('log/error.log') 

    before { 
     env["rack.errors"] = error_logger 
    } 
    end 

    ... 

end 
0

STDOUT को पुन: खोलने और एक फ़ाइल में पुनः निर्देशित एक अच्छा विचार है अगर आप पैसेंजर का उपयोग नहीं है। यह मेरे मामले में होता है कि यात्री शुरू नहीं होता है। इस मुद्दे के लिए https://github.com/phusion/passenger/wiki/Debugging-application-startup-problems#stdout-redirection पढ़ें।

यह बजाय सही तरीके से होगा:

logger = ::File.open('log/sinatra.log', 'a+') 
Sinatra::Application.use Rack::CommonLogger, logger 
संबंधित मुद्दे