File: client.cc

package info (click to toggle)
opentelemetry-cpp 1.23.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,372 kB
  • sloc: cpp: 96,239; sh: 1,766; makefile: 36; python: 31
file content (142 lines) | stat: -rw-r--r-- 4,601 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

// Make sure to include GRPC headers first because otherwise Abseil may create
// ambiguity with `nostd::variant` if compiled with Visual Studio 2015. Other
// modern compilers are unaffected.
#include <grpcpp/grpcpp.h>
#include <grpcpp/security/credentials.h>
#include <grpcpp/support/status.h>

#include <stdint.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <utility>

#include "opentelemetry/context/context.h"
#include "opentelemetry/context/propagation/global_propagator.h"
#include "opentelemetry/context/propagation/text_map_propagator.h"
#include "opentelemetry/context/runtime_context.h"
#include "opentelemetry/nostd/shared_ptr.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/semconv/incubating/rpc_attributes.h"
#include "opentelemetry/semconv/network_attributes.h"
#include "opentelemetry/trace/propagation/http_trace_context.h"
#include "opentelemetry/trace/scope.h"
#include "opentelemetry/trace/span.h"
#include "opentelemetry/trace/span_metadata.h"
#include "opentelemetry/trace/span_startoptions.h"
#include "opentelemetry/trace/tracer.h"
#include "tracer_common.h"

#ifdef BAZEL_BUILD
#  include "examples/grpc/protos/messages.grpc.pb.h"
#  include "examples/grpc/protos/messages.pb.h"
#else
#  include "messages.grpc.pb.h"
#  include "messages.pb.h"
#endif

using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;

using grpc_example::Greeter;
using grpc_example::GreetRequest;
using grpc_example::GreetResponse;

namespace
{
namespace context = opentelemetry::context;
namespace semconv = opentelemetry::semconv;
using namespace opentelemetry::trace;
class GreeterClient
{
public:
  GreeterClient(const std::shared_ptr<Channel> &channel) : stub_(Greeter::NewStub(channel)) {}

  std::string Greet(std::string ip, uint16_t port)
  {
    // Build gRPC Context objects and protobuf message containers
    GreetRequest request;
    GreetResponse response;
    ClientContext context;
    request.set_request("Nice to meet you!");

    StartSpanOptions options;
    options.kind = SpanKind::kClient;

    std::string span_name = "GreeterClient/Greet";
    auto span =
        get_tracer("grpc")->StartSpan(span_name,
                                      {{semconv::rpc::kRpcSystem, "grpc"},
                                       {semconv::rpc::kRpcService, "grpc-example.GreetService"},
                                       {semconv::rpc::kRpcMethod, "Greet"},
                                       {semconv::network::kNetworkPeerAddress, ip},
                                       {semconv::network::kNetworkPeerPort, port}},
                                      options);

    auto scope = get_tracer("grpc-client")->WithActiveSpan(span);

    // inject current context to grpc metadata
    auto current_ctx = context::RuntimeContext::GetCurrent();
    GrpcClientCarrier carrier(&context);
    auto prop = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
    prop->Inject(carrier, current_ctx);

    // Send request to server
    Status status = stub_->Greet(&context, request, &response);
    if (status.ok())
    {
      span->SetStatus(StatusCode::kOk);
      span->SetAttribute(semconv::rpc::kRpcGrpcStatusCode, status.error_code());
      // Make sure to end your spans!
      span->End();
      return response.response();
    }
    else
    {
      std::cout << status.error_code() << ": " << status.error_message() << '\n';
      span->SetStatus(StatusCode::kError);
      span->SetAttribute(semconv::rpc::kRpcGrpcStatusCode, status.error_code());
      // Make sure to end your spans!
      span->End();
      return "RPC failed";
    }
  }

private:
  std::unique_ptr<Greeter::Stub> stub_;
};  // GreeterClient class

void RunClient(uint16_t port)
{
  GreeterClient greeter(
      grpc::CreateChannel("0.0.0.0:" + std::to_string(port), grpc::InsecureChannelCredentials()));
  std::string response = greeter.Greet("0.0.0.0", port);
  std::cout << "grpc_server says: " << response << '\n';
}
}  // namespace

int main(int argc, char **argv)
{
  InitTracer();
  // set global propagator
  context::propagation::GlobalTextMapPropagator::SetGlobalPropagator(
      opentelemetry::nostd::shared_ptr<context::propagation::TextMapPropagator>(
          new propagation::HttpTraceContext()));
  constexpr uint16_t default_port = 8800;
  uint16_t port;
  if (argc > 1)
  {
    port = static_cast<uint16_t>(atoi(argv[1]));
  }
  else
  {
    port = default_port;
  }
  RunClient(port);
  CleanupTracer();
  return 0;
}