Faraday: Tentando registrar o corpo da solicitação, ele registra a resposta

Criado em 14 jul. 2016  ·  14Comentários  ·  Fonte: lostisland/faraday

Oi.

Estou tentando fazer 0.9.2 imprimir os corpos de solicitação e resposta.
Isso não está documentado, mas discutido no PR #277.
Acho que fiz a configuração adequada. Estou usando Faraday via Saorin ..

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

A meu ver, a saída de depuração não imprime o corpo da solicitação , mas imprime o corpo da resposta (não esperado).
(e segue a impressão do corpo da resposta novamente, como esperado).

Então eu recebo algo assim no log: (observe o valor para request . É duplicado de response na verdade.

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"}

Verifique este código de 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

Se eu li corretamente, a linha: debug('request') { dump_body(env[:body]... não imprime a var apropriada.

E, na verdade, inspecionando env[] , não consigo encontrar o corpo da solicitação em nenhum lugar :-( Apenas request_headers , request_options e response dados.

Já que não acredito que ninguém tenha notado isso antes, provavelmente eu cometi algum erro. Mas onde?

unconfirmed

Comentários muito úteis

Oi @iMacTia , também fiquei com esse problema. Eu encontrei esse problema reproduzido quando você define o adaptador antes do logger.

Este corpo de solicitação de log de código:

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

Isso não:

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

Todos 14 comentários

@nthx Estou vendo isso também ..

@stve - o relatório faz sentido para você?

talvez precise de configuração de solicitação também? Mas não tentei isso..

<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

É uma condição de corrida padrão, eu acho. O que está acontecendo aqui é que env[:body] já foi definido para o corpo da solicitação. Mas no momento em que o método de log ou dump_body é executado, o corpo da resposta substituiu o corpo da solicitação dentro env[:body] e nenhuma outra variável/cópia é feita do corpo da solicitação original, não que isso necessariamente conserte as coisas. env é global para a solicitação, não devemos assumir que o middleware está sendo executado de forma síncrona e em ordem antes da chamada ser feita.

Uma solução fácil seria usar dois valores env para rastrear corpos, um para solicitação e outro para resposta.

Não temos esse bug com cabeçalhos porque existem dois valores separados: request_headers e response_headers . Então, por que não seguir o exemplo deles...

Como alternativa, crie um segundo env chamado request_body e armazene o corpo da solicitação duas vezes em env.request_body e env.body . Dessa forma, qualquer código que dependa do comportamento existente o mantém, mas o código atualizado, como nossa função de registro aqui, pode usar request_body se existir.

Se isso não for corrigido no upstream em breve, provavelmente vou corrigir Faraday e usar meu próprio fork. Eu não posso ter log não confiável ...

@nthx , desculpe se eu perdi, mas qual registrador você está usando?
O código parece bom, o único "problema" que posso ver é com os procs usados ​​para avaliar a mensagem. Isso geralmente não é um problema, a menos que sua avaliação ocorra APÓS o processamento da solicitação.
Não tenho certeza se isso é possível com o registrador padrão (síncrono), então gostaria de saber qual você está usando :)

Na verdade, estou usando meu próprio registrador neste caso. Funcionou para outras mensagens, então não achei que pudesse causar um problema.
Vou verificar com o registrador padrão e verificar novamente o meu, e informá-lo.

Oi @nthx , alguma sorte com seus testes? Descobriu algo novo?
Gostaria de encerrar este assunto e entender se o problema está no Faraday ou no logger

Vou fechar isso assumindo que a falha está no registrador, pois testei o padrão e está funcionando bem para mim.

@nthx sinta-se à vontade para reabrir caso tenha alguma nova evidência apontando para Faraday como a possível causa

Eu ainda tinha esse bug, usando o Logger embutido do Faraday na época, mas resolvi isso escrevendo meu próprio logger no middleware e, mais tarde, mudando o uso do Faraday para algo mais simples.

Oi @iMacTia , também fiquei com esse problema. Eu encontrei esse problema reproduzido quando você define o adaptador antes do logger.

Este corpo de solicitação de log de código:

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

Isso não:

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

Olá @llxff ,

sim, isso é esperado, pois a ordem dos middlewares é crítica e o adaptador deve estar sempre na parte inferior.
Se você colocar o adaptador ANTES, o pedido será executado antes que o adaptador do registrador seja alcançado, fazendo com que a resposta seja registrada duas vezes.
Além disso, agora estou lendo o problema @nthx com isso e percebi que ele está perdendo o adaptador em sua pilha de middlewares:

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

Eu também verifiquei o código em Saorin gem e parece completamente errado pelo mesmo motivo exato: https://github.com/mashiro/saorin/blob/master/lib/saorin/client/faraday. rb#L16

Faz sentido. Ainda não posso verificá-lo novamente, mas pense em outra coisa... Li meu relatório inicial e ele diz:

Isso não está documentado, mas discutido no PR #277.

Este ainda é o caso, que não há documentação sobre como realmente configurar o registro de respostas?
Se os documentos estivessem lá, então não haveria dúvidas sobre como fazê-lo.

Você pode criar um ticket para atualizar os documentos? Ou reabrir este talvez?

Além disso - quem deve entrar em contato com os caras do Saorin?

Oi @nthx , você está certo, nossa documentação atualmente não é detalhada o suficiente (na verdade, estamos usando o Leiame como uma "documentação").
No seu caso específico, há o terceiro exemplo na seção https://github.com/lostisland/faraday/blob/master/README.md#basic -use que mostra como usar o middleware do logger, mas concordo que não é suficiente .
Estamos planejando ter um Wiki renovado em um futuro próximo, o que deve ajudar a mitigar esse tipo de problema.

De acordo com Saorin, sugiro que você abra um problema em sua página fornecendo exemplos com o código com falha e relatando meu comentário, o que deve ajudá-los a rastrear o problema.
Eu prefiro que você faça isso porque você está usando ativamente a gem deles e, no entanto, poderá fornecer qualquer informação adicional que eles possam precisar.

Obrigado

Oi,

Acabei de ver esse problema e entendo por que minha solicitação não foi bem assinada.

Criamos um middleware que adiciona uma assinatura antes de fazer a solicitação.
Como definimos o adaptador antes de usar o middleware, a solicitação foi enviada antes de adicionar o cabeçalho de autorização.

O efeito colateral era que o middleware estava usando o env.body para construir a assinatura e então estava usando o corpo de resposta para construir a assinatura.

Como eu estava definindo o adaptador no topo da conexão, meus logs também estavam errados e eu estava pensando que meu script de assinatura também estava errado.

Atenciosamente!

Esta página foi útil?
0 / 5 - 0 avaliações