23
23
#include < fstream>
24
24
#include < memory>
25
25
#include < utility>
26
+ #include < variant>
26
27
27
28
using namespace PerformanceTest ::Reporting;
28
29
29
30
struct RequestContext {
30
- Aws::Utils::DateTime requestStartTime;
31
+ Aws::String serviceName;
32
+ Aws::String requestName;
33
+ std::shared_ptr<const Aws::Http::HttpRequest> request;
34
+ std::variant<int64_t , double > durationMs = int64_t (0 );
31
35
};
32
36
33
37
JsonReportingMetrics::JsonReportingMetrics (const Aws::Set<Aws::String>& monitoredOperations, const Aws::String& productId,
@@ -36,7 +40,10 @@ JsonReportingMetrics::JsonReportingMetrics(const Aws::Set<Aws::String>& monitore
36
40
m_productId(productId),
37
41
m_sdkVersion(sdkVersion),
38
42
m_commitId(commitId),
39
- m_outputFilename(outputFilename) {}
43
+ m_outputFilename(outputFilename),
44
+ m_hasInvalidLatency(false ) {}
45
+
46
+ JsonReportingMetrics::~JsonReportingMetrics () { DumpJson (); }
40
47
41
48
JsonReportingMetricsFactory::JsonReportingMetricsFactory (const Aws::Set<Aws::String>& monitoredOperations, const Aws::String& productId,
42
49
const Aws::String& sdkVersion, const Aws::String& commitId,
@@ -47,16 +54,30 @@ JsonReportingMetricsFactory::JsonReportingMetricsFactory(const Aws::Set<Aws::Str
47
54
m_commitId(commitId),
48
55
m_outputFilename(outputFilename) {}
49
56
50
- JsonReportingMetrics::~JsonReportingMetrics () { DumpJson (); }
51
-
52
57
Aws::UniquePtr<Aws::Monitoring::MonitoringInterface> JsonReportingMetricsFactory::CreateMonitoringInstance () const {
53
58
return Aws::MakeUnique<JsonReportingMetrics>(" JsonReportingMetrics" , m_monitoredOperations, m_productId, m_sdkVersion, m_commitId,
54
59
m_outputFilename);
55
60
}
56
61
62
+ void JsonReportingMetrics::StoreLatencyInContext (const Aws::String& serviceName, const Aws::String& requestName,
63
+ const std::shared_ptr<const Aws::Http::HttpRequest>& request,
64
+ const Aws::Monitoring::CoreMetricsCollection& metricsFromCore, void * context) const {
65
+ RequestContext* requestContext = static_cast <RequestContext*>(context);
66
+
67
+ Aws::String const latencyKey = Aws::Monitoring::GetHttpClientMetricNameByType (Aws::Monitoring::HttpClientMetricsType::RequestLatency);
68
+ auto iterator = metricsFromCore.httpClientMetrics .find (latencyKey);
69
+ if (iterator != metricsFromCore.httpClientMetrics .end () && iterator->second > 0 ) {
70
+ requestContext->serviceName = serviceName;
71
+ requestContext->requestName = requestName;
72
+ requestContext->request = request;
73
+ requestContext->durationMs = iterator->second ;
74
+ } else {
75
+ m_hasInvalidLatency = true ;
76
+ }
77
+ }
78
+
57
79
void JsonReportingMetrics::AddPerformanceRecord (const Aws::String& serviceName, const Aws::String& requestName,
58
- const Aws::Monitoring::CoreMetricsCollection&,
59
- const std::shared_ptr<const Aws::Http::HttpRequest>& request, int64_t durationMs) const {
80
+ const std::shared_ptr<const Aws::Http::HttpRequest>& request, const std::variant<int64_t , double >& durationMs) const {
60
81
// If no operations are registered, monitor all operations. Otherwise, only monitor registered operations
61
82
if (!m_monitoredOperations.empty () && m_monitoredOperations.find (requestName) == m_monitoredOperations.end ()) {
62
83
return ;
@@ -85,27 +106,22 @@ void JsonReportingMetrics::AddPerformanceRecord(const Aws::String& serviceName,
85
106
86
107
void * JsonReportingMetrics::OnRequestStarted (const Aws::String&, const Aws::String&,
87
108
const std::shared_ptr<const Aws::Http::HttpRequest>&) const {
88
- auto context = Aws::New<RequestContext>(" JsonReportingMetrics" );
89
- context->requestStartTime = Aws::Utils::DateTime::Now ();
109
+ auto context = Aws::New<RequestContext>(" RequestContext" );
90
110
return context;
91
111
}
92
112
93
113
void JsonReportingMetrics::OnRequestSucceeded (const Aws::String& serviceName, const Aws::String& requestName,
94
114
const std::shared_ptr<const Aws::Http::HttpRequest>& request,
95
115
const Aws::Client::HttpResponseOutcome&,
96
116
const Aws::Monitoring::CoreMetricsCollection& metricsFromCore, void * context) const {
97
- RequestContext* requestContext = static_cast <RequestContext*>(context);
98
- int64_t durationMs = (Aws::Utils::DateTime::Now () - requestContext->requestStartTime ).count ();
99
- AddPerformanceRecord (serviceName, requestName, metricsFromCore, request, durationMs);
117
+ StoreLatencyInContext (serviceName, requestName, request, metricsFromCore, context);
100
118
}
101
119
102
120
void JsonReportingMetrics::OnRequestFailed (const Aws::String& serviceName, const Aws::String& requestName,
103
121
const std::shared_ptr<const Aws::Http::HttpRequest>& request,
104
122
const Aws::Client::HttpResponseOutcome&,
105
123
const Aws::Monitoring::CoreMetricsCollection& metricsFromCore, void * context) const {
106
- RequestContext* requestContext = static_cast <RequestContext*>(context);
107
- int64_t durationMs = (Aws::Utils::DateTime::Now () - requestContext->requestStartTime ).count ();
108
- AddPerformanceRecord (serviceName, requestName, metricsFromCore, request, durationMs);
124
+ StoreLatencyInContext (serviceName, requestName, request, metricsFromCore, context);
109
125
}
110
126
111
127
void JsonReportingMetrics::OnRequestRetry (const Aws::String&, const Aws::String&, const std::shared_ptr<const Aws::Http::HttpRequest>&,
@@ -114,11 +130,24 @@ void JsonReportingMetrics::OnRequestRetry(const Aws::String&, const Aws::String&
114
130
void JsonReportingMetrics::OnFinish (const Aws::String&, const Aws::String&, const std::shared_ptr<const Aws::Http::HttpRequest>&,
115
131
void * context) const {
116
132
RequestContext* requestContext = static_cast <RequestContext*>(context);
133
+
134
+ if (std::visit ([](auto && v) { return v > 0 ; }, requestContext->durationMs )) {
135
+ AddPerformanceRecord (requestContext->serviceName , requestContext->requestName , requestContext->request , requestContext->durationMs );
136
+ }
137
+
117
138
Aws::Delete (requestContext);
118
139
}
119
140
120
141
void JsonReportingMetrics::DumpJson () const {
121
- if (m_performanceRecords.empty ()) {
142
+ Aws::Utils::Json::JsonValue root;
143
+ root.WithString (" productId" , m_productId);
144
+ root.WithString (" sdkVersion" , m_sdkVersion);
145
+ root.WithString (" commitId" , m_commitId);
146
+
147
+ // If there is an invalid latency or there are no records, then use an empty results array
148
+ if (m_hasInvalidLatency || m_performanceRecords.empty ()) {
149
+ root.WithArray (" results" , Aws::Utils::Array<Aws::Utils::Json::JsonValue>(0 ));
150
+ WriteJsonToFile (root);
122
151
return ;
123
152
}
124
153
@@ -140,12 +169,6 @@ void JsonReportingMetrics::DumpJson() const {
140
169
}
141
170
}
142
171
143
- // Create the JSON output
144
- Aws::Utils::Json::JsonValue root;
145
- root.WithString (" productId" , m_productId);
146
- root.WithString (" sdkVersion" , m_sdkVersion);
147
- root.WithString (" commitId" , m_commitId);
148
-
149
172
Aws::Utils::Array<Aws::Utils::Json::JsonValue> results (aggregatedRecords.size ());
150
173
size_t index = 0 ;
151
174
@@ -172,10 +195,10 @@ void JsonReportingMetrics::DumpJson() const {
172
195
Aws::Utils::Array<Aws::Utils::Json::JsonValue> measurementsArray (record.measurements .size ());
173
196
for (size_t measurementIndex = 0 ; measurementIndex < record.measurements .size (); ++measurementIndex) {
174
197
Aws::Utils::Json::JsonValue measurementValue;
175
- if (record.measurements [measurementIndex]. IsDouble ( )) {
176
- measurementValue.AsDouble (record.measurements [measurementIndex]. AsDouble ( ));
198
+ if (std::holds_alternative< double >( record.measurements [measurementIndex])) {
199
+ measurementValue.AsDouble (std::get< double >( record.measurements [measurementIndex]));
177
200
} else {
178
- measurementValue.AsInt64 (record.measurements [measurementIndex]. AsInt64 ( ));
201
+ measurementValue.AsInt64 (std::get< int64_t >( record.measurements [measurementIndex]));
179
202
}
180
203
measurementsArray[measurementIndex] = std::move (measurementValue);
181
204
}
@@ -185,7 +208,10 @@ void JsonReportingMetrics::DumpJson() const {
185
208
}
186
209
187
210
root.WithArray (" results" , std::move (results));
211
+ WriteJsonToFile (root);
212
+ }
188
213
214
+ void JsonReportingMetrics::WriteJsonToFile (const Aws::Utils::Json::JsonValue& root) const {
189
215
std::ofstream outFile (m_outputFilename.c_str ());
190
216
if (outFile.is_open ()) {
191
217
outFile << root.View ().WriteReadable ();
0 commit comments