Faraday: 尝试记录请求正文,而是记录响应

创建于 2016-07-14  ·  14评论  ·  资料来源: lostisland/faraday

你好。

我正在尝试让 0.9.2 打印请求和响应正文。
这没有记录,但在 #277 PR 中进行了讨论。
我想,我已经进行了正确的设置。 我正在通过 Saorin 使用法拉第 ..

  <strong i="9">@client</strong> = Saorin::Client.new(:url => @endpoint) do |connection|
    connection.response :logger, <strong i="10">@logger</strong>, :bodies => true
  end

在我看来,调试输出不打印请求正文,而是打印响应正文(不是预期的)。
(正如预期的那样,它再次跟随打印响应正文)。

所以我在日志中得到这样的东西:(注意request的值。它实际上是response的副本。

post https://foo.bar.com/api/3.0/json-rpc
request User-Agent: "Faraday v0.9.2"
Content-Type: "application/json"
request {"result":{"accessGranted":false},"id":"foo","jsonrpc":"2.0"}
Status 200
response server: "nginx"
date: "Thu, 14 Jul 2016 21:28:21 GMT"
content-type: "application/json"
transfer-encoding: "chunked"
connection: "close"
response {"result":{"accessGranted":false},"id":"foo","jsonrpc":"2.0"}

检查faraday/response/logger.rb的代码:

    def call(env)
      info "#{env.method} #{env.url.to_s}"
      debug('request') { dump_headers env.request_headers }
      debug('request') { dump_body(env[:body]) } if env[:body] && log_body?(:request)
      super
    end

    def on_complete(env)
      info('Status') { env.status.to_s }
      debug('response') { dump_headers env.response_headers }
      debug('response') { dump_body env[:body] } if env[:body] && log_body?(:response)
    end

如果我没看错,行: debug('request') { dump_body(env[:body]...打印的不是正确的 var。

而且,实际上检查env[] ,我无法在任何地方找到请求正文 :-( 只有request_headersrequest_optionsresponse数据。

因为,我不相信以前没有人注意到这一点,这可能是我犯了一些错误。 但是哪里?

unconfirmed

最有用的评论

@iMacTia ,我也遇到了这个问题。 我发现在记录器之前定义适配器时会重现该问题。

此代码日志请求正文:

Faraday.new(url: url) do |faraday|
  faraday.response :logger, ::Logger.new(STDOUT), bodies: true
  faraday.adapter Faraday.default_adapter
end

这不:

Faraday.new(url: url) do |faraday|
  faraday.adapter Faraday.default_adapter
  faraday.response :logger, ::Logger.new(STDOUT), bodies: true
end

所有14条评论

@nthx我也看到了这个..

@stve - 该报告对您​​有意义吗?

也许它也需要请求配置? 不过没试过。。

<strong i="6">@client</strong> = Saorin::Client.new(:url => @endpoint) do |connection|
  connection.response :logger, <strong i="7">@logger</strong>, :bodies => true
  connection.request :logger, <strong i="8">@logger</strong>, :bodies => true
end

我认为这是一个标准的比赛条件。 这里发生的是env[:body]曾经设置为请求的正文。 但是当 log 方法或 dump_body 执行时,响应正文已经替换了env[:body]中的请求正文,并且原始请求正文没有进一步的变量/副本,并不是说它一定会解决问题。 env对请求来说是全局的,我们不应该假设中间件在调用之前是按顺序同步执行的。

一个简单的解决方法是使用两个env值来跟踪正文,一个用于请求,一个用于响应。

我们没有这个带有标题的错误,因为那里有两个单独的值: request_headersresponse_headers 。 那么为什么不跟随他们的领导......

或者,创建一个名为request_body的第二个env值,并将请求正文存储在env.request_bodyenv.body中两次。 这样,任何依赖于现有行为的代码都会保留它,但更新的代码(例如我们这里的日志记录函数)可以使用request_body (如果存在)。

如果这不能很快在上游得到修复,我很可能会修补 Faraday 并使用我自己的分叉。 我不能有不可靠的日志记录...

@nthx ,如果我错过了,很抱歉,但是您使用的是哪个记录器?
代码看起来不错,我能看到的唯一“问题”是用于评估消息的 procs。 这通常不是问题,除非在处理请求之后进行评估。
我不确定标准(同步)记录器是否可行,所以我想知道您使用的是哪一个:)

实际上,在这种情况下,我一直在使用自己的记录器。 它适用于其他消息,所以我认为它不会引起问题。
我将使用标准记录器进行验证并重新检查我自己的,并让您知道。

@nthx ,你的测试运气好吗? 你有没有发现什么新东西?
我想关闭这个问题并了解问题出在法拉第还是记录器上

假设故障出在记录器上,我将关闭它,因为我测试了标准记录器并且对我来说工作正常。

@nthx如果您有任何新证据表明法拉第是可能的原因,请随时重新打开

我仍然有这个错误,当时使用的是 Faraday 内置的 Logger,但我通过在中间件中编写自己的 logger 来解决它,后来又从使用 Faraday 切换到更简单的东西。

@iMacTia ,我也遇到了这个问题。 我发现在记录器之前定义适配器时会重现该问题。

此代码日志请求正文:

Faraday.new(url: url) do |faraday|
  faraday.response :logger, ::Logger.new(STDOUT), bodies: true
  faraday.adapter Faraday.default_adapter
end

这不:

Faraday.new(url: url) do |faraday|
  faraday.adapter Faraday.default_adapter
  faraday.response :logger, ::Logger.new(STDOUT), bodies: true
end

@llxff

是的,这是预期的,因为中间件的顺序很关键,适配器应该始终位于底部。
如果将适配器放在 BEFORE 之前,则请求将在到达记录器适配器之前执行,导致响应被记录两次。
另外,我现在正在阅读@nthx问题,我刚刚意识到他在他的中间件堆栈中缺少适配器:

<strong i="11">@client</strong> = Saorin::Client.new(:url => @endpoint) do |connection|
    connection.response :logger, <strong i="12">@logger</strong>, :bodies => true
  end

我还检查了Saorin gem 中的代码,由于同样的原因,它看起来完全错误: https://github.com/mashiro/saorin/blob/master/lib/saorin/client/faraday。 rb#L16

说得通。 我还不能再次验证它,但有另一个想法......我已经阅读了我的初始报告,它说:

这没有记录,但在 #277 PR 中进行了讨论。

仍然是这种情况,没有关于如何实际配置响应日志记录的文档?
如果文档在那里,那么毫无疑问如何去做。

您能否创建一张票以更新文档? 或者重新打开这个可能?

另外 - 谁应该联系 Saorin 家伙?

@nthx ,您说得非常对,我们的文档目前还不够详细(实际上,我们将自述文件用作“文档”)。
在您的具体情况下, https://github.com/lostisland/faraday/blob/master/README.md#basic -use 部分中的第三个示例显示了如何使用记录器中间件,但我同意这还不够.
我们计划在不久的将来修改 Wiki,这将有助于缓解此类问题。

按照 Saorin 的说法,我建议您在他们的页面上打开一个问题,提供包含失败代码的示例并报告我的评论,这应该有助于他们追踪问题。
我更喜欢您这样做,因为您正在积极使用他们的 gem,尽管能够提供他们可能需要的任何其他信息。

谢谢

你好,

我刚刚看到了这个问题,我理解为什么我的请求没有得到很好的签名。

我们创建了一个在发出请求之前添加签名的中间件。
由于我们在使用中间件之前定义了适配器,因此请求是在添加授权标头之前发送的。

副作用是中间件使用 env.body 来构建签名,因此它使用响应体来构建签名。

当我在连接顶部定义适配器时,我的日志也是错误的,我认为我的签名脚本也是错误的。

最好的祝福!

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

JasonBarnabe picture JasonBarnabe  ·  4评论

amrrbakry picture amrrbakry  ·  4评论

mattmill30 picture mattmill30  ·  4评论

jedeleh picture jedeleh  ·  3评论

subvertallchris picture subvertallchris  ·  5评论