如何让SInatra和Rack输出到我的Logger实例?

时间:2016-03-03 12:04:06

标签: ruby logging sinatra rack

我有一个Sinatra应用程序,它通过Logger实例向STDOUT输出稳定的信息流。我还打开了Sinatra日志记录和Rack日志记录。为了论证,我们可以说这是一个好主意。

此处输出的内容如下:

[2016-03-03 11:32:38] INFO  WEBrick 1.3.1
[2016-03-03 11:32:38] INFO  ruby 2.3.0 (2015-12-25) [x86_64-linux]
[2016-03-03 11:32:38] INFO  WEBrick::HTTPServer#start: pid=12303 port=4567
[03/03/16 11:32:45] core/lib/registry.rb     INFO Resolving request for u:/swingshift/registry a:GET
[03/03/16 11:32:45] core/lib/registry.rb     INFO SwingShift::RegistryController has been selected...
10.192.0.136 - - [03/Mar/2016:11:32:45 +0000] "GET /swingshift/registry HTTP/1.1" 200 10227 0.0557
10.192.0.136 - - [03/Mar/2016:11:32:46 +0000] "GET /css/bootstrap.min.css HTTP/1.1" 304 - 0.0023

正如你所看到的,它有点混乱。我想要告诉Sinatra和Rack使用我的Logger实例,而不是他们自己的实例。

  • 如何让Sinatra使用我的记录器?
  • 如何让Rack使用我的记录器?

(或者,我可以将一个proc传递给他们的记录器以将它们格式化一样吗?这样做不太好,但它会有所不同。)

这是我的Sinatra设置块。此时$ logger已指向我的Logger实例:

configure do                                                
  $logger.info(__FILE__){"Starting..."}                     
  set :bind, '0.0.0.0'                                      
  enable :sessions                                          
  set :session_secret, 'whatever'

  set :views, BASEDIR
  set :haml, :layout_options => { :views => 'core/views' }  

  enable :logging                                           
  set :dump_errors, true                                    
end                     

我也有一个

use Rack::CommonLogger, $logger

......但它似乎没有做任何事情。

更新:: 我了解https://stackoverflow.com/questions/2239240A/use-rackcommonlogger-in-sinatra,但是:

  • 它没有解决Sinatra日志记录,只是Rack
  • 接受的答案似乎非常复杂,在评论中提出了一些未提出的答案。 (我是否真的需要在config.ru中设置记录器并添加中间件日志记录层?日志记录层的语法是否错误,因为> = 4个人似乎在想?)

据Sinatra说,我应该能够从settings区块控制Rack。这不是真的吗?

更新2:我现在已经适当地解决了另一个问题。按原样实现它......对于日志来说绝对没有。

2 个答案:

答案 0 :(得分:0)

我没有使用WEBrick而是使用Thin(set :server, 'thin')无论如何,根据Sinatra配置,我将rack.errors重定向到我的$logger

class IOToLog < IO
  def initialize(logger)
    @logger = logger
  end
  def write(string)
    @logger.debug {"SINATRA #{string.strip}"}
  end
end
IOTOLOG = IOToLog.new($logger)

before {
  env["rack.errors"] =  IOTOLOG
}

,输出为:

2017-06-21 15:44:46.166 DEBUG SINATRA 127.0.0.1 - - [21/Jun/2017:15:44:46 +0200] "GET /wd/hub/status HTTP/1.1" 200 83 0.0004
2017-06-21 15:44:51.167 DEBUG SINATRA 127.0.0.1 - - [21/Jun/2017:15:44:51 +0200] "GET /wd/hub/status HTTP/1.1" 200 83 0.0004

顺便说一下,我试过env["rack.logger"] = $logger,但没有运气。

答案 1 :(得分:0)

我还不能评论,所以发帖回答。您可以格式化到IOToLog的消息。您需要在阻止之前设置格式。也许像是

before {
   env["rack.errors"] =  IOTOLOG
   IOTOLOG.format
}

在IOToLog中添加如下内容:

class IOToLog < IO
    def format
      @logger.formatter = proc do |severity, datetime, progname, msg|
      "#{severity}: #{msg}\n"
    end
end