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

Commit 560be5e

Browse files
authored
Make trace/ Exporter API consistent with the stats/ one. (#9)
Also: - Add sampler_test. - Replace Span's default constructor with BlankSpan(). - Add BlankSpan test. - Add FullSpanTest that verifies SpanData. - Initialize threads after the rest of the exporter, to avoid racing.
1 parent 6505dd1 commit 560be5e

16 files changed

+240
-129
lines changed

opencensus/stats/internal/stats_exporter.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,13 @@ class StatsExporterImpl {
7777
}
7878

7979
const absl::Duration export_interval_ = absl::Seconds(10);
80-
std::thread t_;
8180

8281
mutable absl::Mutex mu_;
8382

8483
std::vector<std::unique_ptr<StatsExporter::Handler>> handlers_
8584
GUARDED_BY(mu_);
8685
std::unordered_map<std::string, std::unique_ptr<View>> views_ GUARDED_BY(mu_);
86+
std::thread t_;
8787
};
8888

8989
void StatsExporter::AddView(const ViewDescriptor& view) {

opencensus/stats/stats_exporter.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ class StatsExporter final {
4343
// export to) and calls StatsExporter::RegisterHandler itself.
4444
class Handler {
4545
public:
46-
virtual ~Handler() {}
47-
46+
virtual ~Handler() = default;
4847
virtual void ExportViewData(const ViewDescriptor& descriptor,
4948
const ViewData& data) = 0;
5049
};

opencensus/trace/BUILD

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,18 @@ cc_test(
152152
],
153153
)
154154

155+
cc_test(
156+
name = "sampler_test",
157+
srcs = ["internal/sampler_test.cc"],
158+
deps = [
159+
":trace",
160+
"@com_google_absl//absl/strings",
161+
"@com_google_absl//absl/synchronization",
162+
"@com_google_absl//absl/time",
163+
"@com_google_googletest//:gtest_main",
164+
],
165+
)
166+
155167
cc_test(
156168
name = "span_test",
157169
srcs = ["internal/span_test.cc"],
@@ -201,6 +213,7 @@ cc_test(
201213
"@com_google_absl//absl/memory",
202214
"@com_google_absl//absl/strings",
203215
"@com_google_absl//absl/synchronization",
216+
"@com_google_absl//absl/time",
204217
"@com_google_googletest//:gtest_main",
205218
],
206219
)

opencensus/trace/exporter/span_exporter.h

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,17 @@ class SpanExporterImpl;
3030
class SpanExporter final {
3131
public:
3232
// Handlers allow different tracing services to export recorded data for
33-
// sampled spans in their own format.
34-
//
35-
// To export data, the Handler MUST be registered to the global SpanExporter
36-
// using RegisterHandler().
33+
// sampled spans in their own format. The exporter should provide a static
34+
// Register() method that takes any arguments needed by the exporter (e.g. a
35+
// URL to export to) and calls SpanExporter::RegisterHandler itself.
3736
class Handler {
3837
public:
3938
virtual ~Handler() = default;
40-
41-
private:
42-
friend class SpanExporterImpl;
43-
44-
// Exports sampled (see TraceOptions::IsSampled()) Spans using the immutable
45-
// SpanData representation.
46-
//
47-
// The implementation SHOULD NOT block the calling thread. It should execute
48-
// the export on a different thread if possible. This function must be
49-
// thread-safe.
5039
virtual void Export(const std::vector<SpanData>& spans) = 0;
5140
};
5241

53-
// Register a handler that's used to export SpanData for sampled Spans.
54-
static void Register(std::unique_ptr<Handler> handler);
42+
// This should only be called by Handler's Register() method.
43+
static void RegisterHandler(std::unique_ptr<Handler> handler);
5544
};
5645

5746
} // namespace exporter

opencensus/trace/internal/message_event.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ std::string MessageEvent::DebugString() const {
2727
"Type: ",
2828
(type_ == Type::RECEIVED) ? "RECEIVED"
2929
: ((type_ == Type::SENT) ? "SENT" : "UNKNOWN"),
30-
"\nMessage Id: ", id_, "\ncompressed message size: ", compressed_size_,
31-
"\nuncompressed message size: ", uncompressed_size_);
30+
" Message Id: ", id_, " compressed message size: ", compressed_size_,
31+
" uncompressed message size: ", uncompressed_size_);
3232
}
3333

3434
} // namespace exporter
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2017, 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 "opencensus/trace/sampler.h"
16+
17+
#include <atomic>
18+
19+
#include "absl/strings/str_cat.h"
20+
#include "absl/time/clock.h"
21+
#include "gtest/gtest.h"
22+
#include "opencensus/trace/span.h"
23+
#include "opencensus/trace/trace_params.h"
24+
25+
namespace opencensus {
26+
namespace trace {
27+
namespace {
28+
29+
// Example of a stateful sampler class.
30+
class SampleEveryNth : public Sampler {
31+
public:
32+
explicit SampleEveryNth(int nth) : state_(new State(nth)) {}
33+
34+
bool ShouldSample(const SpanContext* parent_context, bool has_remote_parent,
35+
const TraceId& trace_id, const SpanId& span_id,
36+
absl::string_view name,
37+
const std::vector<Span*>& parent_links) const override {
38+
// The shared_ptr is const, but the underlying State it points to isn't.
39+
return state_->Increment();
40+
}
41+
42+
private:
43+
class State {
44+
public:
45+
explicit State(int nth) : nth_(nth), current_(0) {}
46+
bool Increment() {
47+
int prev = current_.fetch_add(1, std::memory_order_acq_rel);
48+
return (prev + 1) % nth_ == 0;
49+
}
50+
51+
private:
52+
const int nth_;
53+
std::atomic<int> current_;
54+
};
55+
56+
std::shared_ptr<State> state_;
57+
};
58+
59+
TEST(SamplerTest, SampleNth) {
60+
static constexpr int kSampleRate = 4;
61+
SampleEveryNth sampler(kSampleRate);
62+
63+
for (int i = 1; i <= 100; ++i) {
64+
auto span = Span::StartSpan(absl::StrCat("MySpan", i), nullptr, {&sampler});
65+
if (i % kSampleRate == 0) {
66+
EXPECT_TRUE(span.IsSampled());
67+
} else {
68+
EXPECT_FALSE(span.IsSampled());
69+
}
70+
}
71+
}
72+
73+
} // namespace
74+
} // namespace trace
75+
} // namespace opencensus

opencensus/trace/internal/span.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ struct SpanGenerator {
111111
}
112112
};
113113

114+
Span Span::BlankSpan() { return Span(); }
115+
114116
Span Span::StartSpan(absl::string_view name, const Span* parent,
115117
const StartSpanOptions& options) {
116118
SpanContext parent_ctx;

opencensus/trace/internal/span_exporter.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ namespace opencensus {
2323
namespace trace {
2424
namespace exporter {
2525

26-
void SpanExporter::Register(std::unique_ptr<Handler> handler) {
27-
SpanExporterImpl::Get()->Register(std::move(handler));
26+
void SpanExporter::RegisterHandler(std::unique_ptr<Handler> handler) {
27+
SpanExporterImpl::Get()->RegisterHandler(std::move(handler));
2828
}
2929

3030
} // namespace exporter

opencensus/trace/internal/span_exporter_impl.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ namespace exporter {
2727
SpanExporterImpl* SpanExporterImpl::span_exporter_ = nullptr;
2828

2929
SpanExporterImpl* SpanExporterImpl::Get() {
30-
static SpanExporterImpl* span_exporter_impl = new SpanExporterImpl(
30+
static SpanExporterImpl* global_span_exporter_impl = new SpanExporterImpl(
3131
kDefaultBufferSize, absl::Milliseconds(kIntervalWaitTimeInMillis));
32-
return span_exporter_impl;
32+
return global_span_exporter_impl;
3333
}
3434

3535
// Create detached worker thread
@@ -40,9 +40,9 @@ SpanExporterImpl::SpanExporterImpl(uint32_t buffer_size,
4040
size_(0),
4141
t_(&SpanExporterImpl::RunWorkerLoop, this) {}
4242

43-
void SpanExporterImpl::Register(
43+
void SpanExporterImpl::RegisterHandler(
4444
std::unique_ptr<SpanExporter::Handler> handler) {
45-
absl::MutexLock lock(&handler_mu_);
45+
absl::MutexLock l(&handler_mu_);
4646
handlers_.emplace_back(std::move(handler));
4747
}
4848

opencensus/trace/internal/span_exporter_impl.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class SpanExporterImpl {
5252
void AddSpan(const std::shared_ptr<opencensus::trace::SpanImpl>& span_impl);
5353
// Registers a handler with the exporter. This is intended to be done at
5454
// initialization.
55-
void Register(std::unique_ptr<SpanExporter::Handler> handler);
55+
void RegisterHandler(std::unique_ptr<SpanExporter::Handler> handler);
5656

5757
static constexpr uint32_t kDefaultBufferSize = 64;
5858
static constexpr uint32_t kIntervalWaitTimeInMillis = 5000;
@@ -77,14 +77,13 @@ class SpanExporterImpl {
7777
// mutex within an AwaitWithTimeout, so we need to store the size in another
7878
// variable.
7979
std::atomic<size_t> size_;
80-
std::thread t_;
8180
mutable absl::Mutex span_mu_;
8281
mutable absl::Mutex handler_mu_;
83-
8482
std::vector<std::shared_ptr<opencensus::trace::SpanImpl>> spans_
8583
GUARDED_BY(span_mu_);
8684
std::vector<std::unique_ptr<SpanExporter::Handler>> handlers_
8785
GUARDED_BY(handler_mu_);
86+
std::thread t_;
8887
};
8988

9089
} // namespace exporter

0 commit comments

Comments
 (0)