client.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. // Make sure to include GRPC headers first because otherwise Abseil may create
  4. // ambiguity with `nostd::variant` if compiled with Visual Studio 2015. Other
  5. // modern compilers are unaffected.
  6. #include <grpcpp/grpcpp.h>
  7. #include <grpcpp/security/credentials.h>
  8. #include <grpcpp/support/status.h>
  9. #include <stdint.h>
  10. #include <stdlib.h>
  11. #include <iostream>
  12. #include <string>
  13. #include <utility>
  14. #include "opentelemetry/context/propagation/global_propagator.h"
  15. #include "opentelemetry/context/propagation/text_map_propagator.h"
  16. #include "opentelemetry/context/runtime_context.h"
  17. #include "opentelemetry/nostd/shared_ptr.h"
  18. #include "opentelemetry/trace/propagation/http_trace_context.h"
  19. #include "opentelemetry/trace/span.h"
  20. #include "opentelemetry/trace/span_metadata.h"
  21. #include "opentelemetry/trace/span_startoptions.h"
  22. #include "opentelemetry/trace/tracer.h"
  23. #ifdef BAZEL_BUILD
  24. # include "examples/grpc/protos/messages.grpc.pb.h"
  25. # include "examples/grpc/protos/messages.pb.h"
  26. #else
  27. # include "messages.grpc.pb.h"
  28. # include "messages.pb.h"
  29. #endif
  30. #include "opentelemetry/semconv/incubating/rpc_attributes.h"
  31. #include "opentelemetry/semconv/network_attributes.h"
  32. #include "tracer_common.h"
  33. using grpc::Channel;
  34. using grpc::ClientContext;
  35. using grpc::Status;
  36. using grpc_example::Greeter;
  37. using grpc_example::GreetRequest;
  38. using grpc_example::GreetResponse;
  39. namespace
  40. {
  41. namespace context = opentelemetry::context;
  42. namespace semconv = opentelemetry::semconv;
  43. using namespace opentelemetry::trace;
  44. class GreeterClient
  45. {
  46. public:
  47. GreeterClient(const std::shared_ptr<Channel> &channel) : stub_(Greeter::NewStub(channel)) {}
  48. std::string Greet(std::string ip, uint16_t port)
  49. {
  50. // Build gRPC Context objects and protobuf message containers
  51. GreetRequest request;
  52. GreetResponse response;
  53. ClientContext context;
  54. request.set_request("Nice to meet you!");
  55. StartSpanOptions options;
  56. options.kind = SpanKind::kClient;
  57. std::string span_name = "GreeterClient/Greet";
  58. auto span =
  59. get_tracer("grpc")->StartSpan(span_name,
  60. {{semconv::rpc::kRpcSystem, "grpc"},
  61. {semconv::rpc::kRpcService, "grpc-example.GreetService"},
  62. {semconv::rpc::kRpcMethod, "Greet"},
  63. {semconv::network::kNetworkPeerAddress, ip},
  64. {semconv::network::kNetworkPeerPort, port}},
  65. options);
  66. auto scope = get_tracer("grpc-client")->WithActiveSpan(span);
  67. // inject current context to grpc metadata
  68. auto current_ctx = context::RuntimeContext::GetCurrent();
  69. GrpcClientCarrier carrier(&context);
  70. auto prop = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
  71. prop->Inject(carrier, current_ctx);
  72. // Send request to server
  73. Status status = stub_->Greet(&context, request, &response);
  74. if (status.ok())
  75. {
  76. span->SetStatus(StatusCode::kOk);
  77. span->SetAttribute(semconv::rpc::kRpcGrpcStatusCode, status.error_code());
  78. // Make sure to end your spans!
  79. span->End();
  80. return response.response();
  81. }
  82. else
  83. {
  84. std::cout << status.error_code() << ": " << status.error_message() << '\n';
  85. span->SetStatus(StatusCode::kError);
  86. span->SetAttribute(semconv::rpc::kRpcGrpcStatusCode, status.error_code());
  87. // Make sure to end your spans!
  88. span->End();
  89. return "RPC failed";
  90. }
  91. }
  92. private:
  93. std::unique_ptr<Greeter::Stub> stub_;
  94. }; // GreeterClient class
  95. void RunClient(uint16_t port)
  96. {
  97. GreeterClient greeter(
  98. grpc::CreateChannel("0.0.0.0:" + std::to_string(port), grpc::InsecureChannelCredentials()));
  99. std::string response = greeter.Greet("0.0.0.0", port);
  100. std::cout << "grpc_server says: " << response << '\n';
  101. }
  102. } // namespace
  103. int main(int argc, char **argv)
  104. {
  105. InitTracer();
  106. // set global propagator
  107. context::propagation::GlobalTextMapPropagator::SetGlobalPropagator(
  108. opentelemetry::nostd::shared_ptr<context::propagation::TextMapPropagator>(
  109. new propagation::HttpTraceContext()));
  110. constexpr uint16_t default_port = 8800;
  111. uint16_t port;
  112. if (argc > 1)
  113. {
  114. port = atoi(argv[1]);
  115. }
  116. else
  117. {
  118. port = default_port;
  119. }
  120. RunClient(port);
  121. CleanupTracer();
  122. return 0;
  123. }