【问题标题】:Trace Error in Rack Middleware机架中间件中的跟踪错误
【发布时间】:2023-03-22 05:36:01
【问题描述】:

目前我还不能 100% 确定,但我相信我遇到了一个异常,导致请求状态以 401 响应。

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

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

如何确定问题发生在哪里?

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

【问题讨论】:

  • 您可以使用rake middleware 命令(guides.rubyonrails.org/…)查看中间件列表并调试执行...添加刹车点、日志记录等,对吗?
  • 谢谢,但我知道,我正在寻找一种将日志记录注入中间件的方法。

标签: ruby-on-rails ruby rack


【解决方案1】:

另一种方法是以下模块,它在 每个 中间件入口/返回处插入调试消息(每次返回后打印状态代码) (改编自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

【讨论】:

    【解决方案2】:

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

    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,您将需要修改记录器,以及如何配置中间件以运行。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 2013-01-02
      相关资源
      最近更新 更多