Skip to content
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

Support envoy to provide stats generated by mixer filter. #891

Merged
merged 11 commits into from
Jan 5, 2018

Conversation

JimmyCYJ
Copy link
Member

@JimmyCYJ JimmyCYJ commented Jan 3, 2018

What this PR does / why we need it:

Which issue this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close that issue when PR gets merged): fixes #132
istio/old_mixerclient_repo#132

Special notes for your reviewer:

Release note:

Support Envoy to provide stats generated by mixer filter

@JimmyCYJ JimmyCYJ requested a review from qiwzhang January 3, 2018 01:54
@googlebot googlebot added the cla: yes Set by the Google CLA bot to indicate the author of a PR has signed the Google CLA. label Jan 3, 2018
@istio-merge-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
We suggest the following additional approver: linsun

Assign the PR to them by writing /assign @linsun in a comment when ready.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

*/
// clang-format off
#define ALL_HTTP_MIXER_FILTER_STATS(COUNTER, GAUGE) \
COUNTER(total_check_calls) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also want separate check and report latencies as histograms. The histograms should use the same bucketization as used by envoy upstream_XXX counters.
upstream_mixer_XXX stats mash checks and reports together.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JimmyCYJ please file a separate issue to add Check/Report latency stats. Don't want to put too much change into one PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I filed a another issue here. istio/old_mixerclient_repo#324
Thanks.

CheckData check_data(headers, decoder_callbacks_->connection());
HeaderUpdate header_update(&headers);
cancel_check_ = handler_->Check(
&check_data, &header_update,
CheckTransport::GetFunc(mixer_control_.cm(), &headers),
[this](const Status& status) { completeCheck(status); });
CheckAndUpdateStats(old_stats);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a timer of every 10 seconds to update counters. Not on every call.

*/
struct InstanceStats {
ALL_HTTP_MIXER_FILTER_STATS(GENERATE_COUNTER_STRUCT)
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can extract this into a separate header file so tcp_filter can use it too. tcp has the same counters with a different prefix.

/**
* Struct definition for all mixer filter stats. @see stats_macros.h
*/
struct InstanceStats {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

call it MixerFilterStats


namespace Envoy {
namespace Http {
namespace Mixer {

// MixerStatsObject maintains statistics for number of check, quota and report
// calls issued by a mixer filter.
class MixerStatsObject {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can move this class into stats.h

// Start timer for updating envoy stats periodically.
timer_.reset(new EnvoyTimer(
dispatcher.createTimer([this]() { StatsUpdateCallback(); })));
timer_->Start(MixerStatsObject::kStatsUpdateIntervalInMs);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use EnvoyTimer.

use dispatcher.createTimer() directly

}

// Copy new_stats to old_stats_ for next stats update.
old_stats_.total_check_calls = new_stats.total_check_calls;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you just do
old_stats_ = new_stats;


// These members are needed to update envoy stats periodically.
MixerStatsObject stats_;
std::unique_ptr<::istio::mixer_client::Timer> timer_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the timer logic can be moved into MixerStatsObj class.
It will take a function call in the contructor to call controller_->GetStatistitis()

* All http mixer filter stats. @see stats_macros.h
*/
// clang-format off
#define ALL_HTTP_MIXER_FILTER_STATS(COUNTER) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove "HTTP_"

// calls issued by a mixer filter.
class MixerStatsObject {
public:
static const int kStatsUpdateIntervalInMs;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this "const int" can be anonymous in cc file?


private:
MixerFilterStats stats_;
GetStatsFunc get_statistics_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_stats_func_? suffixed with func.

also add comment for each class variable.


void MixerControlBase::SetUpStatsTimer() {
timer_ = dispatcher_.createTimer([this]() -> void { StatsUpdateCallback(); });
timer_->enableTimer(std::chrono::milliseconds(MixerStatsObject::kStatsUpdateIntervalInMs));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can move timer_ into StatsObj class


private:
Event::Dispatcher& dispatcher_;
::Envoy::Event::TimerPtr timer_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you move timer_ into StatsObject, you may not need MixerControlBase class

::istio::mixer_client::Statistics new_stats;
stats_.GetStatistics(&new_stats);
stats_.CheckAndUpdateStats(new_stats);
timer_->enableTimer(std::chrono::milliseconds(MixerStatsObject::kStatsUpdateIntervalInMs));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to call "enable" for each call. Only need to enable it once.

timer_->enableTimer(std::chrono::milliseconds(MixerStatsObject::kStatsUpdateIntervalInMs));
}

void MixerControlBase::StatsUpdateCallback() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

call it OnTimer()

@JimmyCYJ
Copy link
Member Author

JimmyCYJ commented Jan 5, 2018

Please take a look. Thanks!

@@ -32,7 +34,8 @@ class HttpMixerControl final : public ThreadLocal::ThreadLocalObject {
// The constructor.
HttpMixerControl(const HttpMixerConfig& mixer_config,
Upstream::ClusterManager& cm, Event::Dispatcher& dispatcher,
Runtime::RandomGenerator& random);
Runtime::RandomGenerator& random,
const std::string& stats_prefix, Stats::Scope& scope);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not need to pass in stats_prefix. It is already in HttpMixerControl constructor.

void OnTimer();

// Compares old stats with new stats and updates envoy stats.
void CheckAndUpdateStats(const ::istio::mixer_client::Statistics& new_stats);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only constructor is public, all these functions can be private.

Can we pass GetStatsFunc in the constructor, not use a separate function to set it.?

// These members are used for creating a timer which update Envoy stats
// periodically.
::Envoy::Event::TimerPtr timer_;
::Envoy::Event::Dispatcher& dispatcher_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need to store dispatcher_?

}

void MixerStatsObject::SetUpStatsTimer() {
timer_ = dispatcher_.createTimer([this]() -> void { OnTimer(); });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we create timer at constructor so dispatcher_ doesn't need to be kept?


void MixerStatsObject::OnTimer() {
::istio::mixer_client::Statistics new_stats;
GetStatistics(&new_stats);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at constructor, if get_stats_func_ is null, don't create timer.

}

void MixerStatsObject::InitGetStatisticsFunc(GetStatsFunc get_stats) {
if (get_stats) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set function as constructor.

if (get_stats_func_) {
get_stats_func_(stats);
} else {
auto& logger = Logger::Registry::getLog(Logger::Id::config);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at constructor, if get_stats_func_ is null, don't create timer. not need for this check

@@ -74,6 +74,8 @@ const std::set<std::string> RequestHeaderExclusives = {
kIstioAttributeHeader.get(),
};

const std::string kStatsPrefix("http_mixer_filter.");

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move these two prefix into mixer_control.cc to be used at their constructors


stats_obj_.InitGetStatisticsFunc(
std::bind(&::istio::mixer_control::tcp::Controller::GetStatistics,
controller(), std::placeholders::_1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use lambda function, such as

do it in the consturctor.

stats_obj_(dispatcher, "tcp_mixer_filter.", scope,
[this](STat *stat) -> bool {
if (!controller_) return false;
controler_->GetStats(stat);
return true;
});

Copy link
Contributor

@qiwzhang qiwzhang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good. Almost there.

We need integration test. Can be a separate PR if you like.

} else {
auto& logger = Logger::Registry::getLog(Logger::Id::config);
ENVOY_LOG_TO_LOGGER(logger, error, "get_stats_func_ is empty");
timer_ = dispatcher.createTimer([this]() -> void { OnTimer(); });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can remove " -> void"

just:

this {OnTimer(); }

CheckAndUpdateStats(new_stats);
timer_->enableTimer(std::chrono::milliseconds(kStatsUpdateIntervalInMs));
} else {
auto& logger = Logger::Registry::getLog(Logger::Id::config);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not need to log anything for else cast

@@ -18,10 +18,12 @@
#include "control/include/http/controller.h"
#include "control/include/tcp/controller.h"
#include "envoy/event/dispatcher.h"
#include "envoy/event/timer.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timer.h is not needed

@@ -13,14 +13,23 @@
* limitations under the License.
*/

#include "src/envoy/mixer/mixer_control.h"
#include <chrono>
#include <memory>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why these two header files are needed here?

namespace Mixer {
namespace {

const int kStatsUpdateIntervalInMs = 10000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comment for const variable.

@@ -33,7 +35,7 @@ MixerStatsObject::MixerStatsObject(Event::Dispatcher& dispatcher,
memset(&old_stats_, 0, sizeof(old_stats_));

if (get_stats_func_) {
timer_ = dispatcher.createTimer([this]() -> void { OnTimer(); });
timer_ = dispatcher.createTimer([this] { OnTimer(); });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The format is wrong, the lambda should be:

this {OnTimer(); }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.createTime(this {OnTimer(); });

you need () after square []

@@ -15,12 +15,18 @@

#include "src/envoy/mixer/mixer_control.h"
#include "src/envoy/mixer/grpc_transport.h"
#include "src/envoy/mixer/stats.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for this include. already included in the mxer_control.h

bool get_stats = get_stats_func_(&new_stats);
if (get_stats) {
CheckAndUpdateStats(new_stats);
timer_->enableTimer(std::chrono::milliseconds(kStatsUpdateIntervalInMs));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should always enable timer

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks!

@qiwzhang qiwzhang merged commit 147edd1 into istio:master Jan 5, 2018
@JimmyCYJ JimmyCYJ deleted the add_stats_to_mixer_filter branch January 5, 2018 19:26
JimmyCYJ added a commit to JimmyCYJ/proxy that referenced this pull request Jan 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Set by the Google CLA bot to indicate the author of a PR has signed the Google CLA.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants