在 Sinatra 中使用 Rack::CommonLogger [英] Use Rack::CommonLogger in Sinatra

查看:34
本文介绍了在 Sinatra 中使用 Rack::CommonLogger的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用 Sinatra 编写的小型网络服务器.我希望能够将消息记录到日志文件中.我已经通读了 http://www.sinatrarb.com/api/index.html 和 www.sinatrarb.com/intro.html,我看到 Rack 有一个叫做 Rack::CommonLogger 的东西,但我找不到任何关于如何访问和使用它来记录消息的例子.我的应用程序很简单,所以我将它编写为顶级 DSL,但如果这是需要的一部分,我可以切换到从 SinatraBase 对其进行子类化.

I have a small web-server that I wrote with Sinatra. I want to be able to log messages to a log file. I've read through http://www.sinatrarb.com/api/index.html and www.sinatrarb.com/intro.html, and I see that Rack has something called Rack::CommonLogger, but I can't find any examples of how it can be accessed and used to log messages. My app is simple so I wrote it as a top-level DSL, but I can switch to subclassing it from SinatraBase if that's part of what's required.

推荐答案

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

Rack::CommonLogger won't provide a logger to your main app, it will just logs the request like Apache would do.

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

所有 Rack 应用程序都有使用 HTTP 请求环境调用 get 的 call 方法,如果您检查此中间件的 call 方法,则会发生以下情况:

All Rack apps have the call method that get's invoked with the HTTP Request env, if you check the call method of this middleware this is what happens:

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] 三重,并且然后使用这些参数调用私有日志方法,返回与您的应用首先返回的相同的三元组.

The @app in this case is the main app, the middleware is just registering the time the request began at, then it class your middleware getting the [status, header, body] triple, and then invoke a private log method with those parameters, returning the same triple that your app returned in the first place.

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 记录器(似乎默认有一个)

As you can tell, the log method just grabs some info from the request env, and logs in on a logger that is specified on the constructor call, if there is no logger instance then it goes to the rack.errors logger (it seems there is one by default)

使用方式(在你的config.ru中):

The way to use it (in your config.ru):

logger = Logger.new('log/app.log')

use Rack::CommonLogger, logger
run YourApp

如果你想在你的所有应用中都有一个通用的记录器,你可以创建一个简单的记录器中间件:

If you want to have a common logger in all your app, you could create a simple logger middleware:

class MyLoggerMiddleware

  def initialize(app, logger)
    @app, @logger = app, logger
  end

  def call(env)
    env['mylogger'] = @logger
    @app.call(env)
  end

end

要使用它,请在您的 config.ru 上:

To use it, on your config.ru:

logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
use MyLoggerMiddleware, logger
run MyApp

希望这会有所帮助.

这篇关于在 Sinatra 中使用 Rack::CommonLogger的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆