Rack::CommonLogger 不会向您的主应用程序提供记录器,它只会像 Apache 那样记录请求。
自行查看代码:https://github.com/rack/rack/blob/master/lib/rack/common_logger.rb
所有Rack 应用程序都有使用 HTTP 请求 env 调用的 call 方法,如果您检查此中间件的 call 方法,会发生这种情况:
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 方法只是从请求环境中获取一些信息,并登录到构造函数调用中指定的记录器,如果没有记录器实例,则它转到rack.errors logger(好像默认有一个)
使用方法(在你的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
希望这会有所帮助。