Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/envoy/api/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ class Api {
* @return a reference to the TimeSource
*/
virtual TimeSource& timeSource() PURE;

/**
* @return a constant reference to the root Stats::Scope
*/
virtual const Stats::Scope& rootScope() PURE;
};

typedef std::unique_ptr<Api> ApiPtr;
Expand Down
24 changes: 24 additions & 0 deletions include/envoy/stats/scope.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#pragma once

#include <cstdint>
#include <functional>
#include <memory>

#include "envoy/common/pure.h"
#include "envoy/stats/histogram.h"
#include "envoy/stats/symbol_table.h"

#include "absl/types/optional.h"

namespace Envoy {
namespace Stats {

Expand Down Expand Up @@ -84,6 +87,27 @@ class Scope {
*/
virtual Histogram& histogram(const std::string& name) PURE;

/**
* @param The name of the stat, obtained from the SymbolTable.
* @return a reference to a counter within the scope's namespace, if it exists.
*/
virtual absl::optional<std::reference_wrapper<const Counter>>
findCounter(StatName name) const PURE;

/**
* @param The name of the stat, obtained from the SymbolTable.
* @return a reference to a gauge within the scope's namespace, if it exists.
*/
virtual absl::optional<std::reference_wrapper<const Gauge>> findGauge(StatName name) const PURE;

/**
* @param The name of the stat, obtained from the SymbolTable.
* @return a reference to a histogram within the scope's namespace, if it
* exists.
*/
virtual absl::optional<std::reference_wrapper<const Histogram>>
findHistogram(StatName name) const PURE;

/**
* @return a reference to the symbol table.
*/
Expand Down
7 changes: 4 additions & 3 deletions source/common/api/api_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
namespace Envoy {
namespace Api {

Impl::Impl(Thread::ThreadFactory& thread_factory, Stats::Store&, Event::TimeSystem& time_system,
Filesystem::Instance& file_system)
: thread_factory_(thread_factory), time_system_(time_system), file_system_(file_system) {}
Impl::Impl(Thread::ThreadFactory& thread_factory, Stats::Store& store,
Event::TimeSystem& time_system, Filesystem::Instance& file_system)
: thread_factory_(thread_factory), store_(store), time_system_(time_system),
file_system_(file_system) {}

Event::DispatcherPtr Impl::allocateDispatcher() {
return std::make_unique<Event::DispatcherImpl>(*this, time_system_);
Expand Down
4 changes: 3 additions & 1 deletion source/common/api/api_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Api {
*/
class Impl : public Api {
public:
Impl(Thread::ThreadFactory& thread_factory, Stats::Store&, Event::TimeSystem& time_system,
Impl(Thread::ThreadFactory& thread_factory, Stats::Store& store, Event::TimeSystem& time_system,
Filesystem::Instance& file_system);

// Api::Api
Expand All @@ -25,9 +25,11 @@ class Impl : public Api {
Thread::ThreadFactory& threadFactory() override { return thread_factory_; }
Filesystem::Instance& fileSystem() override { return file_system_; }
TimeSource& timeSource() override { return time_system_; }
const Stats::Scope& rootScope() override { return store_; }

private:
Thread::ThreadFactory& thread_factory_;
Stats::Store& store_;
Event::TimeSystem& time_system_;
Filesystem::Instance& file_system_;
};
Expand Down
20 changes: 20 additions & 0 deletions source/common/stats/isolated_store_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ template <class Base> class IsolatedStatsCache {
}

private:
friend class IsolatedStoreImpl;

absl::optional<std::reference_wrapper<const Base>> find(StatName name) const {
auto stat = stats_.find(name);
if (stat == stats_.end()) {
return absl::nullopt;
}
return std::cref(*stat->second.get());
}

StatNameHashMap<std::shared_ptr<Base>> stats_;
Allocator alloc_;
};
Expand All @@ -69,6 +79,16 @@ class IsolatedStoreImpl : public StoreImpl {
Histogram& histogram = histograms_.get(name);
return histogram;
}
absl::optional<std::reference_wrapper<const Counter>> findCounter(StatName name) const override {
return counters_.find(name);
}
absl::optional<std::reference_wrapper<const Gauge>> findGauge(StatName name) const override {
return gauges_.find(name);
}
absl::optional<std::reference_wrapper<const Histogram>>
findHistogram(StatName name) const override {
return histograms_.find(name);
}

// Stats::Store
std::vector<CounterSharedPtr> counters() const override { return counters_.toVector(); }
Expand Down
14 changes: 14 additions & 0 deletions source/common/stats/scope_prefixer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ Histogram& ScopePrefixer::histogramFromStatName(StatName name) {
return scope_.histogramFromStatName(StatName(stat_name_storage.get()));
}

absl::optional<std::reference_wrapper<const Counter>>
ScopePrefixer::findCounter(StatName name) const {
return scope_.findCounter(name);
}

absl::optional<std::reference_wrapper<const Gauge>> ScopePrefixer::findGauge(StatName name) const {
return scope_.findGauge(name);
}

absl::optional<std::reference_wrapper<const Histogram>>
ScopePrefixer::findHistogram(StatName name) const {
return scope_.findHistogram(name);
}

void ScopePrefixer::deliverHistogramToSinks(const Histogram& histograms, uint64_t val) {
scope_.deliverHistogramToSinks(histograms, val);
}
Expand Down
5 changes: 5 additions & 0 deletions source/common/stats/scope_prefixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ class ScopePrefixer : public Scope {
return histogramFromStatName(storage.statName());
}

absl::optional<std::reference_wrapper<const Counter>> findCounter(StatName name) const override;
absl::optional<std::reference_wrapper<const Gauge>> findGauge(StatName name) const override;
absl::optional<std::reference_wrapper<const Histogram>>
findHistogram(StatName name) const override;

const SymbolTable& symbolTable() const override { return scope_.symbolTable(); }
virtual SymbolTable& symbolTable() override { return scope_.symbolTable(); }

Expand Down
34 changes: 33 additions & 1 deletion source/common/stats/thread_local_store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ StatType& ThreadLocalStoreImpl::ScopeImpl::safeMakeStat(
StatMap<std::shared_ptr<StatType>>* tls_cache, StatNameHashSet* tls_rejected_stats,
StatType& null_stat) {

// We do name-rejections on the full name, prior to truncation.
if (tls_rejected_stats != nullptr &&
tls_rejected_stats->find(name) != tls_rejected_stats->end()) {
return null_stat;
Expand Down Expand Up @@ -358,6 +357,18 @@ StatType& ThreadLocalStoreImpl::ScopeImpl::safeMakeStat(
return **central_ref;
}

template <class StatType>
absl::optional<std::reference_wrapper<const StatType>>
ThreadLocalStoreImpl::ScopeImpl::findStatLockHeld(
StatName name, StatMap<std::shared_ptr<StatType>>& central_cache_map) const {
auto iter = central_cache_map.find(name);
if (iter == central_cache_map.end()) {
return absl::nullopt;
}

return std::cref(*iter->second.get());
}

Counter& ThreadLocalStoreImpl::ScopeImpl::counterFromStatName(StatName name) {
if (parent_.rejectsAll()) {
return parent_.null_counter_;
Expand Down Expand Up @@ -496,6 +507,27 @@ Histogram& ThreadLocalStoreImpl::ScopeImpl::histogramFromStatName(StatName name)
return **central_ref;
}

absl::optional<std::reference_wrapper<const Counter>>
ThreadLocalStoreImpl::ScopeImpl::findCounter(StatName name) const {
return findStatLockHeld<Counter>(name, central_cache_.counters_);
}

absl::optional<std::reference_wrapper<const Gauge>>
ThreadLocalStoreImpl::ScopeImpl::findGauge(StatName name) const {
return findStatLockHeld<Gauge>(name, central_cache_.gauges_);
}

absl::optional<std::reference_wrapper<const Histogram>>
ThreadLocalStoreImpl::ScopeImpl::findHistogram(StatName name) const {
auto iter = central_cache_.histograms_.find(name);
if (iter == central_cache_.histograms_.end()) {
return absl::nullopt;
}

std::shared_ptr<Histogram> histogram_ref(iter->second);
return std::cref(*histogram_ref.get());
}

Histogram& ThreadLocalStoreImpl::ScopeImpl::tlsHistogram(StatName name,
ParentHistogramImpl& parent) {
// tlsHistogram() is generally not called for a histogram that is rejected by
Expand Down
57 changes: 55 additions & 2 deletions source/common/stats/thread_local_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,40 @@ class ThreadLocalStoreImpl : Logger::Loggable<Logger::Id::stats>, public StoreRo
const SymbolTable& symbolTable() const override { return alloc_.symbolTable(); }
SymbolTable& symbolTable() override { return alloc_.symbolTable(); }
const TagProducer& tagProducer() const { return *tag_producer_; }

absl::optional<std::reference_wrapper<const Counter>> findCounter(StatName name) const override {
absl::optional<std::reference_wrapper<const Counter>> found_counter;
Thread::LockGuard lock(lock_);
for (ScopeImpl* scope : scopes_) {
found_counter = scope->findCounter(name);
if (found_counter.has_value()) {
return found_counter;
}
}
return absl::nullopt;
}
absl::optional<std::reference_wrapper<const Gauge>> findGauge(StatName name) const override {
absl::optional<std::reference_wrapper<const Gauge>> found_gauge;
Thread::LockGuard lock(lock_);
for (ScopeImpl* scope : scopes_) {
found_gauge = scope->findGauge(name);
if (found_gauge.has_value()) {
return found_gauge;
}
}
return absl::nullopt;
}
absl::optional<std::reference_wrapper<const Histogram>>
findHistogram(StatName name) const override {
absl::optional<std::reference_wrapper<const Histogram>> found_histogram;
Thread::LockGuard lock(lock_);
for (ScopeImpl* scope : scopes_) {
found_histogram = scope->findHistogram(name);
if (found_histogram.has_value()) {
return found_histogram;
}
}
return absl::nullopt;
}
// Stats::Store
std::vector<CounterSharedPtr> counters() const override;
std::vector<GaugeSharedPtr> gauges() const override;
Expand Down Expand Up @@ -239,6 +272,13 @@ class ThreadLocalStoreImpl : Logger::Loggable<Logger::Id::stats>, public StoreRo

NullGaugeImpl& nullGauge(const std::string&) override { return parent_.null_gauge_; }

// NOTE: The find methods assume that `name` is fully-qualified.
// Implementations will not add the scope prefix.
absl::optional<std::reference_wrapper<const Counter>> findCounter(StatName name) const override;
absl::optional<std::reference_wrapper<const Gauge>> findGauge(StatName name) const override;
absl::optional<std::reference_wrapper<const Histogram>>
findHistogram(StatName name) const override;

template <class StatType>
using MakeStatFn = std::function<std::shared_ptr<StatType>(StatDataAllocator&, StatName name,
absl::string_view tag_extracted_name,
Expand All @@ -262,6 +302,19 @@ class ThreadLocalStoreImpl : Logger::Loggable<Logger::Id::stats>, public StoreRo
StatMap<std::shared_ptr<StatType>>* tls_cache,
StatNameHashSet* tls_rejected_stats, StatType& null_stat);

/**
* Looks up an existing stat, populating the local cache if necessary. Does
* not check the TLS or rejects, and does not create a stat if it does not
* exist.
*
* @param name the full name of the stat (not tag extracted).
* @param central_cache_map a map from name to the desired object in the central cache.
* @return a reference to the stat, if it exists.
*/
template <class StatType>
absl::optional<std::reference_wrapper<const StatType>>
findStatLockHeld(StatName name, StatMap<std::shared_ptr<StatType>>& central_cache_map) const;

void extractTagsAndTruncate(StatName& name,
std::unique_ptr<StatNameManagedStorage>& truncated_name_storage,
std::vector<Tag>& tags, std::string& tag_extracted_name);
Expand All @@ -271,7 +324,7 @@ class ThreadLocalStoreImpl : Logger::Loggable<Logger::Id::stats>, public StoreRo
const uint64_t scope_id_;
ThreadLocalStoreImpl& parent_;
StatNameStorage prefix_;
CentralCacheEntry central_cache_;
mutable CentralCacheEntry central_cache_;
};

struct TlsCache : public ThreadLocal::ThreadLocalObject {
Expand Down
Loading