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
|
#ifdef BAZEL_BUILD
# include "examples/grpc/protos/messages.grpc.pb.h"
#else
# include "messages.grpc.pb.h"
#endif
#include "opentelemetry/trace/context.h"
#include "opentelemetry/trace/experimental_semantic_conventions.h"
#include "opentelemetry/trace/span_context_kv_iterable_view.h"
#include "tracer_common.h"
#include <grpcpp/grpcpp.h>
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
#include <grpcpp/server_context.h>
#include <chrono>
#include <fstream>
#include <map>
#include <sstream>
#include <string>
#include <thread>
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::ServerWriter;
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
{
class GreeterServer final : public Greeter::Service
{
public:
Status Greet(ServerContext *context,
const GreetRequest *request,
GreetResponse *response) override
{
for (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,
{{OTEL_GET_TRACE_ATTR(AttrRpcSystem), "grpc"},
{OTEL_GET_TRACE_ATTR(AttrRpcService), "GreeterService"},
{OTEL_GET_TRACE_ATTR(AttrRpcMethod), "Greet"},
{OTEL_GET_TRACE_ATTR(AttrRpcGrpcStatusCode), 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");
std::string req = request->request();
std::cout << std::endl << "grpc_client says: " << req << std::endl;
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 << std::endl;
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 = atoi(argv[1]);
}
else
{
port = default_port;
}
RunServer(port);
return 0;
}
|