在Sinatra中使用Rack :: CommonLogger
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Sinatra中使用Rack :: CommonLogger相关的知识,希望对你有一定的参考价值。
我有一个与Sinatra一起编写的小型Web服务器。我希望能够将消息记录到日志文件中。我通过http://www.sinatrarb.com/api/index.html和www.sinatrarb.com/intro.html阅读,我看到Rack有一个名为Rack :: CommonLogger的东西,但我找不到任何关于如何访问和用于记录消息的例子。我的应用程序很简单所以我把它写成顶级DSL,但我可以切换到从SinatraBase继承它,如果这是所需要的一部分。
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
我跟着我在这个blog帖子上发现的内容 - 摘录如下
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
以上是关于在Sinatra中使用Rack :: CommonLogger的主要内容,如果未能解决你的问题,请参考以下文章