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

Commit 861f45c

Browse files
author
Ian Sturdy
authored
Add an interface for registration to ViewDescriptor. (#61)
This makes it easier to discover how to register views for export, and removes one header from the primary client API (stats_exporter is only needed for unregistering views and writing exporters).
1 parent 5762736 commit 861f45c

File tree

10 files changed

+190
-131
lines changed

10 files changed

+190
-131
lines changed

opencensus/exporters/stats/prometheus/internal/prometheus_test_server.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ int main(int argc, char** argv) {
4444
.set_description(
4545
"Cumulative distribution of example.com/Foo/FooUsage broken down "
4646
"by 'key1' and 'key2'.");
47-
opencensus::stats::StatsExporter::AddView(view_descriptor);
47+
view_descriptor.RegisterForExport();
4848

4949
std::cout << "Access metrics on http://127.0.0.1:8080/metrics\n";
5050
while (true) {

opencensus/exporters/stats/stackdriver/internal/stackdriver_e2e_test.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ TEST_F(StackdriverE2eTest, OneView) {
166166
.set_description(
167167
"Cumulative sum of opencensus.io/TestMeasure broken down "
168168
"by 'key1' and 'key2'.");
169-
opencensus::stats::StatsExporter::AddView(view_descriptor);
169+
view_descriptor.RegisterForExport();
170170

171171
opencensus::stats::Record({{TestMeasure(), 1.0}},
172172
{{"key1", "v11"}, {"key2", "v21"}});
@@ -202,7 +202,7 @@ TEST_F(StackdriverE2eTest, LargeTest) {
202202
.set_description(
203203
"Cumulative count of opencensus.io/TestMeasure broken down "
204204
"by 'key1' and 'key2'.");
205-
opencensus::stats::StatsExporter::AddView(count_descriptor);
205+
count_descriptor.RegisterForExport();
206206

207207
const auto sum_descriptor =
208208
opencensus::stats::ViewDescriptor()
@@ -216,7 +216,7 @@ TEST_F(StackdriverE2eTest, LargeTest) {
216216
.set_description(
217217
"Cumulative sum of opencensus.io/TestMeasure broken down "
218218
"by 'key1' and 'key2'.");
219-
opencensus::stats::StatsExporter::AddView(sum_descriptor);
219+
sum_descriptor.RegisterForExport();
220220

221221
std::vector<::testing::Matcher<google::monitoring::v3::TimeSeries>>
222222
sum_matchers;

opencensus/stats/BUILD

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ cc_library(
3131
visibility = ["//visibility:public"],
3232
deps = [
3333
":core",
34-
":export",
3534
":recording",
3635
],
3736
)
@@ -63,7 +62,9 @@ cc_library(
6362
"internal/measure_registry.cc",
6463
"internal/measure_registry_impl.cc",
6564
"internal/set_aggregation_window.cc",
65+
"internal/stats_exporter.cc",
6666
"internal/stats_manager.cc",
67+
"internal/view.cc",
6768
"internal/view_data.cc",
6869
"internal/view_data_impl.cc",
6970
"internal/view_descriptor.cc",
@@ -75,11 +76,14 @@ cc_library(
7576
"internal/aggregation_window.h",
7677
"internal/measure_registry_impl.h",
7778
"internal/set_aggregation_window.h",
79+
"internal/stats_exporter_impl.h",
7880
"internal/stats_manager.h",
7981
"internal/view_data_impl.h",
8082
"measure.h",
8183
"measure_descriptor.h",
8284
"measure_registry.h",
85+
"stats_exporter.h",
86+
"view.h",
8387
"view_data.h",
8488
"view_descriptor.h",
8589
],
@@ -109,27 +113,6 @@ cc_library(
109113
],
110114
)
111115

112-
cc_library(
113-
name = "export",
114-
srcs = [
115-
"internal/stats_exporter.cc",
116-
"internal/view.cc",
117-
],
118-
hdrs = [
119-
"stats_exporter.h",
120-
"view.h",
121-
],
122-
copts = DEFAULT_COPTS,
123-
deps = [
124-
":core",
125-
"@com_google_absl//absl/base:core_headers",
126-
"@com_google_absl//absl/memory",
127-
"@com_google_absl//absl/strings",
128-
"@com_google_absl//absl/synchronization",
129-
"@com_google_absl//absl/time",
130-
],
131-
)
132-
133116
# Tests
134117
# ========================================================================= #
135118

@@ -182,7 +165,6 @@ cc_test(
182165
copts = TEST_COPTS,
183166
deps = [
184167
":core",
185-
":export",
186168
":recording",
187169
"@com_google_absl//absl/memory",
188170
"@com_google_absl//absl/time",
@@ -196,7 +178,6 @@ cc_test(
196178
copts = TEST_COPTS,
197179
deps = [
198180
":core",
199-
":export",
200181
":recording",
201182
"@com_google_absl//absl/types:optional",
202183
"@com_google_googletest//:gtest_main",
@@ -237,7 +218,6 @@ cc_binary(
237218
linkstatic = 1,
238219
deps = [
239220
":core",
240-
":export",
241221
":recording",
242222
"@com_google_absl//absl/memory",
243223
"@com_google_absl//absl/strings",

opencensus/stats/examples/exporter_example.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ TEST_F(ExporterExample, Distribution) {
9898

9999
// The order of view registration and exporter creation does not matter, as
100100
// long as both precede data recording.
101-
opencensus::stats::StatsExporter::AddView(sum_descriptor);
101+
sum_descriptor.RegisterForExport();
102102
ExampleExporter::Register();
103-
opencensus::stats::StatsExporter::AddView(count_descriptor);
103+
count_descriptor.RegisterForExport();
104104

105105
// Someone calls the Foo API, recording usage under example.com/Bar/FooUsage.
106106
UseFoo("foo1", 1);

opencensus/stats/internal/stats_exporter.cc

Lines changed: 61 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
// limitations under the License.
1414

1515
#include "opencensus/stats/stats_exporter.h"
16+
#include "opencensus/stats/internal/stats_exporter_impl.h"
1617

17-
#include <iostream>
1818
#include <thread> // NOLINT
1919
#include <utility>
2020
#include <vector>
@@ -24,107 +24,83 @@
2424
#include "absl/time/clock.h"
2525
#include "absl/time/time.h"
2626
#include "opencensus/stats/internal/aggregation_window.h"
27+
#include "opencensus/stats/view_data.h"
28+
#include "opencensus/stats/view_descriptor.h"
2729

2830
namespace opencensus {
2931
namespace stats {
3032

31-
class StatsExporterImpl {
32-
public:
33-
static StatsExporterImpl* Get() {
34-
static StatsExporterImpl* global_stats_exporter_impl =
35-
new StatsExporterImpl();
36-
return global_stats_exporter_impl;
37-
}
38-
39-
void AddView(const ViewDescriptor& view) {
40-
absl::MutexLock l(&mu_);
41-
views_[view.name()] = absl::make_unique<opencensus::stats::View>(view);
42-
}
43-
44-
void RemoveView(absl::string_view name) {
45-
absl::MutexLock l(&mu_);
46-
views_.erase(std::string(name));
47-
}
33+
// static
34+
StatsExporterImpl* StatsExporterImpl::Get() {
35+
static StatsExporterImpl* global_stats_exporter_impl =
36+
new StatsExporterImpl();
37+
return global_stats_exporter_impl;
38+
}
4839

49-
// Adds a handler, which cannot be subsequently removed (except by
50-
// ClearHandlersForTesting()). The background thread is started when the
51-
// first handler is registered.
52-
void RegisterPushHandler(std::unique_ptr<StatsExporter::Handler> handler) {
53-
absl::MutexLock l(&mu_);
54-
handlers_.push_back(std::move(handler));
55-
if (!thread_started_) {
56-
StartExportThread();
57-
}
58-
}
40+
void StatsExporterImpl::AddView(const ViewDescriptor& view) {
41+
absl::MutexLock l(&mu_);
42+
views_[view.name()] = absl::make_unique<opencensus::stats::View>(view);
43+
}
5944

60-
std::vector<std::pair<ViewDescriptor, ViewData>> GetViewData() {
61-
absl::ReaderMutexLock l(&mu_);
62-
std::vector<std::pair<ViewDescriptor, ViewData>> data;
63-
data.reserve(views_.size());
64-
for (const auto& view : views_) {
65-
data.emplace_back(view.second->descriptor(), view.second->GetData());
66-
}
67-
return data;
68-
}
45+
void StatsExporterImpl::RemoveView(absl::string_view name) {
46+
absl::MutexLock l(&mu_);
47+
views_.erase(std::string(name));
48+
}
6949

70-
void Export() {
71-
absl::ReaderMutexLock l(&mu_);
72-
for (const auto& view : views_) {
73-
SendToHandlers(view.second->descriptor(), view.second->GetData());
74-
}
50+
void StatsExporterImpl::RegisterPushHandler(
51+
std::unique_ptr<StatsExporter::Handler> handler) {
52+
absl::MutexLock l(&mu_);
53+
handlers_.push_back(std::move(handler));
54+
if (!thread_started_) {
55+
StartExportThread();
7556
}
57+
}
7658

77-
void ClearHandlersForTesting() {
78-
absl::MutexLock l(&mu_);
79-
handlers_.clear();
59+
std::vector<std::pair<ViewDescriptor, ViewData>>
60+
StatsExporterImpl::GetViewData() {
61+
absl::ReaderMutexLock l(&mu_);
62+
std::vector<std::pair<ViewDescriptor, ViewData>> data;
63+
data.reserve(views_.size());
64+
for (const auto& view : views_) {
65+
data.emplace_back(view.second->descriptor(), view.second->GetData());
8066
}
67+
return data;
68+
}
8169

82-
private:
83-
StatsExporterImpl() {}
84-
85-
void SendToHandlers(const ViewDescriptor& descriptor, const ViewData& data)
86-
SHARED_LOCKS_REQUIRED(mu_) {
87-
for (auto& handler : handlers_) {
88-
handler->ExportViewData(descriptor, data);
89-
}
70+
void StatsExporterImpl::Export() {
71+
absl::ReaderMutexLock l(&mu_);
72+
for (const auto& view : views_) {
73+
SendToHandlers(view.second->descriptor(), view.second->GetData());
9074
}
75+
}
9176

92-
void StartExportThread() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
93-
t_ = std::thread(&StatsExporterImpl::RunWorkerLoop, this);
94-
thread_started_ = true;
95-
}
77+
void StatsExporterImpl::ClearHandlersForTesting() {
78+
absl::MutexLock l(&mu_);
79+
handlers_.clear();
80+
}
9681

97-
// Loops forever, calling Export() every export_interval_.
98-
void RunWorkerLoop() {
99-
absl::Time next_export_time = absl::Now() + export_interval_;
100-
while (true) {
101-
// SleepFor() returns immediately when given a negative duration.
102-
absl::SleepFor(next_export_time - absl::Now());
103-
// In case the last export took longer than the export interval, we
104-
// calculate the next time from now.
105-
next_export_time = absl::Now() + export_interval_;
106-
Export();
107-
}
82+
void StatsExporterImpl::SendToHandlers(const ViewDescriptor& descriptor,
83+
const ViewData& data)
84+
SHARED_LOCKS_REQUIRED(mu_) {
85+
for (auto& handler : handlers_) {
86+
handler->ExportViewData(descriptor, data);
10887
}
88+
}
10989

110-
const absl::Duration export_interval_ = absl::Seconds(10);
111-
112-
mutable absl::Mutex mu_;
113-
114-
std::vector<std::unique_ptr<StatsExporter::Handler>> handlers_
115-
GUARDED_BY(mu_);
116-
std::unordered_map<std::string, std::unique_ptr<View>> views_ GUARDED_BY(mu_);
117-
118-
bool thread_started_ GUARDED_BY(mu_) = false;
119-
std::thread t_ GUARDED_BY(mu_);
120-
};
90+
void StatsExporterImpl::StartExportThread() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
91+
t_ = std::thread(&StatsExporterImpl::RunWorkerLoop, this);
92+
thread_started_ = true;
93+
}
12194

122-
void StatsExporter::AddView(const ViewDescriptor& view) {
123-
if (view.aggregation_window().type() ==
124-
AggregationWindow::Type::kCumulative) {
125-
StatsExporterImpl::Get()->AddView(view);
126-
} else {
127-
std::cerr << "Only cumulative views may be registered for export.\n";
95+
void StatsExporterImpl::RunWorkerLoop() {
96+
absl::Time next_export_time = absl::Now() + export_interval_;
97+
while (true) {
98+
// SleepFor() returns immediately when given a negative duration.
99+
absl::SleepFor(next_export_time - absl::Now());
100+
// In case the last export took longer than the export interval, we
101+
// calculate the next time from now.
102+
next_export_time = absl::Now() + export_interval_;
103+
Export();
128104
}
129105
}
130106

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright 2018, OpenCensus Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <thread> // NOLINT
16+
#include <utility>
17+
#include <vector>
18+
19+
#include "absl/synchronization/mutex.h"
20+
#include "absl/time/clock.h"
21+
#include "absl/time/time.h"
22+
#include "opencensus/stats/internal/aggregation_window.h"
23+
#include "opencensus/stats/stats_exporter.h"
24+
#include "opencensus/stats/view_data.h"
25+
#include "opencensus/stats/view_descriptor.h"
26+
27+
namespace opencensus {
28+
namespace stats {
29+
30+
class StatsExporterImpl {
31+
public:
32+
static StatsExporterImpl* Get();
33+
34+
void AddView(const ViewDescriptor& view);
35+
36+
void RemoveView(absl::string_view name);
37+
38+
// Adds a handler, which cannot be subsequently removed (except by
39+
// ClearHandlersForTesting()). The background thread is started when the
40+
// first handler is registered.
41+
void RegisterPushHandler(std::unique_ptr<StatsExporter::Handler> handler);
42+
43+
std::vector<std::pair<ViewDescriptor, ViewData>> GetViewData();
44+
45+
void Export();
46+
47+
void ClearHandlersForTesting();
48+
49+
private:
50+
StatsExporterImpl() {}
51+
52+
void SendToHandlers(const ViewDescriptor& descriptor, const ViewData& data)
53+
SHARED_LOCKS_REQUIRED(mu_);
54+
55+
void StartExportThread() EXCLUSIVE_LOCKS_REQUIRED(mu_);
56+
57+
// Loops forever, calling Export() every export_interval_.
58+
void RunWorkerLoop();
59+
60+
const absl::Duration export_interval_ = absl::Seconds(10);
61+
62+
mutable absl::Mutex mu_;
63+
64+
std::vector<std::unique_ptr<StatsExporter::Handler>> handlers_
65+
GUARDED_BY(mu_);
66+
std::unordered_map<std::string, std::unique_ptr<View>> views_ GUARDED_BY(mu_);
67+
68+
bool thread_started_ GUARDED_BY(mu_) = false;
69+
std::thread t_ GUARDED_BY(mu_);
70+
};
71+
72+
} // namespace stats
73+
} // namespace opencensus

0 commit comments

Comments
 (0)