ruby - 在 Sinatra 中使用 Rack::CommonLogger

标签 ruby logging sinatra rack error-logging

我有一个用 Sinatra 编写的小型网络服务器。我希望能够将消息记录到日志文件中。我已经通读了 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 请求环境调用的调用方法,如果你检查这个中间件的调用方法,就会发生这种情况:

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

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

使用方法(在你的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

希望这对您有所帮助。

关于ruby - 在 Sinatra 中使用 Rack::CommonLogger,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2239240/

相关文章:

ruby-on-rails - rails : Subclass not registering as instance of parent class

ruby - 记录 shell 命令的所有输出

java - 使用 If 子句包围 Logger 以避免冗余的 String 构造

java - 动态创建 Logback Loggers 和 Appenders

ruby - 让 Nginx 使用正确的 passenger gem

ruby - 如何在 VoltRb 中访问页面的 URL

ruby - Chartkick 中的日期不正确

unix - 不能使用 '>' 或 '>>' 从 log.Println() 和 log.Printf() 写入文件

ruby - Sinatra 在发布时清除 session

ruby - 如何使用 ruby​​1.9 部署 Rack 应用程序?