Skip to content

Commit

Permalink
stats: allow combining configured tags with custom tags (envoyproxy#2…
Browse files Browse the repository at this point in the history
…7215)

Adds a way to create a StatNameTagVector that contains extracted tags names from both the configured and well defined tags, and custom provided tags. 

Fixes envoyproxy#27030

Risk Level: Low
Testing: Unit tests

Signed-off-by: ohadvano <[email protected]>
  • Loading branch information
ohadvano authored May 9, 2023
1 parent b896b6d commit eee6b6d
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 0 deletions.
21 changes: 21 additions & 0 deletions envoy/stats/store.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace Stats {

class Sink;
class SinkPredicates;
class StatNamePool;

/**
* Store keeps track of all Scopes created in it, and the Scopes manage
Expand Down Expand Up @@ -172,6 +173,26 @@ class Store {
* @return a scope of the given name.
*/
ScopeSharedPtr createScope(const std::string& name) { return rootScope()->createScope(name); }

/**
* Extracts tags from the name and appends them to the provided StatNameTagVector.
* The StatName for the extracted tags will be saved in the provided pool.
* @param name The stat name.
* @param pool The pool to create the tags in.
* @param stat_tags The stat name tags vector to append the tags to.
*/
virtual void extractAndAppendTags(StatName name, StatNamePool& pool,
StatNameTagVector& stat_tags) PURE;

/**
* Extracts tags from the name and appends them to the provided StatNameTagVector.
* The StatName for the extracted tags will be saved in the provided pool.
* @param name The stat name.
* @param pool The pool to create the tags in.
* @param stat_tags The stat name tags vector to append the tags to.
*/
virtual void extractAndAppendTags(absl::string_view name, StatNamePool& pool,
StatNameTagVector& stat_tags) PURE;
};

using StorePtr = std::unique_ptr<Store>;
Expand Down
8 changes: 8 additions & 0 deletions source/common/stats/isolated_store_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,14 @@ class IsolatedStoreImpl : public Store {
return constRootScope()->iterate(fn);
}

void extractAndAppendTags(StatName, StatNamePool&, StatNameTagVector&) override {
IS_ENVOY_BUG("Unexpected call to a function that is not yet implemented");
}

void extractAndAppendTags(absl::string_view, StatNamePool&, StatNameTagVector&) override {
IS_ENVOY_BUG("Unexpected call to a function that is not yet implemented");
}

protected:
/**
* Provides a hook for sub-classes to define how to create new scopes. When
Expand Down
14 changes: 14 additions & 0 deletions source/common/stats/thread_local_store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1075,5 +1075,19 @@ void ThreadLocalStoreImpl::setSinkPredicates(std::unique_ptr<SinkPredicates>&& s
}
}

void ThreadLocalStoreImpl::extractAndAppendTags(StatName name, StatNamePool& pool,
StatNameTagVector& stat_tags) {
extractAndAppendTags(symbolTable().toString(name), pool, stat_tags);
}

void ThreadLocalStoreImpl::extractAndAppendTags(absl::string_view name, StatNamePool& pool,
StatNameTagVector& stat_tags) {
TagVector tags;
tagProducer().produceTags(name, tags);
for (const auto& tag : tags) {
stat_tags.emplace_back(pool.add(tag.name_), pool.add(tag.value_));
}
}

} // namespace Stats
} // namespace Envoy
3 changes: 3 additions & 0 deletions source/common/stats/thread_local_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ class ThreadLocalStoreImpl : Logger::Loggable<Logger::Id::stats>, public StoreRo
void releaseHistogramCrossThread(uint64_t histogram_id);

const TagProducer& tagProducer() const { return *tag_producer_; }
void extractAndAppendTags(StatName name, StatNamePool& pool, StatNameTagVector& tags) override;
void extractAndAppendTags(absl::string_view name, StatNamePool& pool,
StatNameTagVector& tags) override;

private:
friend class ThreadLocalStoreTestingPeer;
Expand Down
78 changes: 78 additions & 0 deletions test/common/stats/thread_local_store_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,84 @@ TEST_F(StatsThreadLocalStoreTest, SharedScopes) {
tls_.shutdownThread();
}

TEST_F(StatsThreadLocalStoreTest, ExtractAndAppendTagsFixedValue) {
store_->initializeThreading(main_thread_dispatcher_, tls_);

envoy::config::metrics::v3::StatsConfig stats_config;
auto* tag_specifier = stats_config.add_stats_tags();
tag_specifier->set_tag_name("foo");
tag_specifier->set_fixed_value("bar");

store_->setTagProducer(std::make_unique<TagProducerImpl>(stats_config));

StatNamePool pool(symbol_table_);
StatNameTagVector tags{{pool.add("a"), pool.add("b")}};
store_->extractAndAppendTags(pool.add("c1"), pool, tags);

ASSERT_EQ(2, tags.size());
EXPECT_EQ("a", symbol_table_.toString(tags[0].first));
EXPECT_EQ("b", symbol_table_.toString(tags[0].second));
EXPECT_EQ("foo", symbol_table_.toString(tags[1].first));
EXPECT_EQ("bar", symbol_table_.toString(tags[1].second));
}

TEST_F(StatsThreadLocalStoreTest, ExtractAndAppendTagsRegexValueNoMatch) {
store_->initializeThreading(main_thread_dispatcher_, tls_);

envoy::config::metrics::v3::StatsConfig stats_config;
auto* tag_specifier = stats_config.add_stats_tags();
tag_specifier->set_tag_name("foo");
tag_specifier->set_regex("bar");

store_->setTagProducer(std::make_unique<TagProducerImpl>(stats_config));

StatNamePool pool(symbol_table_);
StatNameTagVector tags{{pool.add("a"), pool.add("b")}};
store_->extractAndAppendTags(pool.add("c1"), pool, tags);

ASSERT_EQ(1, tags.size());
EXPECT_EQ("a", symbol_table_.toString(tags[0].first));
EXPECT_EQ("b", symbol_table_.toString(tags[0].second));
}

TEST_F(StatsThreadLocalStoreTest, ExtractAndAppendTagsRegexValueWithMatch) {
store_->initializeThreading(main_thread_dispatcher_, tls_);

envoy::config::metrics::v3::StatsConfig stats_config;
auto* tag_specifier = stats_config.add_stats_tags();
tag_specifier->set_tag_name("foo_tag");
tag_specifier->set_regex("^foo.(.+)");

store_->setTagProducer(std::make_unique<TagProducerImpl>(stats_config));

StatNamePool pool(symbol_table_);
StatNameTagVector tags{{pool.add("a"), pool.add("b")}};
store_->extractAndAppendTags(pool.add("foo.bar"), pool, tags);

ASSERT_EQ(2, tags.size());
EXPECT_EQ("a", symbol_table_.toString(tags[0].first));
EXPECT_EQ("b", symbol_table_.toString(tags[0].second));
EXPECT_EQ("foo_tag", symbol_table_.toString(tags[1].first));
EXPECT_EQ("bar", symbol_table_.toString(tags[1].second));
}

TEST_F(StatsThreadLocalStoreTest, ExtractAndAppendTagsRegexBuiltinExpression) {
store_->initializeThreading(main_thread_dispatcher_, tls_);

envoy::config::metrics::v3::StatsConfig stats_config;
store_->setTagProducer(std::make_unique<TagProducerImpl>(stats_config));

StatNamePool pool(symbol_table_);
StatNameTagVector tags{{pool.add("a"), pool.add("b")}};
store_->extractAndAppendTags(pool.add("cluster.foo.bar"), pool, tags);

ASSERT_EQ(2, tags.size());
EXPECT_EQ("a", symbol_table_.toString(tags[0].first));
EXPECT_EQ("b", symbol_table_.toString(tags[0].second));
EXPECT_EQ("envoy.cluster_name", symbol_table_.toString(tags[1].first));
EXPECT_EQ("foo", symbol_table_.toString(tags[1].second));
}

class LookupWithStatNameTest : public ThreadLocalStoreNoMocksMixin, public testing::Test {};

TEST_F(LookupWithStatNameTest, All) {
Expand Down
8 changes: 8 additions & 0 deletions test/integration/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,14 @@ class TestIsolatedStoreImpl : public StoreRoot {
bool iterate(const IterateFn<Histogram>& fn) const override { return store_.iterate(fn); }
bool iterate(const IterateFn<TextReadout>& fn) const override { return store_.iterate(fn); }

void extractAndAppendTags(StatName, StatNamePool&, StatNameTagVector&) override {
IS_ENVOY_BUG("Unexpected call to a function that is not yet implemented");
};

void extractAndAppendTags(absl::string_view, StatNamePool&, StatNameTagVector&) override {
IS_ENVOY_BUG("Unexpected call to a function that is not yet implemented");
};

// Stats::StoreRoot
void addSink(Sink&) override {}
void setTagProducer(TagProducerPtr&&) override {}
Expand Down

0 comments on commit eee6b6d

Please sign in to comment.