简体   繁体   English

机架中间件中的跟踪错误

[英]Trace Error in Rack Middleware

I'm not 100% sure at this point, but I believe I'm getting an exception that is causing the status of a request to respond with a 401. 我此时并不是100%肯定,但我相信我得到的异常导致请求的状态以401响应。

I've eliminated all the code in the controller, and the issue still happens, and something seems to be catching the exception in order to return the 401 status, so there's no stack trace. 我已经删除了控制器中的所有代码,问题仍然存在,并且似乎正在捕获异常,以便返回401状态,因此没有堆栈跟踪。

I've created a custom middleware to try and debug, but I still haven't been able to get to the source of the issue. 我已经创建了一个自定义中间件来尝试和调试,但我仍然无法找到问题的根源。

How can I isolate where the issue is happening? 如何找出问题所在?

We are using heroku, so pry doesn't seem to work, nor do I have command line access to the running server. 我们正在使用heroku,所以pry似乎不起作用,也没有命令行访问正在运行的服务器。 I've not been able to replicate the issue on my local dev machine. 我无法在我的本地开发机器上复制该问题。

I never found out how to inject logging, but a bit of a hacky workaround is to create an additional middleware, which can perform logging where you want it. 我从来没有发现如何注入日志记录,但是一些hacky解决方法是创建一个额外的中间件,它可以在你想要的地方执行日志记录。

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

and then adding the logger where you want in the middleware stack, in Rails this would go in config/application.rb : 然后在Rails中将logger添加到中间件堆栈中,这将放在config/application.rb

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

which would cause the Rails logger to add 这将导致Rails记录器添加

Executing app.call Debugger 1

Then execute Rack:Sendfile, and the log: 然后执行Rack:Sendfile和日志:

Status: 400 after app.call Debugger 1

Assuming you are using rails, and the status code returned by Rack::Sendfile returned a 400 status code. 假设您正在使用rails,并且Rack :: Sendfile返回的状态代码返回了400状态代码。

Note, you will need to modify the logger, and how you are configuring the middleware to run if you are not using Rails. 注意,如果不使用Rails,则需要修改记录器以及如何配置要运行的中间件。

This is not an ideal solution, there's probably a better way to do it, but at the time of writing I don't have a better one. 这不是一个理想的解决方案,可能有更好的方法,但在撰写本文时我没有更好的解决方案。

An alternative is the following module which inserts a debug message at each middleware entry/return (with the status code printed after each return) (adapted from https://github.com/DataDog/dd-trace-rb/issues/368 ) 另一种方法是下面的模块,它在每个中间件入口/返回处插入一个调试消息(每次返回后打印状态代码)(改编自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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM