File: server.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 (143 lines) | stat: -rw-r--r-- 4,552 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
143
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#include <grpcpp/security/server_credentials.h>
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
#include <grpcpp/server_context.h>
#include <grpcpp/support/status.h>
#include <grpcpp/support/string_ref.h>
#include <stdint.h>
#include <stdlib.h>
#include <iostream>
#include <map>
#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/nostd/variant.h"
#include "opentelemetry/semconv/incubating/rpc_attributes.h"
#include "opentelemetry/trace/context.h"
#include "opentelemetry/trace/scope.h"
#include "opentelemetry/trace/span.h"
#include "opentelemetry/trace/span_context.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::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;

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

using Span        = opentelemetry::trace::Span;
using SpanContext = opentelemetry::trace::SpanContext;
using namespace opentelemetry::trace;

namespace context = opentelemetry::context;
namespace semconv = opentelemetry::semconv;

namespace
{
class GreeterServer final : public Greeter::Service
{
public:
  Status Greet(ServerContext *context,
               const GreetRequest *request,
               GreetResponse *response) override
  {
    for (const auto &elem : context->client_metadata())
    {
      std::cout << "ELEM: " << elem.first << " " << elem.second << "\n";
    }

    // Create a SpanOptions object and set the kind to Server to inform OpenTel.
    StartSpanOptions options;
    options.kind = SpanKind::kServer;

    // extract context from grpc metadata
    GrpcServerCarrier carrier(context);

    auto prop        = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
    auto current_ctx = context::RuntimeContext::GetCurrent();
    auto new_context = prop->Extract(carrier, current_ctx);
    options.parent   = GetSpan(new_context)->GetContext();

    std::string span_name = "GreeterService/Greet";
    auto span             = get_tracer("grpc")->StartSpan(span_name,
                                                          {{semconv::rpc::kRpcSystem, "grpc"},
                                                           {semconv::rpc::kRpcService, "GreeterService"},
                                                           {semconv::rpc::kRpcMethod, "Greet"},
                                                           {semconv::rpc::kRpcGrpcStatusCode, 0}},
                                                          options);
    auto scope            = get_tracer("grpc")->WithActiveSpan(span);

    // Fetch and parse whatever HTTP headers we can from the gRPC request.
    span->AddEvent("Processing client attributes");

    const std::string &req = request->request();
    std::cout << '\n' << "grpc_client says: " << req << '\n';
    std::string message = "The pleasure is mine.";
    // Send response to client
    response->set_response(message);
    span->AddEvent("Response sent to client");

    span->SetStatus(StatusCode::kOk);
    // Make sure to end your spans!
    span->End();
    return Status::OK;
  }
};  // GreeterServer class

void RunServer(uint16_t port)
{
  std::string address("0.0.0.0:" + std::to_string(port));
  GreeterServer service;
  ServerBuilder builder;

  builder.RegisterService(&service);
  builder.AddListeningPort(address, grpc::InsecureServerCredentials());

  std::unique_ptr<Server> server(builder.BuildAndStart());
  std::cout << "Server listening on port: " << address << '\n';
  server->Wait();
  server->Shutdown();
}
}  // namespace

int main(int argc, char **argv)
{
  InitTracer();
  constexpr uint16_t default_port = 8800;
  uint16_t port;
  if (argc > 1)
  {
    port = static_cast<uint16_t>(atoi(argv[1]));
  }
  else
  {
    port = default_port;
  }

  RunServer(port);
  CleanupTracer();
  return 0;
}