Skip to content
This repository has been archived by the owner on Jul 31, 2023. It is now read-only.

Commit

Permalink
Make stats export interval configurable at runtime. (#422)
Browse files Browse the repository at this point in the history
Fixes #412.
  • Loading branch information
g-easy authored Nov 29, 2019
1 parent eabb06a commit b14a5c0
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 12 deletions.
27 changes: 25 additions & 2 deletions opencensus/stats/internal/stats_exporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ StatsExporterImpl* StatsExporterImpl::Get() {
return global_stats_exporter_impl;
}

void StatsExporterImpl::SetInterval(absl::Duration interval) {
absl::MutexLock l(&mu_);
export_interval_ = interval;
}

absl::Time StatsExporterImpl::GetNextExportTime() const {
absl::MutexLock l(&mu_);
return absl::Now() + export_interval_;
}

void StatsExporterImpl::AddView(const ViewDescriptor& view) {
absl::MutexLock l(&mu_);
views_[view.name()] = absl::make_unique<opencensus::stats::View>(view);
Expand Down Expand Up @@ -90,31 +100,44 @@ void StatsExporterImpl::StartExportThread() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
}

void StatsExporterImpl::RunWorkerLoop() {
absl::Time next_export_time = absl::Now() + export_interval_;
absl::Time next_export_time = GetNextExportTime();
while (true) {
// SleepFor() returns immediately when given a negative duration.
absl::SleepFor(next_export_time - absl::Now());
// In case the last export took longer than the export interval, we
// calculate the next time from now.
next_export_time = absl::Now() + export_interval_;
next_export_time = GetNextExportTime();
Export();
}
}

// StatsExporter
// -------------

// static
void StatsExporter::SetInterval(absl::Duration interval) {
StatsExporterImpl::Get()->SetInterval(interval);
}

// static
void StatsExporter::RemoveView(absl::string_view name) {
StatsExporterImpl::Get()->RemoveView(name);
}

// static
void StatsExporter::RegisterPushHandler(std::unique_ptr<Handler> handler) {
StatsExporterImpl::Get()->RegisterPushHandler(std::move(handler));
}

// static
std::vector<std::pair<ViewDescriptor, ViewData>> StatsExporter::GetViewData() {
return StatsExporterImpl::Get()->GetViewData();
}

// static
void StatsExporter::ExportForTesting() { StatsExporterImpl::Get()->Export(); }

// static
void StatsExporter::ClearHandlersForTesting() {
StatsExporterImpl::Get()->ClearHandlersForTesting();
}
Expand Down
13 changes: 4 additions & 9 deletions opencensus/stats/internal/stats_exporter_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ namespace stats {
class StatsExporterImpl {
public:
static StatsExporterImpl* Get();

void SetInterval(absl::Duration interval);
absl::Time GetNextExportTime() const;
void AddView(const ViewDescriptor& view);

void RemoveView(absl::string_view name);

// Adds a handler, which cannot be subsequently removed (except by
Expand All @@ -44,27 +44,22 @@ class StatsExporterImpl {
void RegisterPushHandler(std::unique_ptr<StatsExporter::Handler> handler);

std::vector<std::pair<ViewDescriptor, ViewData>> GetViewData();

void Export();

void ClearHandlersForTesting();

private:
StatsExporterImpl() {}
StatsExporterImpl() = default;

void StartExportThread() EXCLUSIVE_LOCKS_REQUIRED(mu_);

// Loops forever, calling Export() every export_interval_.
void RunWorkerLoop();

const absl::Duration export_interval_ = absl::Seconds(10);

mutable absl::Mutex mu_;

absl::Duration export_interval_ GUARDED_BY(mu_) = absl::Seconds(10);
std::vector<std::unique_ptr<StatsExporter::Handler>> handlers_
GUARDED_BY(mu_);
std::unordered_map<std::string, std::unique_ptr<View>> views_ GUARDED_BY(mu_);

bool thread_started_ GUARDED_BY(mu_) = false;
std::thread t_ GUARDED_BY(mu_);
};
Expand Down
4 changes: 3 additions & 1 deletion opencensus/stats/internal/stats_exporter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ MeasureDouble TestMeasure() {

class StatsExporterTest : public ::testing::Test {
protected:
static void SetUpTestSuite() { StatsExporter::SetInterval(absl::Seconds(5)); }

void SetUp() {
// Access the measure to ensure it has been registered.
TestMeasure();
Expand Down Expand Up @@ -165,7 +167,7 @@ TEST_F(StatsExporterTest, TimedExport) {
std::vector<std::pair<ViewDescriptor, ViewData>> exported_data;
MockExporter::Register(&exported_data);
descriptor1_.RegisterForExport();
absl::SleepFor(absl::Seconds(11));
absl::SleepFor(absl::Seconds(6));
EXPECT_THAT(exported_data,
::testing::UnorderedElementsAre(::testing::Key(descriptor1_)));
}
Expand Down
9 changes: 9 additions & 0 deletions opencensus/stats/stats_exporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ namespace stats {
// StatsExporter is thread-safe.
class StatsExporter final {
public:
// Sets the interval between exports. Takes effect after the current export
// finishes.
//
// Warning: this API may be removed in future, in favor of configuring this
// per-exporter.
static void SetInterval(absl::Duration interval);

// Removes the view with 'name' from the registry, if one is registered.
static void RemoveView(absl::string_view name);

Expand All @@ -59,10 +66,12 @@ class StatsExporter final {
static std::vector<std::pair<ViewDescriptor, ViewData>> GetViewData();

private:
StatsExporter() = delete;
friend class StatsExporterTest;

// Forces immediate export of data.
static void ExportForTesting();

static void ClearHandlersForTesting();
};

Expand Down

0 comments on commit b14a5c0

Please sign in to comment.