简体   繁体   English

您如何读取/记录 gRPC HTTP 标头(不是自定义元数据)?

[英]How do you read/log gRPC HTTP headers (not custom metadata)?

I am working with gRPC and Protobuf, using a C++ server and a C++ client, as well as a grpc-js client.我正在使用 gRPC 和 Protobuf,使用 C++ 服务器和 C++ 客户端以及 grpc-js 客户端。 Is there a way to get a read on all of the HTTP request/response headers from the transport layer in gRPC?有没有办法从 gRPC 的传输层读取所有 HTTP 请求/响应标头? I am looking for the sort of typical client/server HTTP headers - particularly, I would like to see what version of the protocol is being used (whether it is HTTP1.1/2).我正在寻找那种典型的客户端/服务器 HTTP 标头 - 特别是,我想看看正在使用什么版本的协议(无论是 HTTP1.1/2)。 I know that gRPC is supposed to be using HTTP2, but I am trying to confirm it at a low level.我知道 gRPC 应该使用 HTTP2,但我试图在低级别确认它。

In a typical gRPC client implementation you have something like this:在一个典型的 gRPC 客户端实现中,你有这样的东西:

class PingPongClient {
 public:
  PingPongClient(std::shared_ptr<Channel> channel)
      : stub_(PingPong::NewStub(channel)) {}

  // Assembles the client's payload, sends it and presents the response back
  // from the server.
  PingPongReply PingPong(PingPongRequest request) {
    // Container for the data we expect from the server.
    PingPongReply reply;

    // Context for the client. It could be used to convey extra information to
    // the server and/or tweak certain RPC behaviors.
    ClientContext context;

    // The actual RPC.
    Status status = stub_->Ping(&context, request, &reply);

    // Act upon its status.
    if (status.ok()) {
        return reply;
    } else {
      auto errorMsg = status.error_code() + ": " + status.error_message();
      std::cout << errorMsg << std::endl;
      throw std::runtime_error(errorMsg);
    }
  }

 private:
  std::unique_ptr<PingPong::Stub> stub_;
};

and on the serverside, something like:在服务器端,类似:

class PingPongServiceImpl final : public PingPong::Service {
  Status Ping(
    ServerContext* context,
    const PingPongRequest* request,
    PingPongReply* reply
  ) override {
    std::cout << "PingPong" << std::endl;
    printContextClientMetadata(context->client_metadata());

    if (request->input_msg() == "hello") {
      reply->set_output_msg("world");
    } else {
      reply->set_output_msg("I can't pong unless you ping me 'hello'!");
    }

    std::cout << "Replying with " << reply->output_msg() << std::endl;

    return Status::OK;
  }
};

I would think that either ServerContext or the request object might have access to this information, but context seems to only provide an interface into metadata, which is custom.我认为 ServerContext 或请求 object 可能有权访问此信息,但上下文似乎只提供了一个自定义元数据的接口。

None of the gRPC C++ examples give any indication that there is such an API, nor do any of the associated source/header files in the gRPC source code . gRPC C++ 示例没有任何迹象表明存在这样的 API, gRPC 源代码中的任何相关源/头文件也没有。 I have exhausted my options here in terms of tutorials, blog posts, videos, and documentation - I asked a similar question on the grpc-io forum, but have gotten no takers.在教程、博客文章、视频和文档方面,我已经用尽了我的选择——我在 grpc-io 论坛上问了一个类似的问题,但没有得到任何人。 Hoping the SO crew has some insights here!希望SO工作人员在这里有一些见解!

I should also note that I experimented with passing a variety of environment variables as flags to the running processes to see if I can get details about HTTP headers, but even with these flags enabled (the HTTP-related ones), I do not see basic HTTP headers.我还应该注意,我尝试将各种环境变量作为标志传递给正在运行的进程,以查看是否可以获得有关 HTTP 标头的详细信息,但即使启用了这些标志(与 HTTP 相关的标志),我也看不到基本的HTTP 接头。

First, the gRPC libraries absolutely do use HTTP/2.首先,gRPC 库绝对使用 HTTP/2。 The protocol is explicitly defined in terms of HTTP/2 . 该协议是根据 HTTP/2 明确定义的

The gRPC libraries do not directly expose the raw HTTP headers to the application. gRPC 库不会直接向应用程序公开原始 HTTP 标头。 However, they do have trace logging options that can log a variety of information for debugging purposes, including headers.但是,它们确实具有跟踪日志记录选项,可以记录各种用于调试目的的信息,包括标头。 The tracers can be enabled by setting the environment variable GRPC_TRACE .可以通过设置环境变量GRPC_TRACE来启用跟踪器。 The environment variable GRPC_VERBOSITY=DEBUG should also be set to make sure that all of the logs are output.还应设置环境变量GRPC_VERBOSITY=DEBUG以确保所有日志都是 output。 More information can be found in this document describing how the library uses envinronment variables.可以在描述库如何使用环境变量的文档中找到更多信息。

In the C++ library, the http tracer should log the raw headers.在 C++ 库中, http跟踪器应记录原始标头。 The grpc-js library has different internals and different tracer definitions, so you should use the call_stream tracer for that one. grpc-js 库具有不同的内部结构和不同的跟踪器定义,因此您应该使用call_stream跟踪器。 Those will also log other request information, but it should be pretty easy to pick out the headers.这些也会记录其他请求信息,但应该很容易挑选出标题。

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

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