1
#pragma once
2

            
3
#include <memory>
4

            
5
#include "envoy/tracing/trace_driver.h"
6

            
7
#include "source/common/tracing/common_values.h"
8
#include "source/common/tracing/null_span_impl.h"
9
#include "source/common/tracing/trace_context_impl.h"
10
#include "source/extensions/tracers/skywalking/trace_segment_reporter.h"
11

            
12
#include "cpp2sky/tracing_context.h"
13
#include "cpp2sky/well_known_names.h"
14

            
15
namespace Envoy {
16
namespace Extensions {
17
namespace Tracers {
18
namespace SkyWalking {
19

            
20
using cpp2sky::TracingContextSharedPtr;
21
using cpp2sky::TracingSpanSharedPtr;
22

            
23
const Tracing::TraceContextHandler& skywalkingPropagationHeaderKey();
24

            
25
class Tracer {
26
public:
27
  Tracer(TraceSegmentReporterPtr reporter);
28

            
29
  /*
30
   * Report trace segment data to backend tracing service.
31
   *
32
   * @param segment_context The segment context.
33
   */
34
  void sendSegment(TracingContextSharedPtr tracing_context);
35

            
36
  /*
37
   * Create a new span based on the segment context and parent span.
38
   *
39
   * @param name Operation name of span.
40
   * @param tracing_context The SkyWalking tracing context. The newly created span belongs to this
41
   * context.
42
   *
43
   * @return The unique ptr to the newly created span.
44
   */
45
  Tracing::SpanPtr startSpan(absl::string_view name, absl::string_view protocol,
46
                             TracingContextSharedPtr tracing_context);
47

            
48
private:
49
  TraceSegmentReporterPtr reporter_;
50
};
51

            
52
using TracerPtr = std::unique_ptr<Tracer>;
53

            
54
class Span : public Tracing::Span {
55
public:
56
  Span(absl::string_view name, absl::string_view protocol, TracingContextSharedPtr tracing_context,
57
       Tracer& parent_tracer)
58
8
      : parent_tracer_(parent_tracer), tracing_context_(tracing_context),
59
8
        span_entity_(tracing_context_->createEntrySpan()) {
60
8
    span_entity_->startSpan({name.data(), name.size()});
61
8
    skywalking::v3::SpanLayer layer;
62
8
    if (absl::StrContains(protocol, "HTTP")) {
63
      // TraceContext.protocol of http is parsed from http message, which value could be HTTP/1.1,
64
      // etc.
65
1
      layer = skywalking::v3::SpanLayer::Http;
66
7
    } else if (!skywalking::v3::SpanLayer_Parse(std::string(protocol), &layer)) {
67
6
      layer = skywalking::v3::SpanLayer::Unknown;
68
6
    }
69
8
    span_entity_->setSpanLayer(layer);
70
8
  }
71
  Span(absl::string_view name, skywalking::v3::SpanLayer span_layer, Span& parent_span,
72
       TracingContextSharedPtr tracing_context, Tracer& parent_tracer)
73
3
      : parent_tracer_(parent_tracer), tracing_context_(tracing_context),
74
3
        span_entity_(tracing_context_->createExitSpan(parent_span.spanEntity())) {
75
3
    span_entity_->startSpan({name.data(), name.size()});
76
3
    span_entity_->setSpanLayer(span_layer);
77
3
  }
78

            
79
  // Tracing::Span
80
1
  void setOperation(absl::string_view) override {}
81
  void setTag(absl::string_view name, absl::string_view value) override;
82
  void log(SystemTime timestamp, const std::string& event) override;
83
  void finishSpan() override;
84
  void injectContext(Tracing::TraceContext& trace_context,
85
                     const Tracing::UpstreamContext& upstream) override;
86
  Tracing::SpanPtr spawnChild(const Tracing::Config& config, const std::string& name,
87
                              SystemTime start_time) override;
88
  void setSampled(bool do_sample) override;
89
  // TODO(wbpcode): The SkyWalking tracer may create NullSpanImpl if the tracing decision is not to
90
  // trace. That make it is impossible to update the sampling decision. So, the useLocalDecision()
91
  // always return false now. This should be resolved in the future.
92
1
  bool useLocalDecision() const override { return false; }
93
1
  std::string getBaggage(absl::string_view) override { return EMPTY_STRING; }
94
1
  void setBaggage(absl::string_view, absl::string_view) override {}
95
1
  std::string getTraceId() const override { return tracing_context_->traceId(); }
96
1
  std::string getSpanId() const override { return EMPTY_STRING; }
97

            
98
8
  const TracingContextSharedPtr tracingContext() { return tracing_context_; }
99
39
  const TracingSpanSharedPtr spanEntity() { return span_entity_; }
100

            
101
private:
102
  Tracer& parent_tracer_;
103
  TracingContextSharedPtr tracing_context_;
104
  TracingSpanSharedPtr span_entity_;
105
};
106

            
107
} // namespace SkyWalking
108
} // namespace Tracers
109
} // namespace Extensions
110
} // namespace Envoy