机架中间件中的跟踪错误

Trace Error in Rack Middleware

我现在不是 100% 确定,但我相信我遇到了一个异常,导致请求的状态以 401 响应。

我已经删除了控制器中的所有代码,但问题仍然存在,并且似乎为了 return 401 状态而捕获了异常,所以没有堆栈跟踪。

我已经创建了一个自定义中间件来尝试调试,但我仍然无法找到问题的根源。

如何确定问题发生的位置?

我们使用的是 heroku,所以 pry 似乎不起作用,我也没有命令行访问 运行 服务器。我无法在我的本地开发机器上复制该问题。

我从来不知道如何注入日志记录,但有点棘手的解决方法是创建一个额外的中间件,它可以在您需要的地方执行日志记录。

class Debugger
  def initialize(app, *args)
    @app = app
    @args = args
  end

  def call(env)
    Rails.logger.debug "executing app.call Debugger #{@args.first}"
    status, headers, body = @app.call(env)

    Rails.logger.debug "Status: #{status} after app.call Debugger #{@args.first}"
    [status, headers, body]
  end
end

然后在中间件堆栈中添加记录器,在 Rails 中,这将进入 config/application.rb:

config.middleware.insert_before Rack::Sendfile, "Debugger", "1"

这会导致 Rails 记录器添加

Executing app.call Debugger 1

然后执行Rack:Sendfile,日志:

Status: 400 after app.call Debugger 1

假设您正在使用 rails,并且 Rack::Sendfile 返回的状态代码返回了 400 状态代码。

请注意,如果您不使用 Rails。

,您将需要修改记录器,以及如何将中间件配置为 运行

这不是一个理想的解决方案,可能有更好的方法,但在撰写本文时我没有更好的方法。

另一种方法是以下模块,它在 each 中间件 entry/return 处插入一条调试消息(在每个 return 之后打印状态代码) (改编自 https://github.com/DataDog/dd-trace-rb/issues/368

# Trace each middleware module entry/exit. Freely adapted from
# https://github.com/DataDog/dd-trace-rb/issues/368 "Trace each middleware in the Rails stack"
module MiddlewareTracer
  def call(env)
    Rails.logger.debug { "MiddleWare: entry #{self.class.name}" }
    status, headers, response = super(env)
    Rails.logger.debug { "MiddleWare: #{self.class.name}, returning with status #{status}" }
    [status, headers, response]
  end
end

# Instrument the middleware stack after initialization so that we
# know the stack won't be changed afterwards.
Rails.configuration.after_initialize do
  Rails.application.middleware.each do |middleware|
    klass = middleware.klass

    # There are a few odd middlewares that aren't classes.
    klass.prepend(MiddlewareTracer) if klass.respond_to?(:prepend)
  end
end