2
0

server.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include "server.h"
  4. #include "opentelemetry/semconv/client_attributes.h"
  5. #include "opentelemetry/semconv/incubating/http_attributes.h"
  6. #include "opentelemetry/semconv/server_attributes.h"
  7. #include "opentelemetry/semconv/url_attributes.h"
  8. #include "opentelemetry/trace/context.h"
  9. #include "tracer_common.h"
  10. #include <iostream>
  11. #include <thread>
  12. namespace
  13. {
  14. using namespace opentelemetry::trace;
  15. namespace context = opentelemetry::context;
  16. namespace semconv = opentelemetry::semconv;
  17. uint16_t server_port = 8800;
  18. constexpr const char *server_name = "localhost";
  19. class RequestHandler : public HTTP_SERVER_NS::HttpRequestCallback
  20. {
  21. public:
  22. int onHttpRequest(HTTP_SERVER_NS::HttpRequest const &request,
  23. HTTP_SERVER_NS::HttpResponse &response) override
  24. {
  25. StartSpanOptions options;
  26. options.kind = SpanKind::kServer; // server
  27. std::string span_name = request.uri;
  28. // extract context from http header
  29. std::map<std::string, std::string> &request_headers =
  30. const_cast<std::map<std::string, std::string> &>(request.headers);
  31. const HttpTextMapCarrier<std::map<std::string, std::string>> carrier(request_headers);
  32. auto prop = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
  33. auto current_ctx = context::RuntimeContext::GetCurrent();
  34. auto new_context = prop->Extract(carrier, current_ctx);
  35. options.parent = GetSpan(new_context)->GetContext();
  36. // start span with parent context extracted from http header
  37. auto span = get_tracer("http-server")
  38. ->StartSpan(span_name,
  39. {{semconv::server::kServerAddress, server_name},
  40. {semconv::server::kServerPort, server_port},
  41. {semconv::http::kHttpRequestMethod, request.method},
  42. {semconv::url::kUrlScheme, "http"},
  43. {semconv::http::kHttpRequestBodySize,
  44. static_cast<uint64_t>(request.content.length())},
  45. {semconv::client::kClientAddress, request.client}},
  46. options);
  47. auto scope = get_tracer("http_server")->WithActiveSpan(span);
  48. for (auto &kv : request.headers)
  49. {
  50. span->SetAttribute("http.header." + std::string(kv.first.data()), kv.second);
  51. }
  52. if (request.uri == "/helloworld")
  53. {
  54. span->AddEvent("Processing request");
  55. response.headers[HTTP_SERVER_NS::CONTENT_TYPE] = HTTP_SERVER_NS::CONTENT_TYPE_TEXT;
  56. span->End();
  57. return 200;
  58. }
  59. span->End();
  60. return 404;
  61. }
  62. };
  63. } // namespace
  64. int main(int argc, char *argv[])
  65. {
  66. InitTracer();
  67. // The port the validation service listens to can be specified via the command line.
  68. if (argc > 1)
  69. {
  70. server_port = static_cast<uint16_t>(atoi(argv[1]));
  71. }
  72. HttpServer http_server(server_name, server_port);
  73. RequestHandler req_handler;
  74. http_server.AddHandler("/helloworld", &req_handler);
  75. auto root_span = get_tracer("http_server")->StartSpan(__func__);
  76. Scope scope(root_span);
  77. http_server.Start();
  78. std::cout << "Server is running..Press ctrl-c to exit...\n";
  79. while (1)
  80. {
  81. std::this_thread::sleep_for(std::chrono::seconds(100));
  82. }
  83. http_server.Stop();
  84. root_span->End();
  85. CleanupTracer();
  86. return 0;
  87. }