Skip to content

Commit 6b9bbb9

Browse files
authored
apply propagated skip-analysis status to segment context and span creation (#48)
* apply propagated sampling status to segment context and span creation * improve test * always sampling * always sampling and introduce skipanalysis
1 parent 9e4af4e commit 6b9bbb9

File tree

13 files changed

+227
-161
lines changed

13 files changed

+227
-161
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ to avoid undefined behavior.
107107
SegmentContextPtr current_segment = createSegmentContext(config);
108108
CurrentSegmentSpanPtr current_span = current_segment->createCurrentSegmentRootSpan();
109109
110-
current_span->startSpan();
111-
current_span->setOperationName("sample_workload");
110+
current_span->startSpan("sample_workload");
112111
current_span->endSpan();
113112
114113
tracer->sendSegment(std::move(current_segment));

cpp2sky/propagation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class SpanContext {
2727
* Get the status of sample on SKyWalking.
2828
* It indicates whether current context should send or not.
2929
*/
30-
virtual bool mustSend() const = 0;
30+
virtual bool sample() const = 0;
3131

3232
/**
3333
* Get parent's trace ID. This value must be unique globally.

cpp2sky/segment_context.h

Lines changed: 32 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ class CurrentSegmentSpan {
3434
*/
3535
virtual SpanObject createSpanObject() = 0;
3636

37-
/**
38-
* Get sampling status. If true, spans belongs to this segment will be sent to
39-
* OAP.
40-
*/
41-
virtual bool samplingStatus() const = 0;
42-
4337
/**
4438
* Get span ID.
4539
*/
@@ -114,9 +108,11 @@ class CurrentSegmentSpan {
114108
/**
115109
* Set start time to calculate execution time.
116110
*/
117-
virtual void startSpan() = 0;
118-
virtual void startSpan(TimePoint<SystemTime> current_time) = 0;
119-
virtual void startSpan(TimePoint<SteadyTime> current_time) = 0;
111+
virtual void startSpan(std::string operation_name) = 0;
112+
virtual void startSpan(std::string operation_name,
113+
TimePoint<SystemTime> current_time) = 0;
114+
virtual void startSpan(std::string operation_name,
115+
TimePoint<SteadyTime> current_time) = 0;
120116

121117
/**
122118
* Set end time to calculate execution time.
@@ -125,16 +121,6 @@ class CurrentSegmentSpan {
125121
virtual void endSpan(TimePoint<SystemTime> current_time) = 0;
126122
virtual void endSpan(TimePoint<SteadyTime> current_time) = 0;
127123

128-
/**
129-
* Set operation name for this span (lvalue)
130-
*/
131-
virtual void setOperationName(const std::string& operation_name) = 0;
132-
133-
/**
134-
* Set operation name for this span (rvalue)
135-
*/
136-
virtual void setOperationName(std::string&& operation_name) = 0;
137-
138124
/**
139125
* Set peer address for this span (lvalue)
140126
*/
@@ -160,31 +146,27 @@ class CurrentSegmentSpan {
160146
/**
161147
* If error had caused on this span, This should be called.
162148
*/
163-
virtual void errorOccured() = 0;
149+
virtual void setErrorStatus() = 0;
164150

165151
/**
166152
* Determine whether to skip the analysis of this span. If we'd like to skip
167153
* analysis, this should be called.
168154
*/
169-
virtual void skipAnalysis() = 0;
170-
171-
/**
172-
* Set tag to current span. (lvalue)
173-
*/
174-
virtual void addTag(const std::string& key, const std::string& value) = 0;
155+
virtual void setSkipAnalysis() = 0;
175156

176157
/**
177-
* Set tag to current span. (rvalue)
158+
* Set tag to current span.
178159
*/
179-
virtual void addTag(std::string&& key, std::string&& value) = 0;
160+
virtual void addTag(std::string key, std::string value) = 0;
180161

181162
/**
182163
* Add log related with current span.
183-
* @param set_time To determine whether to set actual time or not.
184-
* This value is introduced for unit-test.
185164
*/
186-
virtual void addLog(const std::string& key, const std::string& value,
187-
bool set_time = true) = 0;
165+
virtual void addLog(std::string key, std::string value) = 0;
166+
virtual void addLog(std::string key, std::string value,
167+
TimePoint<SystemTime> current_time) = 0;
168+
virtual void addLog(std::string key, std::string value,
169+
TimePoint<SteadyTime> current_time) = 0;
188170

189171
/**
190172
* Set component ID.
@@ -195,11 +177,6 @@ class CurrentSegmentSpan {
195177
* This span had finished or not.
196178
*/
197179
virtual bool finished() const = 0;
198-
199-
/**
200-
* Change sampling status. If true, it will be sampled.
201-
*/
202-
virtual void setSamplingStatus(bool do_sample) = 0;
203180
};
204181

205182
using CurrentSegmentSpanPtr = std::shared_ptr<CurrentSegmentSpan>;
@@ -259,21 +236,32 @@ class SegmentContext {
259236
* Generate sw8 value to send SegmentRef.
260237
* @param parent Parent span that belongs to current segment.
261238
* @param target_address Target address to send request. For more detail:
262-
* @param sample If false, it means this trace shouldn't need to be sampled
263-
* and send to backend.
264239
* https://github.com/apache/skywalking-data-collect-protocol/blob/master/language-agent/Tracing.proto#L97-L101
265240
*/
241+
virtual std::string createSW8HeaderValue(
242+
CurrentSegmentSpanPtr parent, const std::string& target_address) = 0;
266243
virtual std::string createSW8HeaderValue(CurrentSegmentSpanPtr parent,
267-
std::string& target_address,
268-
bool sample = true) = 0;
269-
virtual std::string createSW8HeaderValue(CurrentSegmentSpanPtr parent,
270-
std::string&& target_address,
271-
bool sample = true) = 0;
244+
std::string&& target_address) = 0;
245+
// If you don't specify parent span, stored to current segment, it will be
246+
// selected newest span as parent span.
247+
virtual std::string createSW8HeaderValue(
248+
const std::string& target_address) = 0;
249+
virtual std::string createSW8HeaderValue(std::string&& target_address) = 0;
272250

273251
/**
274252
* Generate Apache SkyWalking native segment object.
275253
*/
276254
virtual SegmentObject createSegmentObject() = 0;
255+
256+
/**
257+
* If called, all spans belongs to this segment will be skipped analysis.
258+
*/
259+
virtual void setSkipAnalysis() = 0;
260+
261+
/**
262+
* Whether belonging span can be skipped analysis or not.
263+
*/
264+
virtual bool skipAnalysis() = 0;
277265
};
278266

279267
using SegmentContextPtr = std::shared_ptr<SegmentContext>;

example/sample.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ int main() {
4747
auto current_span = current_segment->createCurrentSegmentRootSpan();
4848

4949
// 4. Set info
50-
current_span->startSpan();
51-
current_span->setOperationName("/ping");
50+
current_span->startSpan("/ping");
5251
current_span->endSpan();
5352

5453
// 5. Send span data

example/sample_client.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ int main() {
4545
auto current_span = current_segment->createCurrentSegmentRootSpan();
4646

4747
// 4. Set info
48-
current_span->startSpan();
49-
current_span->setOperationName("/ping");
48+
current_span->startSpan("/ping");
5049

5150
httplib::Client cli("remote", 8082);
5251
httplib::Headers headers = {

source/propagation_impl.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ SpanContextImpl::SpanContextImpl(std::string_view header_value) {
6161
"Invalid span context format. sample field must be 0 or 1.");
6262
}
6363

64-
must_send_ = fields[0] == "1" ? true : false;
64+
// Sampling is always true
65+
sample_ = true;
6566
trace_id_ = Base64::decodeWithoutPadding(std::string_view(fields[1]));
6667
trace_segment_id_ = Base64::decodeWithoutPadding(std::string_view(fields[2]));
6768
span_id_ = std::stoi(fields[3]);

source/propagation_impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class SpanContextImpl : public SpanContext {
2626
public:
2727
SpanContextImpl(std::string_view header_value);
2828

29-
bool mustSend() const override { return must_send_; }
29+
bool sample() const override { return sample_; }
3030
const std::string& traceId() const override { return trace_id_; }
3131
const std::string& traceSegmentId() const override {
3232
return trace_segment_id_;
@@ -42,7 +42,7 @@ class SpanContextImpl : public SpanContext {
4242
private:
4343
// Based on
4444
// https://github.com/apache/skywalking/blob/master/docs/en/protocols/Skywalking-Cross-Process-Propagation-Headers-Protocol-v3.md
45-
bool must_send_ = false;
45+
bool sample_ = true;
4646
std::string trace_id_;
4747
std::string trace_segment_id_;
4848
int32_t span_id_;

source/segment_context_impl.cc

Lines changed: 65 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <string>
1818

19+
#include "cpp2sky/exception.h"
1920
#include "cpp2sky/time.h"
2021
#include "language-agent/Tracing.pb.h"
2122
#include "source/utils/base64.h"
@@ -40,6 +41,7 @@ SpanObject CurrentSegmentSpanImpl::createSpanObject() {
4041
obj.set_componentid(component_id_);
4142
obj.set_iserror(is_error_);
4243
obj.set_peer(peer_);
44+
obj.set_skipanalysis(skip_analysis_);
4345

4446
auto parent_span = parent_segment_context_.parentSpanContext();
4547
// Inject request parent to the current segment.
@@ -68,39 +70,51 @@ SpanObject CurrentSegmentSpanImpl::createSpanObject() {
6870
*entry = log;
6971
}
7072

71-
if (parent_segment_context_.parentSpanContextExtension() != nullptr) {
72-
if (parent_segment_context_.parentSpanContextExtension()->tracingMode() ==
73-
TracingMode::Skip) {
74-
obj.set_skipanalysis(true);
75-
}
76-
}
7773
return obj;
7874
}
7975

80-
void CurrentSegmentSpanImpl::addLog(const std::string& key,
81-
const std::string& value, bool set_time) {
76+
void CurrentSegmentSpanImpl::addLog(std::string key, std::string value) {
77+
assert(!finished_);
78+
auto now = TimePoint<SystemTime>();
79+
addLog(key, value, now);
80+
}
81+
82+
void CurrentSegmentSpanImpl::addLog(std::string key, std::string value,
83+
TimePoint<SystemTime> current_time) {
8284
assert(!finished_);
8385
Log l;
84-
if (set_time) {
85-
// SystemTimePoint now = SystemTime::now();
86-
// l.set_time(millisecondsFromEpoch(now));
87-
}
86+
l.set_time(current_time.fetch());
8887
auto* entry = l.add_data();
8988
entry->set_key(key);
9089
entry->set_value(value);
9190
logs_.emplace_back(l);
9291
}
9392

94-
void CurrentSegmentSpanImpl::startSpan() {
93+
void CurrentSegmentSpanImpl::addLog(std::string key, std::string value,
94+
TimePoint<SteadyTime> current_time) {
95+
assert(!finished_);
96+
Log l;
97+
l.set_time(current_time.fetch());
98+
auto* entry = l.add_data();
99+
entry->set_key(key);
100+
entry->set_value(value);
101+
logs_.emplace_back(l);
102+
}
103+
104+
void CurrentSegmentSpanImpl::startSpan(std::string operation_name) {
95105
auto now = TimePoint<SystemTime>();
96-
startSpan(now);
106+
startSpan(operation_name, now);
97107
}
98108

99-
void CurrentSegmentSpanImpl::startSpan(TimePoint<SystemTime> current_time) {
109+
void CurrentSegmentSpanImpl::startSpan(std::string operation_name,
110+
TimePoint<SystemTime> current_time) {
111+
operation_name_ = operation_name;
100112
start_time_ = current_time.fetch();
101113
}
102114

103-
void CurrentSegmentSpanImpl::startSpan(TimePoint<SteadyTime> current_time) {
115+
void CurrentSegmentSpanImpl::startSpan(std::string operation_name,
116+
TimePoint<SteadyTime> current_time) {
117+
operation_name_ = operation_name;
104118
start_time_ = current_time.fetch();
105119
}
106120

@@ -170,6 +184,10 @@ CurrentSegmentSpanPtr SegmentContextImpl::createCurrentSegmentSpan(
170184
}
171185
// It supports only HTTP request tracing.
172186
current_span->setSpanLayer(SpanLayer::Http);
187+
if (should_skip_analysis_) {
188+
current_span->setSkipAnalysis();
189+
}
190+
173191
spans_.push_back(current_span);
174192
return current_span;
175193
}
@@ -180,16 +198,33 @@ CurrentSegmentSpanPtr SegmentContextImpl::createCurrentSegmentRootSpan() {
180198
}
181199

182200
std::string SegmentContextImpl::createSW8HeaderValue(
183-
CurrentSegmentSpanPtr parent_span, std::string& target_address,
184-
bool sample) {
185-
std::string header_value;
201+
CurrentSegmentSpanPtr parent_span, const std::string& target_address) {
186202
if (parent_span == nullptr) {
187-
return header_value;
203+
if (spans_.empty()) {
204+
throw TracerException(
205+
"Can't create propagation header because current segment has no "
206+
"valid span.");
207+
}
208+
return encodeSpan(spans_.back(), target_address);
188209
}
210+
return encodeSpan(parent_span, target_address);
211+
}
212+
213+
std::string SegmentContextImpl::createSW8HeaderValue(
214+
CurrentSegmentSpanPtr parent_span, std::string&& target_address) {
215+
return createSW8HeaderValue(parent_span, target_address);
216+
}
217+
218+
std::string SegmentContextImpl::encodeSpan(CurrentSegmentSpanPtr parent_span,
219+
const std::string& target_address) {
220+
assert(parent_span);
221+
std::string header_value;
222+
189223
auto parent_spanid = std::to_string(parent_span->spanId());
190224
auto endpoint = spans_.front()->operationName();
191225

192-
header_value += sample ? "1-" : "0-";
226+
// always send to OAP
227+
header_value += "1-";
193228
header_value += Base64::encode(trace_id_) + "-";
194229
header_value += Base64::encode(trace_segment_id_) + "-";
195230
header_value += parent_spanid + "-";
@@ -201,12 +236,6 @@ std::string SegmentContextImpl::createSW8HeaderValue(
201236
return header_value;
202237
}
203238

204-
std::string SegmentContextImpl::createSW8HeaderValue(
205-
CurrentSegmentSpanPtr parent_span, std::string&& target_address,
206-
bool sample) {
207-
return createSW8HeaderValue(parent_span, target_address, sample);
208-
}
209-
210239
SegmentObject SegmentContextImpl::createSegmentObject() {
211240
SegmentObject obj;
212241
obj.set_traceid(trace_id_);
@@ -226,9 +255,8 @@ SegmentContextFactoryImpl::SegmentContextFactoryImpl(const TracerConfig& cfg)
226255
: service_name_(cfg.service_name()), instance_name_(cfg.instance_name()) {}
227256

228257
SegmentContextPtr SegmentContextFactoryImpl::create() {
229-
auto context = std::make_unique<SegmentContextImpl>(
230-
service_name_, instance_name_, random_generator_);
231-
return context;
258+
return std::make_unique<SegmentContextImpl>(service_name_, instance_name_,
259+
random_generator_);
232260
}
233261

234262
SegmentContextPtr SegmentContextFactoryImpl::create(
@@ -239,9 +267,13 @@ SegmentContextPtr SegmentContextFactoryImpl::create(
239267

240268
SegmentContextPtr SegmentContextFactoryImpl::create(
241269
SpanContextPtr span_context, SpanContextExtensionPtr ext_span_context) {
242-
return std::make_unique<SegmentContextImpl>(service_name_, instance_name_,
243-
span_context, ext_span_context,
244-
random_generator_);
270+
auto context = std::make_unique<SegmentContextImpl>(
271+
service_name_, instance_name_, span_context, ext_span_context,
272+
random_generator_);
273+
if (ext_span_context->tracingMode() == TracingMode::Skip) {
274+
context->setSkipAnalysis();
275+
}
276+
return context;
245277
}
246278

247279
} // namespace cpp2sky

0 commit comments

Comments
 (0)