やあ。
0.9.2でリクエストとレスポンスの両方の本文を印刷しようとしています。
これは文書化されていませんが、#277PRで説明されています。
適切な設定をしたと思います。 Saorin経由でFaradayを使用しています。
<strong i="9">@client</strong> = Saorin::Client.new(:url => @endpoint) do |connection|
connection.response :logger, <strong i="10">@logger</strong>, :bodies => true
end
私の目には、デバッグ出力は要求本文を出力しませんが、応答本文を出力します(予期されていません)。
(そして、予想通り、応答本文を再度印刷します)。
だから私はログにそのようなsthを取得します:( 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]...
は適切な変数を出力しません。
そして、実際に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
はリクエストに対してグローバルであるため、呼び出しが行われる前にミドルウェアが同期して順番に実行されていると想定しないでください。
簡単な修正は、2つのenv
値を使用して本文を追跡することです。1つは要求用、もう1つは応答用です。
request_headers
とresponse_headers
の2つの個別の値があるため、ヘッダーにこのバグはありません。 だから、なぜ彼らの先導に従ってみませんか...
または、 request_body
という2番目のenv
値を作成し、リクエスト本文をenv.request_body
とenv.body
の両方に2回保存します。 そうすれば、既存の動作に依存するコードはそれを保持しますが、ここでのロギング関数などの更新されたコードは、存在する場合はrequest_body
を使用できます。
これがすぐにアップストリームで修正されない場合は、ファラデーにパッチを適用して自分のフォークを使用する可能性が非常に高くなります。 信頼性の低いロギングを行うことはできません...
@nthx 、見逃してしまったら申し訳ありませんが、どのロガーを使用していますか?
コードは正常に見えます。私が見ることができる唯一の「問題」は、メッセージの評価に使用されるprocにあります。 リクエストが処理された後に評価が行われない限り、これは通常問題にはなりません。
これが標準の(同期)ロガーで可能かどうかわからないので、どちらを使用しているか知りたいです:)
実際、この場合は自分のロガーを使用しています。 他のメッセージでも機能しているので、問題が発生する可能性はないと思いました。
標準のロガーで確認し、自分のロガーを再確認して、お知らせします。
こんにちは@nthx 、あなたのテストで運が良かったですか? 何か新しいことを発見しましたか?
この問題を閉じて、問題がファラデーにあるのかロガーにあるのかを理解したいと思います
標準のロガーをテストし、正常に動作しているので、障害がロガーにあると仮定して、これを閉じます。
@nthxは、考えられる原因としてファラデーを指摘する新しい証拠がある場合に備えて、自由に再開してください。
当時はファラデーの組み込みロガーを使用してこのバグがまだありましたが、ミドルウェアで独自のロガーを作成し、後でファラデーの使用からより単純なものに切り替えることで解決しました。
こんにちは@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に配置すると、ロガーアダプターに到達する前に要求が実行され、応答が2回ログに記録されます。
また、これに関する@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
理にかなっています。 まだもう一度確認することはできませんが、別の考えがあります...最初のレポートを読んだところ、次のように書かれています。
これは文書化されていませんが、#277PRで説明されています。
これは、応答のロギングを実際に構成する方法に関するドキュメントがないということですか?
ドキュメントがそこにあれば、それを行う方法に疑いの余地はありません。
ドキュメントを更新するためのチケットを作成していただけますか? それともこれを再開しますか?
また、誰がSaorinの人に連絡する必要がありますか?
こんにちは@nthxあなたは非常に正しいです私たちのドキュメントは現在十分に詳細ではありません(実際には、Readmeを「ドキュメント」として使用しています)。
あなたの特定のケースでは、 https://github.com/lostisland/faraday/blob/master/README.md#basic -useセクションにロガーミドルウェアの使用方法を示す3番目の例がありますが、それだけでは不十分であることに同意します。
近い将来、この種の問題を軽減するのに役立つWikiを刷新する予定です。
Saorinによると、失敗したコードの例を提供し、私のコメントを報告する問題を彼らのページで開くことをお勧めします。これは、問題を追跡するのに役立つはずです。
あなたが彼らの宝石を積極的に使用していて、彼らが必要とするかもしれないどんな追加情報も提供することができるので、私はあなたがこれをすることを好みます。
ありがとう
やあ、
私はこの問題を見たばかりで、私の要求がうまく署名されなかった理由を理解しています。
リクエストを行う前に署名を追加するミドルウェアを作成しました。
ミドルウェアを使用する前にアダプタを定義するため、認証ヘッダーを追加する前にリクエストが送信されました。
副作用として、ミドルウェアはenv.bodyを使用して署名を作成していたため、応答本文を使用して署名を作成していました。
接続の先頭でアダプターを定義していたので、ログも間違っていて、署名スクリプトも間違っていると思っていました。
よろしくお願いします!
最も参考になるコメント
こんにちは@iMacTia 、私もこの問題にこだわっています。 ロガーの前にアダプターを定義すると、問題が再現されることがわかりました。
このコードログリクエスト本文:
これはしません: