diff --git a/src/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h b/src/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h
index 777e58e3417..77dc135b96f 100644
--- a/src/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h
+++ b/src/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h
@@ -72,6 +72,13 @@ namespace Aws
         typedef Utils::Outcome<std::shared_ptr<Aws::Http::HttpResponse>, AWSError<CoreErrors>> HttpResponseOutcome;
         typedef Utils::Outcome<AmazonWebServiceResult<Utils::Stream::ResponseStream>, AWSError<CoreErrors>> StreamOutcome;
 
+        class AWS_CORE_API AWSClient;
+        class FeatureLogger{
+            public:
+            void LogFeature(const AWSClient* clientPtr, const std::string& featureMetadata) const;
+        };
+
+
         /**
          * Abstract AWS Client. Contains most of the functionality necessary to build an http request, get it signed, and send it across the wire.
          */
@@ -333,6 +340,7 @@ namespace Aws
             static bool DoesResponseGenerateError(const std::shared_ptr<Aws::Http::HttpResponse>& response);
             std::shared_ptr<smithy::components::tracing::TelemetryProvider> m_telemetryProvider;
             std::shared_ptr<Aws::Auth::AWSAuthSignerProvider> m_signerProvider;
+            FeatureLogger m_featureLogger;
         private:
             /**
              * Try to adjust signer's clock
@@ -356,6 +364,8 @@ namespace Aws
             Aws::Client::RequestCompressionConfig m_requestCompressionConfig;
             std::shared_ptr<smithy::client::UserAgentInterceptor> m_userAgentInterceptor;
             Aws::Vector<std::shared_ptr<smithy::interceptor::Interceptor>> m_interceptors;
+
+            friend class FeatureLogger;
         };
 
         AWS_CORE_API Aws::String GetAuthorizationHeader(const Aws::Http::HttpRequest& httpRequest);
diff --git a/src/aws-cpp-sdk-core/include/aws/core/client/UserAgent.h b/src/aws-cpp-sdk-core/include/aws/core/client/UserAgent.h
index 70e83c178cb..1da5667ec49 100644
--- a/src/aws-cpp-sdk-core/include/aws/core/client/UserAgent.h
+++ b/src/aws-cpp-sdk-core/include/aws/core/client/UserAgent.h
@@ -34,6 +34,7 @@ class AWS_CORE_API UserAgent {
   Aws::String SerializeWithFeatures(const Aws::Set<UserAgentFeature>& features) const;
   void SetApiName(const Aws::String& apiName) { m_api = apiName; }
   void AddLegacyFeature(const Aws::String& legacyFeature);
+  void SetFeatureMetadataIfNotSet(const Aws::String& metadata) { if(m_featureMetadata.empty()){m_featureMetadata = metadata;} }
 
  private:
   const Aws::String m_sdkVersion;
@@ -48,6 +49,7 @@ class AWS_CORE_API UserAgent {
   const Aws::String m_execEnv;
   const Aws::String m_appId;
   const Aws::String m_customizations;
+  Aws::String m_featureMetadata;
   Aws::Set<UserAgentFeature> m_features;
 };
 }  // namespace Client
diff --git a/src/aws-cpp-sdk-core/include/smithy/client/features/UserAgentInterceptor.h b/src/aws-cpp-sdk-core/include/smithy/client/features/UserAgentInterceptor.h
index 35e6436e0a1..4408f3b0058 100644
--- a/src/aws-cpp-sdk-core/include/smithy/client/features/UserAgentInterceptor.h
+++ b/src/aws-cpp-sdk-core/include/smithy/client/features/UserAgentInterceptor.h
@@ -35,6 +35,8 @@ class UserAgentInterceptor : public interceptor::Interceptor {
     return context.GetTransmitResponse();
   }
 
+  void SetFeatureMetadataIfNotSet(const Aws::String& metadata) { m_userAgent.SetFeatureMetadataIfNotSet(metadata); }
+
   void SetApiName(const Aws::String& apiName) { m_userAgent.SetApiName(apiName); }
 
   void AddLegacyFeaturesToUserAgent(const Aws::String& valueToAppend) { m_userAgent.AddLegacyFeature(valueToAppend); }
diff --git a/src/aws-cpp-sdk-core/source/client/AWSClient.cpp b/src/aws-cpp-sdk-core/source/client/AWSClient.cpp
index 205970795c8..2a9b41dad9b 100644
--- a/src/aws-cpp-sdk-core/source/client/AWSClient.cpp
+++ b/src/aws-cpp-sdk-core/source/client/AWSClient.cpp
@@ -667,6 +667,7 @@ StreamOutcome AWSClient::MakeRequestWithUnparsedResponse(const Aws::Http::URI& u
     const char* signerRegionOverride,
     const char* signerServiceNameOverride) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     HttpResponseOutcome httpResponseOutcome = AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride);
     if (httpResponseOutcome.IsSuccess())
     {
@@ -685,6 +686,7 @@ StreamOutcome AWSClient::MakeRequestWithUnparsedResponse(const Aws::Http::URI& u
     const char* signerRegionOverride,
     const char* signerServiceNameOverride) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     HttpResponseOutcome httpResponseOutcome = AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride);
     if (httpResponseOutcome.IsSuccess())
     {
@@ -703,6 +705,7 @@ StreamOutcome AWSClient::MakeRequestWithUnparsedResponse(const Aws::AmazonWebSer
                                                          const char* signerRegionOverride,
                                                          const char* signerServiceNameOverride) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     const Aws::Http::URI& uri = endpoint.GetURI();
     if (endpoint.GetAttributes()) {
         signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
@@ -727,6 +730,7 @@ XmlOutcome AWSXMLClient::MakeRequestWithEventStream(const Aws::AmazonWebServiceR
                                                     const char* signerRegionOverride,
                                                     const char* signerServiceNameOverride) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     const Aws::Http::URI& uri = endpoint.GetURI();
     if (endpoint.GetAttributes()) {
         signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
@@ -751,6 +755,7 @@ XmlOutcome AWSXMLClient::MakeRequestWithEventStream(const Aws::Http::URI& uri,
     const char* signerRegionOverride,
     const char* signerServiceNameOverride) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     HttpResponseOutcome httpOutcome = AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride);
     if (httpOutcome.IsSuccess())
     {
@@ -767,6 +772,7 @@ XmlOutcome AWSXMLClient::MakeRequestWithEventStream(const Aws::Http::URI& uri,
     const char* signerRegionOverride,
     const char* signerServiceNameOverride) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     HttpResponseOutcome httpOutcome = AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride);
     if (httpOutcome.IsSuccess())
     {
@@ -925,31 +931,37 @@ void AWSClient::BuildHttpRequest(const Aws::AmazonWebServiceRequest& request, co
 
 Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, long long expirationInSeconds, const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter)
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, expirationInSeconds, serviceSpecificParameter);
 }
 
 Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds, const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter)
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, customizedHeaders, expirationInSeconds, serviceSpecificParameter);
 }
 
 Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, long long expirationInSeconds, const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, region, expirationInSeconds, serviceSpecificParameter);
 }
 
 Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds, const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter)
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, region, customizedHeaders, expirationInSeconds, serviceSpecificParameter);
 }
 
 Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, long long expirationInSeconds, const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, region, serviceName, expirationInSeconds, serviceSpecificParameter);
 }
 
 Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds, const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter)
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, region, serviceName, customizedHeaders, expirationInSeconds, serviceSpecificParameter);
 }
 
@@ -960,6 +972,7 @@ Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http
 
 Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, const char* signerName, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds, const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter)
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, region, serviceName, signerName, customizedHeaders, expirationInSeconds, serviceSpecificParameter);
 }
 
@@ -972,18 +985,21 @@ Aws::String AWSClient::GeneratePresignedUrl(const Aws::Endpoint::AWSEndpoint& en
                                             const char* signerServiceNameOverride /* = nullptr */,
                                             const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter)
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(endpoint, method, customizedHeaders, expirationInSeconds, signerName, signerRegionOverride, signerServiceNameOverride, serviceSpecificParameter);
 }
 
 Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region,
     const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds, const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(request, uri, method, region, extraParams, expirationInSeconds, serviceSpecificParameter);
 }
 
 Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName,
     const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds, const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(request, uri, method, region, serviceName, extraParams, expirationInSeconds, serviceSpecificParameter);
 }
 
@@ -997,17 +1013,20 @@ Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest&
                                             long long expirationInSeconds,
                                             const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(request, uri, method, region, serviceName, signerName, extraParams, expirationInSeconds, serviceSpecificParameter);
 }
 
 Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, const Aws::Http::URI& uri, Aws::Http::HttpMethod method,
     const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds, const std::shared_ptr<Aws::Http::ServiceSpecificParameters> serviceSpecificParameter) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     return AWSUrlPresigner(*this).GeneratePresignedUrl(request, uri, method, extraParams, expirationInSeconds, serviceSpecificParameter);
 }
 
 std::shared_ptr<Aws::Http::HttpResponse> AWSClient::MakeHttpRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     return m_httpClient->MakeRequest(request, m_readRateLimiter.get(), m_writeRateLimiter.get());
 }
 
@@ -1045,4 +1064,12 @@ void AWSClient::AppendRecursionDetectionHeader(std::shared_ptr<Aws::Http::HttpRe
     xAmznTraceIdVal = xAmznTraceIdValEncodedStr.str();
 
     ioRequest->SetHeaderValue(Aws::Http::X_AMZN_TRACE_ID_HEADER, xAmznTraceIdVal);
-}
\ No newline at end of file
+}
+
+void FeatureLogger::LogFeature(const AWSClient* clientPtr, const std::string& featureMetadata) const
+{
+    if(clientPtr)
+    {
+      clientPtr->m_userAgentInterceptor->SetFeatureMetadataIfNotSet(featureMetadata);
+    }
+ }
\ No newline at end of file
diff --git a/src/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp b/src/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp
index f42a306156d..aa2080819b7 100644
--- a/src/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp
+++ b/src/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp
@@ -58,6 +58,7 @@ JsonOutcome AWSJsonClient::MakeRequest(const Aws::AmazonWebServiceRequest& reque
                                        const char* signerRegionOverride /* = nullptr */,
                                        const char* signerServiceNameOverride /* = nullptr */) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     const Aws::Http::URI& uri = endpoint.GetURI();
     if (endpoint.GetAttributes()) {
         signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
@@ -80,6 +81,7 @@ JsonOutcome AWSJsonClient::MakeRequest(const Aws::Endpoint::AWSEndpoint& endpoin
                                        const char* signerRegionOverride /* = nullptr */,
                                        const char* signerServiceNameOverride /* = nullptr */) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     const Aws::Http::URI& uri = endpoint.GetURI();
     if (endpoint.GetAttributes()) {
         signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
@@ -103,6 +105,7 @@ JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri,
     const char* signerRegionOverride,
     const char* signerServiceNameOverride) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride));
     if (!httpOutcome.IsSuccess())
     {
@@ -142,6 +145,7 @@ JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri,
     const char* signerRegionOverride,
     const char* signerServiceNameOverride) const
 {
+    m_featureLogger.LogFeature(this,  __func__);
     HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride));
     if (!httpOutcome.IsSuccess())
     {
@@ -189,6 +193,7 @@ JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri,
 
 JsonOutcome AWSJsonClient::MakeEventStreamRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     // request is assumed to be signed
     std::shared_ptr<HttpResponse> httpResponse = MakeHttpRequest(request);
 
@@ -223,6 +228,7 @@ JsonOutcome AWSJsonClient::MakeEventStreamRequest(std::shared_ptr<Aws::Http::Htt
 AWSError<CoreErrors> AWSJsonClient::BuildAWSError(
     const std::shared_ptr<Aws::Http::HttpResponse>& httpResponse) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     AWSError<CoreErrors> error;
     if (httpResponse->HasClientError())
     {
diff --git a/src/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp b/src/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp
index f1ac1793caa..da700e07952 100644
--- a/src/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp
+++ b/src/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp
@@ -52,6 +52,7 @@ XmlOutcome AWSXMLClient::MakeRequest(const Aws::AmazonWebServiceRequest& request
                                      const char* signerRegionOverride /* = nullptr */,
                                      const char* signerServiceNameOverride /* = nullptr */) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     const Aws::Http::URI& uri = endpoint.GetURI();
     if (endpoint.GetAttributes()) {
         signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
@@ -98,6 +99,7 @@ XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri,
     const char* signerRegionOverride,
     const char* signerServiceNameOverride) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride));
     if (!httpOutcome.IsSuccess())
     {
@@ -140,6 +142,7 @@ XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri,
     const char* signerRegionOverride,
     const char* signerServiceNameOverride) const
 {
+    m_featureLogger.LogFeature(this, __func__);
     HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride));
     if (!httpOutcome.IsSuccess())
     {
diff --git a/src/aws-cpp-sdk-core/source/client/UserAgent.cpp b/src/aws-cpp-sdk-core/source/client/UserAgent.cpp
index f0cc5adc08c..ce800ab49d0 100644
--- a/src/aws-cpp-sdk-core/source/client/UserAgent.cpp
+++ b/src/aws-cpp-sdk-core/source/client/UserAgent.cpp
@@ -70,6 +70,7 @@ const char* CPP = "c++";
 const char* EXEC_ENV = "exec-env";
 const char* APP_ID = "app";
 const char* BUSINESS_METRICS = "m";
+const char* FEATURE_METADATA = "ft";
 }  // namespace
 
 UserAgent::UserAgent(const ClientConfiguration& clientConfiguration,
@@ -128,6 +129,10 @@ Aws::String UserAgent::SerializeWithFeatures(const Aws::Set<UserAgentFeature>& f
   }
 
   // Does not need to be in order
+  if (!m_featureMetadata.empty()) {
+    SerializeMetadata(FEATURE_METADATA, m_featureMetadata);
+  }
+
   if (!m_archName.empty()) {
     SerializeMetadataWithVersion(METADATA, ARCH, m_archName);
   }