-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
stats: json optimization of histograms #3280
Changes from 1 commit
5c3d11b
636e670
6243853
9c89ab4
776d307
b829018
dbe7610
7c68d2a
81f8da7
e7ca172
e86c4c8
de78873
6ca2748
98dd266
10dc326
3e3bdaa
ae5dfbd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -190,7 +190,48 @@ The fields are: | |
|
||
.. http:get:: /stats?format=json | ||
|
||
Outputs /stats in JSON format. This can be used for programmatic access of stats. | ||
Outputs /stats in JSON format. This can be used for programmatic access of stats. Counters and Gauges | ||
will be in the form of a set of (name,value) pairs. Histograms will be under the element "histograms", | ||
that contains "supported_quantiles" which lists the quantiles supported and an array of computed_quantiles | ||
that has the computed quantile for each histogram. | ||
|
||
The JSON structure would as shown below. | ||
|
||
.. code-block:: json | ||
|
||
{ | ||
"stats": [ | ||
{ | ||
"name": "example.counter", | ||
"value": 0 | ||
}, | ||
{ | ||
"name": "example.gauge", | ||
"value": 0 | ||
}, | ||
{ | ||
"histograms": { | ||
"supported_quantiles": [...], | ||
"computed_quantiles": [ | ||
{ | ||
"name": "example.histogram", | ||
"values": [ | ||
{ | ||
"interval": null, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above, it would be nice to see an example of a histogram with non-null quantiles values since that will be the common case. But it'd also be nice to keep some sort of Side note: will this ever print histograms that have no samples in both cumulative and internal since that would mean its There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will make those changes. and regarding used, it currently prints all histograms. And I think it is a good point, it would be good filter the unused ones. I will make that change as well. |
||
"cumulative": null | ||
}, | ||
{ | ||
"interval": null, | ||
"cumulative": null | ||
}, | ||
... | ||
] | ||
} | ||
] | ||
} | ||
} | ||
] | ||
} | ||
|
||
.. http:get:: /stats?format=prometheus | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -161,10 +161,37 @@ TEST_P(IntegrationAdminTest, Admin) { | |
response = IntegrationUtil::makeSingleRequest(lookupPort("admin"), "GET", "/stats?format=json", | ||
"", downstreamProtocol(), version_); | ||
EXPECT_TRUE(response->complete()); | ||
EXPECT_STREQ("200", response->headers().Status()->value().c_str()); | ||
|
||
Json::ObjectSharedPtr statsjson = Json::Factory::loadFromString(response->body()); | ||
EXPECT_TRUE(statsjson->hasObject("stats")); | ||
EXPECT_STREQ("application/json", ContentType(response)); | ||
EXPECT_STREQ("200", response->headers().Status()->value().c_str()); | ||
|
||
uint64_t histogram_count = 0; | ||
for (Json::ObjectSharedPtr obj_ptr : statsjson->getObjectArray("stats")) { | ||
if (obj_ptr->hasObject("histograms")) { | ||
histogram_count++; | ||
const Json::ObjectSharedPtr& histograms_ptr = obj_ptr->getObject("histograms"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm confused here: you are looking for 'histograms' plural so I was expecting another loop over all the histograms. Can you explain? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a toplevel "histograms" element that has supported_quantiles array and computed_quantiels, which is again an array of actual histogram computed values in the form of "name" and "values" (interval and cumulative) - the last array is repeated as many times as there are histograms" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm still not entirely clear on the cardinality of variouis things from looking at the code. If we actually add a second histogram and make the test expect 2? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no. it is still 1. The computed_quantiles array size would be equivalent to the number of histograms. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please add a second histogram to this test, so computed_quantiles array has length 2? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not adding any histograms in the test. I just grab whatever the output is from /stats?format=json and validate that it has histograms, it would definitely some (but non predictable). I am not setting up any thing for this test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, very cool. Let me rephrase my request. Can you make a new test where you add some specific histogram data with more than one histogram, and check the JSON output? |
||
// Validate that both supported_quantiles and computed_quantiles are present in JSON. | ||
EXPECT_TRUE(histograms_ptr->hasObject("supported_quantiles")); | ||
EXPECT_TRUE(histograms_ptr->hasObject("computed_quantiles")); | ||
|
||
const std::vector<Json::ObjectSharedPtr>& computed_quantiles = | ||
histograms_ptr->getObjectArray("computed_quantiles"); | ||
EXPECT_GT(computed_quantiles.size(), 0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we make this EXPECT_EQ something specific here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this count would be equivalent to number of histograms. I do not know exactly how many will come that is why I have added this GT zero condition. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't the number of histograms predictable in this test? |
||
|
||
// Validate that each computed_quantile has name and value objects. | ||
EXPECT_TRUE(computed_quantiles[0]->hasObject("name")); | ||
EXPECT_TRUE(computed_quantiles[0]->hasObject("values")); | ||
|
||
// Validate that supported and computed quantiles are of the same size. | ||
EXPECT_EQ(histograms_ptr->getObjectArray("supported_quantiles").size(), | ||
computed_quantiles[0]->getObjectArray("values").size()); | ||
} | ||
} | ||
|
||
// Validate that the stats JSON has exactly one histograms element. | ||
EXPECT_EQ(1, histogram_count); | ||
|
||
response = IntegrationUtil::makeSingleRequest( | ||
lookupPort("admin"), "GET", "/stats?format=prometheus", "", downstreamProtocol(), version_); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add real values here, so the user knows what the array will look like (as in, is it an array of
doubles
or subobjects)?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will add.