From 787d9c19088c8cd0eea19f4d920a498888fcc41d Mon Sep 17 00:00:00 2001 From: WenTao Ou Date: Thu, 6 Oct 2022 06:15:21 +0800 Subject: [PATCH] Add user agent for OTLP http/grpc client (#1657) --- .../exporters/otlp/otlp_environment.h | 6 ++++++ .../exporters/otlp/otlp_grpc_exporter_options.h | 2 ++ .../exporters/otlp/otlp_http_client.h | 9 +++++++-- exporters/otlp/src/otlp_grpc_client.cc | 8 ++++++-- exporters/otlp/src/otlp_http_client.cc | 1 + exporters/otlp/test/otlp_http_exporter_test.cc | 14 ++++++++++++++ 6 files changed, 36 insertions(+), 4 deletions(-) diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h index 787f852442a..27bd378b7c4 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h @@ -8,6 +8,7 @@ #include "opentelemetry/sdk/common/attribute_utils.h" #include "opentelemetry/sdk/common/env_variables.h" +#include "opentelemetry/sdk/version/version.h" #include #include @@ -21,6 +22,11 @@ namespace exporter namespace otlp { +inline const std::string GetOtlpDefaultUserAgent() +{ + return "OTel-OTLP-Exporter-Cpp/" OPENTELEMETRY_SDK_VERSION; +} + inline const std::string GetOtlpDefaultGrpcEndpoint() { constexpr char kOtlpTracesEndpointEnv[] = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"; diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h index c62a0f0af9a..664ee2934bd 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h @@ -32,6 +32,8 @@ struct OtlpGrpcExporterOptions std::chrono::system_clock::duration timeout = GetOtlpDefaultTimeout(); // Additional HTTP headers OtlpHeaders metadata = GetOtlpDefaultHeaders(); + // User agent + std::string user_agent = GetOtlpDefaultUserAgent(); }; } // namespace otlp diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_client.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_client.h index e5102c6ca0a..bf154b23a05 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_client.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_client.h @@ -72,6 +72,9 @@ struct OtlpHttpClientOptions // Requests per connections std::size_t max_requests_per_connection = 8; + // User agent + std::string user_agent = GetOtlpDefaultUserAgent(); + inline OtlpHttpClientOptions(nostd::string_view input_url, HttpRequestContentType input_content_type, JsonBytesMappingKind input_json_bytes_mapping, @@ -80,7 +83,8 @@ struct OtlpHttpClientOptions std::chrono::system_clock::duration input_timeout, const OtlpHeaders &input_http_headers, std::size_t input_concurrent_sessions = 64, - std::size_t input_max_requests_per_connection = 8) + std::size_t input_max_requests_per_connection = 8, + nostd::string_view input_user_agent = GetOtlpDefaultUserAgent()) : url(input_url), content_type(input_content_type), json_bytes_mapping(input_json_bytes_mapping), @@ -89,7 +93,8 @@ struct OtlpHttpClientOptions timeout(input_timeout), http_headers(input_http_headers), max_concurrent_requests(input_concurrent_sessions), - max_requests_per_connection(input_max_requests_per_connection) + max_requests_per_connection(input_max_requests_per_connection), + user_agent(input_user_agent) {} }; diff --git a/exporters/otlp/src/otlp_grpc_client.cc b/exporters/otlp/src/otlp_grpc_client.cc index ede5ca892da..158f2760006 100644 --- a/exporters/otlp/src/otlp_grpc_client.cc +++ b/exporters/otlp/src/otlp_grpc_client.cc @@ -55,6 +55,8 @@ std::shared_ptr OtlpGrpcClient::MakeChannel(const OtlpGrpcExporte } std::string grpc_target = url.host_ + ":" + std::to_string(static_cast(url.port_)); + grpc::ChannelArguments grpc_arguments; + grpc_arguments.SetUserAgentPrefix(options.user_agent); if (options.use_ssl_credentials) { @@ -67,11 +69,13 @@ std::shared_ptr OtlpGrpcClient::MakeChannel(const OtlpGrpcExporte { ssl_opts.pem_root_certs = GetFileContents((options.ssl_credentials_cacert_path).c_str()); } - channel = grpc::CreateChannel(grpc_target, grpc::SslCredentials(ssl_opts)); + channel = + grpc::CreateCustomChannel(grpc_target, grpc::SslCredentials(ssl_opts), grpc_arguments); } else { - channel = grpc::CreateChannel(grpc_target, grpc::InsecureChannelCredentials()); + channel = + grpc::CreateCustomChannel(grpc_target, grpc::InsecureChannelCredentials(), grpc_arguments); } return channel; diff --git a/exporters/otlp/src/otlp_http_client.cc b/exporters/otlp/src/otlp_http_client.cc index 9833d70d0a2..b64ebb16d14 100644 --- a/exporters/otlp/src/otlp_http_client.cc +++ b/exporters/otlp/src/otlp_http_client.cc @@ -966,6 +966,7 @@ OtlpHttpClient::createSession( request->SetMethod(http_client::Method::Post); request->SetBody(body_vec); request->ReplaceHeader("Content-Type", content_type); + request->ReplaceHeader("User-Agent", options_.user_agent); // Returns the created session data return HttpSessionData{ diff --git a/exporters/otlp/test/otlp_http_exporter_test.cc b/exporters/otlp/test/otlp_http_exporter_test.cc index e3152ff3ab4..35ae5f50d79 100644 --- a/exporters/otlp/test/otlp_http_exporter_test.cc +++ b/exporters/otlp/test/otlp_http_exporter_test.cc @@ -163,6 +163,13 @@ class OtlpHttpExporterTestPeer : public ::testing::Test EXPECT_EQ("Custom-Header-Value", custom_header->second); } + auto user_agent_header = mock_session->GetRequest()->headers_.find("User-Agent"); + ASSERT_TRUE(user_agent_header != mock_session->GetRequest()->headers_.end()); + if (user_agent_header != mock_session->GetRequest()->headers_.end()) + { + EXPECT_EQ(GetOtlpDefaultUserAgent(), user_agent_header->second); + } + // let the otlp_http_client to continue http_client::nosend::Response response; response.Finish(*callback.get()); @@ -247,6 +254,13 @@ class OtlpHttpExporterTestPeer : public ::testing::Test EXPECT_EQ("Custom-Header-Value", custom_header->second); } + auto user_agent_header = mock_session->GetRequest()->headers_.find("User-Agent"); + ASSERT_TRUE(user_agent_header != mock_session->GetRequest()->headers_.end()); + if (user_agent_header != mock_session->GetRequest()->headers_.end()) + { + EXPECT_EQ(GetOtlpDefaultUserAgent(), user_agent_header->second); + } + // let the otlp_http_client to continue std::thread async_finish{[callback]() { std::this_thread::sleep_for(std::chrono::milliseconds(100));