在Sinatra中使用Rack :: CommonLogger

我有一个与Sinatra一起编写的小型Web服务器。 我希望能够将消息记录到日志文件中。 我通过http://www.sinatrarb.com/api/index.html和www.sinatrarb.com/intro.html阅读,我看到Rack有一个名为Rack :: CommonLogger的东西,但我找不到如何访问和用于记录消息的任何示例。 我的应用程序很简单所以我把它写成顶级DSL,但我可以切换到从SinatraBaseinheritance它,如果这是所需要的一部分。

Rack::CommonLogger不会为你的主应用程序提供记录器,它只会像Apache那样记录请求。

自己检查代码: https : //github.com/rack/rack/blob/master/lib/rack/common_logger.rb

所有Rack应用程序都具有使用HTTP Request 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是主应用程序,中间件只是注册请求开始的时间,然后它将中间件分类为[status,header,body]三元组,然后使用这些参数调用私有日志方法,返回您的应用首先返回的相同三元组。

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中获取一些信息,然后登录构造函数调用中指定的记录器,如果没有logger实例,那么它将转到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 

希望这可以帮助。

在你的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 

我按照我在这篇博文上发现的内容 – 摘录如下

 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 

然后使用putsprint 。 它对我有用。

 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 

如果您使用Passenger,重新打开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 
Interesting Posts