你好。
我正在尝试让 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_headers
、 request_options
和response
数据。
因为,我不相信以前没有人注意到这一点,这可能是我犯了一些错误。 但是哪里?
@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_headers
和response_headers
。 那么为什么不跟随他们的领导......
或者,创建一个名为request_body
的第二个env
值,并将请求正文存储在env.request_body
和env.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 来构建签名,因此它使用响应体来构建签名。
当我在连接顶部定义适配器时,我的日志也是错误的,我认为我的签名脚本也是错误的。
最好的祝福!
最有用的评论
嗨@iMacTia ,我也遇到了这个问题。 我发现在记录器之前定义适配器时会重现该问题。
此代码日志请求正文:
这不: