在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
然后使用puts
或print
。 它对我有用。
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