Sinatra with Puma 在终端中提供两倍的输出

Sinatra with Puma gives twice the output in the terminal

我已将 Puma 添加到我的 sinatra 应用程序中,现在我在终端中得到两行请求输出。我已经检查过,它实际上并没有调用代码两次,我猜测 Puma 可能正在将请求信息与 Sinatra 一起输出。

作为演示,我创建了一个简单的应用程序,如下所示:

Gemfile

source 'https://rubygems.org'
ruby '2.2.0'

gem 'sinatra'
gem 'puma'

config.ru

require 'sinatra'

get '/' do
  'Hello World'
end

run Sinatra::Application

这是命令我运行:

rackup -s puma

这是我在浏览时收到的输出类型 http://localhost:9292/

R5001755:test louis.sayers$ rackup -s puma
Puma 2.11.3 starting...
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://localhost:9292
::1 - - [03/Jul/2015:21:46:37 +1000] "GET / HTTP/1.1" 200 11 0.0074
::1 - - [03/Jul/2015:21:46:37 +1000] "GET / HTTP/1.1" 200 11 0.0222

我上传了example project to github如果你想玩

对发生的事情有什么想法吗?感谢您的帮助!

这是由 CommonLogger middleware. It is added by both Rack (when using rackup) and by Sinatra (when logging is enabled), resulting in the duplicated output. Sinatra actually uses a custom subclass of this middleware 尝试解决此问题引起的。为了让它工作,它修补了原来的 CommonLogger class.

问题的出现是因为 Puma 还 defines its own version of CommonLogger 不包括 Sinatra 引入的更改。当在 Sinatra 之后加载 Puma 时,Puma 版本会覆盖补丁版本,因此会出现原始行为(重复的输出行)。

有几种方法可以解决此问题。您可以禁用 Sinatra 中的日志记录以防止添加重复的中间件。 Sinatra 日志记录设置适用于 CommonLoggerLogger middleware (which is what the logger helper 使用),因此您可能想自己添加 Logger 中间件:

disable :logging
use Rack::Logger

您还可以通过在 rackup 命令中使用 -q 选项来阻止 rackup 添加 CommonLogger 中间件:

$ rackup -q -s puma

另一种选择是确保 Puma 在 Sinatra 之前加载,这样当 Sinatra 打补丁时 CommonLogger 它正在打 Puma 版本并且补丁不会在以后被覆盖。您可以通过使用 rackup-r 选项强制它加载 Puma 来执行此操作:

$ rackup -s puma -r puma