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;
}
|