diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring')
3 files changed, 540 insertions, 0 deletions
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/DefaultMonitoring.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/DefaultMonitoring.cpp new file mode 100644 index 0000000000..9953004bc3 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/DefaultMonitoring.cpp @@ -0,0 +1,340 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/monitoring/DefaultMonitoring.h> +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/json/JsonSerializer.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/client/AWSClient.h> +#include <aws/core/auth/AWSCredentialsProvider.h> +#include <aws/core/platform/Environment.h> +#include <aws/core/config/AWSProfileConfigLoader.h> +#include <aws/core/utils/logging/LogMacros.h> +using namespace Aws::Utils; + +namespace Aws +{ + namespace Monitoring + { + static const char DEFAULT_MONITORING_ALLOC_TAG[] = "DefaultMonitoringAllocTag"; + static const int CLIENT_ID_LENGTH_LIMIT = 256; + static const int USER_AGENT_LENGTH_LIMIT = 256; + static const int ERROR_MESSAGE_LENGTH_LIMIT = 512; + + const char DEFAULT_MONITORING_CLIENT_ID[] = ""; // default to empty; + const char DEFAULT_MONITORING_HOST[] = "127.0.0.1"; // default to loopback ip address instead of "localhost" based on design specification. + unsigned short DEFAULT_MONITORING_PORT = 31000; //default to 31000; + bool DEFAULT_MONITORING_ENABLE = false; //default to false; + + const int DefaultMonitoring::DEFAULT_MONITORING_VERSION = 1; + const char DefaultMonitoring::DEFAULT_CSM_CONFIG_ENABLED[] = "csm_enabled"; + const char DefaultMonitoring::DEFAULT_CSM_CONFIG_CLIENT_ID[] = "csm_client_id"; + const char DefaultMonitoring::DEFAULT_CSM_CONFIG_HOST[] = "csm_host"; + const char DefaultMonitoring::DEFAULT_CSM_CONFIG_PORT[] = "csm_port"; + const char DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_ENABLED[] = "AWS_CSM_ENABLED"; + const char DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_CLIENT_ID[] = "AWS_CSM_CLIENT_ID"; + const char DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_HOST[] = "AWS_CSM_HOST"; + const char DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_PORT[] = "AWS_CSM_PORT"; + + + struct DefaultContext + { + Aws::Utils::DateTime apiCallStartTime; + Aws::Utils::DateTime attemptStartTime; + int retryCount = 0; + bool lastAttemptSucceeded = false; + bool lastErrorRetryable = false; //doesn't apply if last attempt succeeded. + const Aws::Client::HttpResponseOutcome* outcome = nullptr; + }; + + static inline void FillRequiredFieldsToJson(Json::JsonValue& json, + const Aws::String& type, + const Aws::String& service, + const Aws::String& api, + const Aws::String& clientId, + const DateTime& timestamp, + int version, + const Aws::String& userAgent) + { + json.WithString("Type", type) + .WithString("Service", service) + .WithString("Api", api) + .WithString("ClientId", clientId.substr(0, CLIENT_ID_LENGTH_LIMIT)) + .WithInt64("Timestamp", timestamp.Millis()) + .WithInteger("Version", version) + .WithString("UserAgent", userAgent.substr(0, USER_AGENT_LENGTH_LIMIT)); + } + + static inline void FillRequiredApiCallFieldsToJson(Json::JsonValue& json, + int attemptCount, + int64_t apiCallLatency, + bool maxRetriesExceeded) + { + json.WithInteger("AttemptCount", attemptCount) + .WithInt64("Latency", apiCallLatency) + .WithInteger("MaxRetriesExceeded", maxRetriesExceeded ? 1 : 0); + } + + static inline void FillRequiredApiAttemptFieldsToJson(Json::JsonValue& json, + const Aws::String& domainName, + int64_t attemptLatency) + { + json.WithString("Fqdn", domainName) + .WithInt64("AttemptLatency", attemptLatency); + } + + static inline void ExportResponseHeaderToJson(Json::JsonValue& json, const Aws::Http::HeaderValueCollection& headers, + const Aws::String& headerName, const Aws::String& targetName) + { + auto iter = headers.find(headerName); + if (iter != headers.end()) + { + json.WithString(targetName, iter->second); + } + } + + static inline void ExportHttpMetricsToJson(Json::JsonValue& json, const Aws::Monitoring::HttpClientMetricsCollection& httpMetrics, Aws::Monitoring::HttpClientMetricsType type) + { + auto iter = httpMetrics.find(GetHttpClientMetricNameByType(type)); + if (iter != httpMetrics.end()) + { + json.WithInt64(GetHttpClientMetricNameByType(type), iter->second); + } + } + + static inline void FillOptionalApiCallFieldsToJson(Json::JsonValue& json, + const Aws::Http::HttpRequest* request, + const Aws::Client::HttpResponseOutcome& outcome) + { + if (!request->GetSigningRegion().empty()) + { + json.WithString("Region", request->GetSigningRegion()); + } + if (!outcome.IsSuccess()) + { + if (outcome.GetError().GetExceptionName().empty()) // Not Aws Exception + { + json.WithString("FinalSdkExceptionMessage", outcome.GetError().GetMessage().substr(0, ERROR_MESSAGE_LENGTH_LIMIT)); + } + else // Aws Exception + { + json.WithString("FinalAwsException", outcome.GetError().GetExceptionName()) + .WithString("FinalAwsExceptionMessage", outcome.GetError().GetMessage().substr(0, ERROR_MESSAGE_LENGTH_LIMIT)); + } + json.WithInteger("FinalHttpStatusCode", static_cast<int>(outcome.GetError().GetResponseCode())); + } + else + { + json.WithInteger("FinalHttpStatusCode", static_cast<int>(outcome.GetResult()->GetResponseCode())); + } + } + + static inline void FillOptionalApiAttemptFieldsToJson(Json::JsonValue& json, + const Aws::Http::HttpRequest* request, + const Aws::Client::HttpResponseOutcome& outcome, + const CoreMetricsCollection& metricsFromCore) + { + /** + *No matter request succeeded or not, these fields should be included as long as their requirements + *are met. We should be able to access response (so as to access original request) if the response has error. + */ + if (request->HasAwsSessionToken() && !request->GetAwsSessionToken().empty()) + { + json.WithString("SessionToken", request->GetAwsSessionToken()); + } + if (!request->GetSigningRegion().empty()) + { + json.WithString("Region", request->GetSigningRegion()); + } + if (!request->GetSigningAccessKey().empty()) + { + json.WithString("AccessKey", request->GetSigningAccessKey()); + } + + const auto& headers = outcome.IsSuccess() ? outcome.GetResult()->GetHeaders() : outcome.GetError().GetResponseHeaders(); + + ExportResponseHeaderToJson(json, headers, StringUtils::ToLower("x-amzn-RequestId"), "XAmznRequestId"); + ExportResponseHeaderToJson(json, headers, StringUtils::ToLower("x-amz-request-id"), "XAmzRequestId"); + ExportResponseHeaderToJson(json, headers, StringUtils::ToLower("x-amz-id-2"), "XAmzId2"); + + if (!outcome.IsSuccess()) + { + if (outcome.GetError().GetExceptionName().empty()) // Not Aws Exception + { + json.WithString("SdkExceptionMessage", outcome.GetError().GetMessage().substr(0, ERROR_MESSAGE_LENGTH_LIMIT)); + } + else // Aws Exception + { + json.WithString("AwsException", outcome.GetError().GetExceptionName()) + .WithString("AwsExceptionMessage", outcome.GetError().GetMessage().substr(0, ERROR_MESSAGE_LENGTH_LIMIT)); + } + json.WithInteger("HttpStatusCode", static_cast<int>(outcome.GetError().GetResponseCode())); + } + else + { + json.WithInteger("HttpStatusCode", static_cast<int>(outcome.GetResult()->GetResponseCode())); + } + + // Optional MetricsCollectedFromCore + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::AcquireConnectionLatency); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::ConnectionReused); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::ConnectLatency); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::DestinationIp); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::DnsLatency); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::RequestLatency); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::SslLatency); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::TcpLatency); + } + + DefaultMonitoring::DefaultMonitoring(const Aws::String& clientId, const Aws::String& host, unsigned short port): + m_udp(host.c_str(), port), m_clientId(clientId) + { + } + + void* DefaultMonitoring::OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request) const + { + AWS_UNREFERENCED_PARAM(request); + + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestStart Service: " << serviceName << "Request: " << requestName); + auto context = Aws::New<DefaultContext>(DEFAULT_MONITORING_ALLOC_TAG); + context->apiCallStartTime = Aws::Utils::DateTime::Now(); + context->attemptStartTime = context->apiCallStartTime; + context->retryCount = 0; + return context; + } + + + void DefaultMonitoring::OnRequestSucceeded(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const + { + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestSucceeded Service: " << serviceName << "Request: " << requestName); + CollectAndSendAttemptData(serviceName, requestName, request, outcome, metricsFromCore, context); + } + + void DefaultMonitoring::OnRequestFailed(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const + { + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestFailed Service: " << serviceName << "Request: " << requestName); + CollectAndSendAttemptData(serviceName, requestName, request, outcome, metricsFromCore, context); + } + + void DefaultMonitoring::OnRequestRetry(const Aws::String& serviceName, const Aws::String& requestName, + const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const + { + AWS_UNREFERENCED_PARAM(request); + + DefaultContext* defaultContext = static_cast<DefaultContext*>(context); + defaultContext->retryCount++; + defaultContext->attemptStartTime = Aws::Utils::DateTime::Now(); + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestRetry Service: " << serviceName << "Request: " << requestName << " RetryCnt:" << defaultContext->retryCount); + } + + void DefaultMonitoring::OnFinish(const Aws::String& serviceName, const Aws::String& requestName, + const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const + { + AWS_UNREFERENCED_PARAM(request); + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestFinish Service: " << serviceName << "Request: " << requestName); + + DefaultContext* defaultContext = static_cast<DefaultContext*>(context); + Aws::Utils::Json::JsonValue json; + FillRequiredFieldsToJson(json, "ApiCall", serviceName, requestName, m_clientId, defaultContext->apiCallStartTime, DEFAULT_MONITORING_VERSION, request->GetUserAgent()); + FillRequiredApiCallFieldsToJson(json, defaultContext->retryCount + 1, (DateTime::Now() - defaultContext->apiCallStartTime).count(), (!defaultContext->lastAttemptSucceeded && defaultContext->lastErrorRetryable)); + FillOptionalApiCallFieldsToJson(json, request.get(), *(defaultContext->outcome)); + Aws::String compactData = json.View().WriteCompact(); + m_udp.SendData(reinterpret_cast<const uint8_t*>(compactData.c_str()), static_cast<int>(compactData.size())); + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Send API Metrics: \n" << json.View().WriteReadable()); + Aws::Delete(defaultContext); + } + + void DefaultMonitoring::CollectAndSendAttemptData(const Aws::String& serviceName, const Aws::String& requestName, + const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Client::HttpResponseOutcome& outcome, + const CoreMetricsCollection& metricsFromCore, void* context) const + { + DefaultContext* defaultContext = static_cast<DefaultContext*>(context); + defaultContext->outcome = &outcome; + defaultContext->lastAttemptSucceeded = outcome.IsSuccess() ? true : false; + defaultContext->lastErrorRetryable = (!outcome.IsSuccess() && outcome.GetError().ShouldRetry()) ? true : false; + Aws::Utils::Json::JsonValue json; + FillRequiredFieldsToJson(json, "ApiCallAttempt", serviceName, requestName, m_clientId, defaultContext->attemptStartTime, DEFAULT_MONITORING_VERSION, request->GetUserAgent()); + FillRequiredApiAttemptFieldsToJson(json, request->GetUri().GetAuthority(), (DateTime::Now() - defaultContext->attemptStartTime).count()); + FillOptionalApiAttemptFieldsToJson(json, request.get(), outcome, metricsFromCore); + Aws::String compactData = json.View().WriteCompact(); + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Send Attempt Metrics: \n" << json.View().WriteReadable()); + m_udp.SendData(reinterpret_cast<const uint8_t*>(compactData.c_str()), static_cast<int>(compactData.size())); + } + + Aws::UniquePtr<MonitoringInterface> DefaultMonitoringFactory::CreateMonitoringInstance() const + { + Aws::String clientId(DEFAULT_MONITORING_CLIENT_ID); // default to empty + Aws::String host(DEFAULT_MONITORING_HOST); // default to 127.0.0.1 + unsigned short port = DEFAULT_MONITORING_PORT; // default to 31000 + bool enable = DEFAULT_MONITORING_ENABLE; //default to false; + + //check profile_config + Aws::String tmpEnable = Aws::Config::GetCachedConfigValue(DefaultMonitoring::DEFAULT_CSM_CONFIG_ENABLED); + Aws::String tmpClientId = Aws::Config::GetCachedConfigValue(DefaultMonitoring::DEFAULT_CSM_CONFIG_CLIENT_ID); + Aws::String tmpHost = Aws::Config::GetCachedConfigValue(DefaultMonitoring::DEFAULT_CSM_CONFIG_HOST); + Aws::String tmpPort = Aws::Config::GetCachedConfigValue(DefaultMonitoring::DEFAULT_CSM_CONFIG_PORT); + + if (!tmpEnable.empty()) + { + enable = StringUtils::CaselessCompare(tmpEnable.c_str(), "true") ? true : false; + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved csm_enabled from profile_config to be " << enable); + } + if (!tmpClientId.empty()) + { + clientId = tmpClientId; + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved csm_client_id from profile_config to be " << clientId); + } + + if (!tmpHost.empty()) + { + host = tmpHost; + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved csm_host from profile_config to be " << host); + } + + if (!tmpPort.empty()) + { + port = static_cast<short>(StringUtils::ConvertToInt32(tmpPort.c_str())); + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved csm_port from profile_config to be " << port); + } + + // check environment variables + tmpEnable = Aws::Environment::GetEnv(DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_ENABLED); + tmpClientId = Aws::Environment::GetEnv(DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_CLIENT_ID); + tmpHost = Aws::Environment::GetEnv(DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_HOST); + tmpPort = Aws::Environment::GetEnv(DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_PORT); + if (!tmpEnable.empty()) + { + enable = StringUtils::CaselessCompare(tmpEnable.c_str(), "true") ? true : false; + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved AWS_CSM_ENABLED from Environment variable to be " << enable); + } + if (!tmpClientId.empty()) + { + clientId = tmpClientId; + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved AWS_CSM_CLIENT_ID from Environment variable to be " << clientId); + + } + if (!tmpHost.empty()) + { + host = tmpHost; + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved AWS_CSM_HOST from Environment variable to be " << host); + } + if (!tmpPort.empty()) + { + port = static_cast<unsigned short>(StringUtils::ConvertToInt32(tmpPort.c_str())); + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved AWS_CSM_PORT from Environment variable to be " << port); + } + + if (!enable) + { + return nullptr; + } + return Aws::MakeUnique<DefaultMonitoring>(DEFAULT_MONITORING_ALLOC_TAG, clientId, host, port); + } + + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/HttpClientMetrics.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/HttpClientMetrics.cpp new file mode 100644 index 0000000000..f3ef582867 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/HttpClientMetrics.cpp @@ -0,0 +1,71 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/utils/HashingUtils.h> +#include <aws/core/monitoring/HttpClientMetrics.h> + +namespace Aws +{ + namespace Monitoring + { + static const char HTTP_CLIENT_METRICS_DESTINATION_IP[] = "DestinationIp"; + static const char HTTP_CLIENT_METRICS_ACQUIRE_CONNECTION_LATENCY[] = "AcquireConnectionLatency"; + static const char HTTP_CLIENT_METRICS_CONNECTION_REUSED[] = "ConnectionReused"; + static const char HTTP_CLIENT_METRICS_CONNECTION_LATENCY[] = "ConnectLatency"; + static const char HTTP_CLIENT_METRICS_REQUEST_LATENCY[] = "RequestLatency"; + static const char HTTP_CLIENT_METRICS_DNS_LATENCY[] = "DnsLatency"; + static const char HTTP_CLIENT_METRICS_TCP_LATENCY[] = "TcpLatency"; + static const char HTTP_CLIENT_METRICS_SSL_LATENCY[] = "SslLatency"; + static const char HTTP_CLIENT_METRICS_UNKNOWN[] = "Unknown"; + + using namespace Aws::Utils; + HttpClientMetricsType GetHttpClientMetricTypeByName(const Aws::String& name) + { + static std::map<int, HttpClientMetricsType> metricsNameHashToType = + { + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_DESTINATION_IP), HttpClientMetricsType::DestinationIp), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_ACQUIRE_CONNECTION_LATENCY), HttpClientMetricsType::AcquireConnectionLatency), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_CONNECTION_REUSED), HttpClientMetricsType::ConnectionReused), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_CONNECTION_LATENCY), HttpClientMetricsType::ConnectLatency), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_REQUEST_LATENCY), HttpClientMetricsType::RequestLatency), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_DNS_LATENCY), HttpClientMetricsType::DnsLatency), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_TCP_LATENCY), HttpClientMetricsType::TcpLatency), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_SSL_LATENCY), HttpClientMetricsType::SslLatency) + }; + + int nameHash = HashingUtils::HashString(name.c_str()); + auto it = metricsNameHashToType.find(nameHash); + if (it == metricsNameHashToType.end()) + { + return HttpClientMetricsType::Unknown; + } + return it->second; + } + + Aws::String GetHttpClientMetricNameByType(HttpClientMetricsType type) + { + static std::map<int, std::string> metricsTypeToName = + { + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::DestinationIp), HTTP_CLIENT_METRICS_DESTINATION_IP), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::AcquireConnectionLatency), HTTP_CLIENT_METRICS_ACQUIRE_CONNECTION_LATENCY), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::ConnectionReused), HTTP_CLIENT_METRICS_CONNECTION_REUSED), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::ConnectLatency), HTTP_CLIENT_METRICS_CONNECTION_LATENCY), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::RequestLatency), HTTP_CLIENT_METRICS_REQUEST_LATENCY), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::DnsLatency), HTTP_CLIENT_METRICS_DNS_LATENCY), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::TcpLatency), HTTP_CLIENT_METRICS_TCP_LATENCY), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::SslLatency), HTTP_CLIENT_METRICS_SSL_LATENCY), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::Unknown), HTTP_CLIENT_METRICS_UNKNOWN) + }; + + auto it = metricsTypeToName.find(static_cast<int>(type)); + if (it == metricsTypeToName.end()) + { + return HTTP_CLIENT_METRICS_UNKNOWN; + } + return Aws::String(it->second.c_str()); + } + + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp new file mode 100644 index 0000000000..7a8d3adb41 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp @@ -0,0 +1,129 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/monitoring/MonitoringInterface.h> +#include <aws/core/monitoring/MonitoringFactory.h> +#include <aws/core/monitoring/MonitoringManager.h> +#include <aws/core/monitoring/DefaultMonitoring.h> +#include <aws/core/Core_EXPORTS.h> + +#ifdef _MSC_VER +#pragma warning(disable : 4592) +#endif + +namespace Aws +{ + namespace Monitoring + { + typedef Aws::Vector<Aws::UniquePtr<MonitoringInterface>> Monitors; + + const char MonitoringTag[] = "MonitoringAllocTag"; + + /** + * Global factory to create global metrics instance. + */ + static Aws::UniquePtr<Monitors> s_monitors; + + Aws::Vector<void*> OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request) + { + assert(s_monitors); + Aws::Vector<void*> contexts; + contexts.reserve(s_monitors->size()); + for (const auto& interface: *s_monitors) + { + contexts.emplace_back(interface->OnRequestStarted(serviceName, requestName, request)); + } + return contexts; + } + + void OnRequestSucceeded(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts) + { + assert(s_monitors); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnRequestSucceeded(serviceName, requestName, request, outcome, metricsFromCore, contexts[index++]); + } + } + + void OnRequestFailed(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts) + { + assert(s_monitors); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnRequestFailed(serviceName, requestName, request, outcome, metricsFromCore, contexts[index++]); + } + } + + void OnRequestRetry(const Aws::String& serviceName, const Aws::String& requestName, + const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts) + { + assert(s_monitors); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnRequestRetry(serviceName, requestName, request, contexts[index++]); + } + } + + void OnFinish(const Aws::String& serviceName, const Aws::String& requestName, + const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts) + { + assert(s_monitors); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnFinish(serviceName, requestName, request, contexts[index++]); + } + } + + void InitMonitoring(const std::vector<MonitoringFactoryCreateFunction>& monitoringFactoryCreateFunctions) + { + if (s_monitors) + { + return; + } + s_monitors = Aws::MakeUnique<Monitors>(MonitoringTag); + for (const auto& function: monitoringFactoryCreateFunctions) + { + auto factory = function(); + if (factory) + { + auto instance = factory->CreateMonitoringInstance(); + if (instance) + { + s_monitors->emplace_back(std::move(instance)); + } + } + } + + auto defaultMonitoringFactory = Aws::MakeShared<DefaultMonitoringFactory>(MonitoringTag); + auto instance = defaultMonitoringFactory->CreateMonitoringInstance(); + if (instance) + { + s_monitors->emplace_back(std::move(instance)); + } + } + + void CleanupMonitoring() + { + if (!s_monitors) + { + return; + } + + s_monitors = nullptr; + } + } // namespace Monitoring + +} // namespace Aws |