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

Re-order functions in stats_impl to group classes together #4004

Merged
merged 14 commits into from
Aug 1, 2018
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
1 change: 1 addition & 0 deletions include/envoy/stats/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

namespace Envoy {
namespace Event {

class Dispatcher;
}

Expand Down
1 change: 1 addition & 0 deletions source/common/config/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ envoy_cc_library(
"//source/common/protobuf:utility_lib",
"//source/common/singleton:const_singleton",
"//source/common/stats:stats_lib",
"//source/common/stats:tag_producer_lib",
"@envoy_api//envoy/api/v2/core:base_cc",
"@envoy_api//envoy/config/filter/network/http_connection_manager/v2:http_connection_manager_cc",
],
Expand Down
1 change: 1 addition & 0 deletions source/common/config/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "common/protobuf/protobuf.h"
#include "common/protobuf/utility.h"
#include "common/stats/stats_impl.h"
#include "common/stats/tag_producer_impl.h"

namespace Envoy {
namespace Config {
Expand Down
120 changes: 116 additions & 4 deletions source/common/stats/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,87 @@ load(
envoy_package()

envoy_cc_library(
name = "stats_lib",
srcs = ["stats_impl.cc"],
hdrs = ["stats_impl.h"],
name = "heap_stat_data_lib",
srcs = ["heap_stat_data.cc"],
hdrs = ["heap_stat_data.h"],
deps = [
":stat_data_allocator_lib",
"//source/common/common:assert_lib",
"//source/common/common:hash_lib",
"//source/common/common:thread_annotations",
"//source/common/common:thread_lib",
],
)

envoy_cc_library(
name = "histogram_lib",
srcs = ["histogram_impl.cc"],
hdrs = ["histogram_impl.h"],
external_deps = [
"abseil_optional",
"libcircllhist",
],
deps = [
":metric_impl_lib",
"//source/common/common:assert_lib",
"//source/common/common:hash_lib",
"//source/common/common:utility_lib",
],
)

envoy_cc_library(
name = "isolated_store_lib",
srcs = ["isolated_store_impl.cc"],
hdrs = ["isolated_store_impl.h"],
deps = [
":histogram_lib",
":stats_lib",
":stats_options_lib",
"//source/common/stats:heap_stat_data_lib",
],
)

envoy_cc_library(
name = "metric_impl_lib",
hdrs = ["metric_impl.h"],
deps = [
"//include/envoy/stats:stats_interface",
],
)

envoy_cc_library(
name = "raw_stat_data_lib",
srcs = ["raw_stat_data.cc"],
hdrs = ["raw_stat_data.h"],
deps = [
":stat_data_allocator_lib",
"//include/envoy/stats:stats_interface",
"//source/common/common:assert_lib",
"//source/common/common:hash_lib",
],
)

envoy_cc_library(
name = "stat_data_allocator_lib",
hdrs = ["stat_data_allocator.h"],
deps = [
":metric_impl_lib",
"//include/envoy/stats:stats_interface",
"//source/common/common:assert_lib",
],
)

envoy_cc_library(
name = "stats_lib",
srcs = ["stats_impl.cc"],
hdrs = ["stats_impl.h"],
deps = [
":histogram_lib",
":metric_impl_lib",
":raw_stat_data_lib",
":stats_options_lib",
":tag_extractor_lib",
":utility_lib",
"//include/envoy/common:time_interface",
"//include/envoy/server:options_interface",
"//include/envoy/stats:stats_interface",
Expand All @@ -26,19 +99,58 @@ envoy_cc_library(
"//source/common/common:perf_annotation_lib",
"//source/common/common:thread_annotations",
"//source/common/common:utility_lib",
"//source/common/config:well_known_names",
"//source/common/protobuf",
"//source/common/singleton:const_singleton",
"@envoy_api//envoy/config/metrics/v2:stats_cc",
],
)

envoy_cc_library(
name = "stats_options_lib",
hdrs = ["stats_options_impl.h"],
deps = [
"//include/envoy/stats:stats_interface",
],
)

envoy_cc_library(
name = "tag_extractor_lib",
srcs = ["tag_extractor_impl.cc"],
hdrs = ["tag_extractor_impl.h"],
deps = [
"//include/envoy/stats:stats_interface",
"//source/common/common:perf_annotation_lib",
],
)

envoy_cc_library(
name = "tag_producer_lib",
srcs = ["tag_producer_impl.cc"],
hdrs = ["tag_producer_impl.h"],
deps = [
":tag_extractor_lib",
"//include/envoy/stats:stats_interface",
"//source/common/common:perf_annotation_lib",
"//source/common/config:well_known_names",
"//source/common/protobuf",
"@envoy_api//envoy/config/metrics/v2:stats_cc",
],
)

envoy_cc_library(
name = "thread_local_store_lib",
srcs = ["thread_local_store.cc"],
hdrs = ["thread_local_store.h"],
deps = [
":heap_stat_data_lib",
":stats_lib",
":tag_producer_lib",
"//include/envoy/thread_local:thread_local_interface",
],
)

envoy_cc_library(
name = "utility_lib",
srcs = ["utility.cc"],
hdrs = ["utility.h"],
)
49 changes: 49 additions & 0 deletions source/common/stats/heap_stat_data.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "common/stats/heap_stat_data.h"

#include "common/common/lock_guard.h"
#include "common/common/thread.h"

namespace Envoy {
namespace Stats {

HeapStatData::HeapStatData(absl::string_view key) : name_(key.data(), key.size()) {}

HeapStatDataAllocator::HeapStatDataAllocator() {}

HeapStatDataAllocator::~HeapStatDataAllocator() { ASSERT(stats_.empty()); }

HeapStatData* HeapStatDataAllocator::alloc(absl::string_view name) {
// Any expected truncation of name is done at the callsite. No truncation is
// required to use this allocator.
auto data = std::make_unique<HeapStatData>(name);
Thread::ReleasableLockGuard lock(mutex_);
auto ret = stats_.insert(data.get());
HeapStatData* existing_data = *ret.first;
lock.release();

if (ret.second) {
return data.release();
}
++existing_data->ref_count_;
return existing_data;
}

void HeapStatDataAllocator::free(HeapStatData& data) {
ASSERT(data.ref_count_ > 0);
if (--data.ref_count_ > 0) {
return;
}

{
Thread::LockGuard lock(mutex_);
size_t key_removed = stats_.erase(&data);
ASSERT(key_removed == 1);
}

delete &data;
}

template class StatDataAllocatorImpl<HeapStatData>;

} // namespace Stats
} // namespace Envoy
75 changes: 75 additions & 0 deletions source/common/stats/heap_stat_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#pragma once

#include <cstdint>
#include <string>
#include <unordered_set>

#include "common/common/hash.h"
#include "common/common/thread.h"
#include "common/common/thread_annotations.h"
#include "common/stats/stat_data_allocator.h"

namespace Envoy {
namespace Stats {

/**
* This structure is an alternate backing store for both CounterImpl and GaugeImpl. It is designed
* so that it can be allocated efficiently from the heap on demand.
*/
struct HeapStatData {
explicit HeapStatData(absl::string_view key);

/**
* @returns absl::string_view the name as a string_view.
*/
absl::string_view key() const { return name_; }

std::atomic<uint64_t> value_{0};
std::atomic<uint64_t> pending_increment_{0};
std::atomic<uint16_t> flags_{0};
std::atomic<uint16_t> ref_count_{1};
std::string name_;
};

/**
* Implementation of StatDataAllocator using a pure heap-based strategy, so that
* Envoy implementations that do not require hot-restart can use less memory.
*/
class HeapStatDataAllocator : public StatDataAllocatorImpl<HeapStatData> {
public:
HeapStatDataAllocator();
~HeapStatDataAllocator();

// StatDataAllocatorImpl
HeapStatData* alloc(absl::string_view name) override;
void free(HeapStatData& data) override;

// StatDataAllocator
bool requiresBoundedStatNameSize() const override { return false; }

private:
struct HeapStatHash_ {
size_t operator()(const HeapStatData* a) const { return HashUtil::xxHash64(a->key()); }
};
struct HeapStatCompare_ {
bool operator()(const HeapStatData* a, const HeapStatData* b) const {
return (a->key() == b->key());
}
};

// TODO(jmarantz): See https://github.com/envoyproxy/envoy/pull/3927 and
// https://github.com/envoyproxy/envoy/issues/3585, which can help reorganize
// the heap stats using a ref-counted symbol table to compress the stat strings.
typedef std::unordered_set<HeapStatData*, HeapStatHash_, HeapStatCompare_> StatSet;

// An unordered set of HeapStatData pointers which keys off the key()
// field in each object. This necessitates a custom comparator and hasher.
StatSet stats_ GUARDED_BY(mutex_);
// A mutex is needed here to protect the stats_ object from both alloc() and free() operations.
// Although alloc() operations are called under existing locking, free() operations are made from
// the destructors of the individual stat objects, which are not protected by locks.
Thread::MutexBasicLockable mutex_;
};

} // namespace Stats
} // namespace Envoy
49 changes: 49 additions & 0 deletions source/common/stats/histogram_impl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "common/stats/histogram_impl.h"

#include <algorithm>
#include <string>

#include "common/common/utility.h"

//#include "common/stats/utility.h"

#include "absl/strings/str_join.h"

namespace Envoy {
namespace Stats {

HistogramStatisticsImpl::HistogramStatisticsImpl(const histogram_t* histogram_ptr)
: computed_quantiles_(supportedQuantiles().size(), 0.0) {
hist_approx_quantile(histogram_ptr, supportedQuantiles().data(), supportedQuantiles().size(),
computed_quantiles_.data());
}

const std::vector<double>& HistogramStatisticsImpl::supportedQuantiles() const {
static const std::vector<double> supported_quantiles = {0, 0.25, 0.5, 0.75, 0.90,
0.95, 0.99, 0.999, 1};
return supported_quantiles;
}

std::string HistogramStatisticsImpl::summary() const {
std::vector<std::string> summary;
const std::vector<double>& supported_quantiles_ref = supportedQuantiles();
summary.reserve(supported_quantiles_ref.size());
for (size_t i = 0; i < supported_quantiles_ref.size(); ++i) {
summary.push_back(
fmt::format("P{}: {}", 100 * supported_quantiles_ref[i], computed_quantiles_[i]));
}
return absl::StrJoin(summary, ", ");
}

/**
* Clears the old computed values and refreshes it with values computed from passed histogram.
*/
void HistogramStatisticsImpl::refresh(const histogram_t* new_histogram_ptr) {
std::fill(computed_quantiles_.begin(), computed_quantiles_.end(), 0.0);
ASSERT(supportedQuantiles().size() == computed_quantiles_.size());
hist_approx_quantile(new_histogram_ptr, supportedQuantiles().data(), supportedQuantiles().size(),
computed_quantiles_.data());
}

} // namespace Stats
} // namespace Envoy
Loading