-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
MX support additional labels #6030
Changes from all commits
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 |
---|---|---|
|
@@ -28,6 +28,7 @@ | |
#include "source/common/network/utility.h" | ||
#include "source/common/stream_info/utility.h" | ||
#include "source/extensions/filters/common/expr/context.h" | ||
#include "source/extensions/filters/common/expr/cel_state.h" | ||
#include "source/extensions/filters/common/expr/evaluator.h" | ||
#include "source/extensions/filters/http/common/pass_through_filter.h" | ||
#include "source/extensions/filters/http/grpc_stats/grpc_stats_filter.h" | ||
|
@@ -122,13 +123,40 @@ bool peerInfoRead(Reporter reporter, const StreamInfo::FilterState& filter_state | |
filter_state.hasDataWithName(Istio::Common::NoPeer); | ||
} | ||
|
||
const Istio::Common::WorkloadMetadataObject* peerInfo(Reporter reporter, | ||
const StreamInfo::FilterState& filter_state) { | ||
std::optional<Istio::Common::WorkloadMetadataObject> | ||
peerInfo(Reporter reporter, const StreamInfo::FilterState& filter_state) { | ||
const auto& filter_state_key = | ||
reporter == Reporter::ServerSidecar || reporter == Reporter::ServerGateway | ||
? Istio::Common::DownstreamPeer | ||
: Istio::Common::UpstreamPeer; | ||
return filter_state.getDataReadOnly<Istio::Common::WorkloadMetadataObject>(filter_state_key); | ||
// This's a workaround before FilterStateObject support operation like `.labels['role']`. | ||
// The workaround is to use CelState to store the peer metadata. | ||
// Rebuild the WorkloadMetadataObject from the CelState. | ||
const auto* cel_state = | ||
filter_state.getDataReadOnly<Envoy::Extensions::Filters::Common::Expr::CelState>( | ||
filter_state_key); | ||
if (!cel_state) { | ||
return {}; | ||
} | ||
|
||
ProtobufWkt::Struct obj; | ||
if (!obj.ParseFromString(absl::string_view(cel_state->value()))) { | ||
return {}; | ||
} | ||
|
||
Istio::Common::WorkloadMetadataObject peer_info( | ||
extractString(obj, Istio::Common::InstanceNameToken), | ||
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 labels? 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. labels won't be used in the next, unneed to rebuild labels here. |
||
extractString(obj, Istio::Common::ClusterNameToken), | ||
extractString(obj, Istio::Common::NamespaceNameToken), | ||
extractString(obj, Istio::Common::WorkloadNameToken), | ||
extractString(obj, Istio::Common::ServiceNameToken), | ||
extractString(obj, Istio::Common::ServiceVersionToken), | ||
extractString(obj, Istio::Common::AppNameToken), | ||
extractString(obj, Istio::Common::AppVersionToken), | ||
Istio::Common::fromSuffix(extractString(obj, Istio::Common::WorkloadTypeToken)), | ||
extractString(obj, Istio::Common::IdentityToken)); | ||
|
||
return peer_info; | ||
} | ||
|
||
// Process-wide context shared with all filter instances. | ||
|
@@ -313,8 +341,6 @@ using ContextSharedPtr = std::shared_ptr<Context>; | |
|
||
SINGLETON_MANAGER_REGISTRATION(Context) | ||
|
||
using google::api::expr::runtime::CelValue; | ||
|
||
// Instructions on dropping, creating, and overriding labels. | ||
// This is not the "hot path" of the metrics system and thus, fairly | ||
// unoptimized. | ||
|
@@ -651,6 +677,13 @@ struct Config : public Logger::Loggable<Logger::Id::filter> { | |
Protobuf::Arena arena; | ||
auto eval_status = compiled_exprs[id].first->Evaluate(*this, &arena); | ||
if (!eval_status.ok() || eval_status.value().IsError()) { | ||
if (!eval_status.ok()) { | ||
ENVOY_LOG(debug, "Failed to evaluate metric expression: {}", eval_status.status()); | ||
} | ||
if (eval_status.value().IsError()) { | ||
ENVOY_LOG(debug, "Failed to evaluate metric expression: {}", | ||
eval_status.value().ErrorOrDie()->message()); | ||
} | ||
expr_values_.push_back(std::make_pair(parent_.context_->unknown_, 0)); | ||
} else { | ||
const auto string_value = Filters::Common::Expr::print(eval_status.value()); | ||
|
@@ -769,6 +802,7 @@ struct Config : public Logger::Loggable<Logger::Id::filter> { | |
using ConfigSharedPtr = std::shared_ptr<Config>; | ||
|
||
class IstioStatsFilter : public Http::PassThroughFilter, | ||
public Logger::Loggable<Logger::Id::filter>, | ||
public AccessLog::Instance, | ||
public Network::ReadFilter, | ||
public Network::ConnectionCallbacks { | ||
|
@@ -895,6 +929,7 @@ class IstioStatsFilter : public Http::PassThroughFilter, | |
const auto& info = decoder_callbacks_->streamInfo(); | ||
peer_read_ = peerInfoRead(config_->reporter(), info.filterState()); | ||
if (peer_read_ || end_stream) { | ||
ENVOY_LOG(trace, "Populating peer metadata from HTTP MX."); | ||
populatePeerInfo(info, info.filterState()); | ||
} | ||
if (is_grpc_ && (peer_read_ || end_stream)) { | ||
|
@@ -933,6 +968,7 @@ class IstioStatsFilter : public Http::PassThroughFilter, | |
peer_read_ = peerInfoRead(config_->reporter(), filter_state); | ||
// Report connection open once peer info is read or connection is closed. | ||
if (peer_read_ || end_stream) { | ||
ENVOY_LOG(trace, "Populating peer metadata from TCP MX."); | ||
populatePeerInfo(info, filter_state); | ||
tags_.push_back({context_.request_protocol_, context_.tcp_}); | ||
populateFlagsAndConnectionSecurity(info); | ||
|
@@ -977,9 +1013,9 @@ class IstioStatsFilter : public Http::PassThroughFilter, | |
const StreamInfo::FilterState& filter_state) { | ||
// Compute peer info with client-side fallbacks. | ||
absl::optional<Istio::Common::WorkloadMetadataObject> peer; | ||
const auto* object = peerInfo(config_->reporter(), filter_state); | ||
auto object = peerInfo(config_->reporter(), filter_state); | ||
if (object) { | ||
peer.emplace(*object); | ||
peer.emplace(object.value()); | ||
} else if (config_->reporter() == Reporter::ClientSidecar) { | ||
if (auto label_obj = extractEndpointMetadata(info); label_obj) { | ||
peer.emplace(label_obj.value()); | ||
|
@@ -1121,9 +1157,9 @@ class IstioStatsFilter : public Http::PassThroughFilter, | |
switch (config_->reporter()) { | ||
case Reporter::ServerGateway: { | ||
std::optional<Istio::Common::WorkloadMetadataObject> endpoint_peer; | ||
const auto* endpoint_object = peerInfo(Reporter::ClientSidecar, filter_state); | ||
auto endpoint_object = peerInfo(Reporter::ClientSidecar, filter_state); | ||
if (endpoint_object) { | ||
endpoint_peer.emplace(*endpoint_object); | ||
endpoint_peer.emplace(endpoint_object.value()); | ||
} | ||
tags_.push_back( | ||
{context_.destination_workload_, | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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.
Does this have control plane implications? Will calling filters have to specify a CEL formatter?
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.
this is used before v1.24, so i think it wont.