1
#pragma once
2

            
3
#include <memory>
4
#include <string>
5
#include <vector>
6

            
7
#include "envoy/common/pure.h"
8
#include "envoy/stream_info/stream_info.h"
9
#include "envoy/tracing/trace_config.h"
10

            
11
namespace Envoy {
12
namespace Tracing {
13

            
14
class Span;
15
using SpanPtr = std::unique_ptr<Span>;
16

            
17
/**
18
 * The upstream service type.
19
 */
20
enum class ServiceType {
21
  // Service type is unknown.
22
  Unknown,
23
  // Service is treated as HTTP.
24
  Http,
25
  // Service is treated as GoogleGrpc.
26
  GoogleGrpc,
27
  // Service is treated as EnvoyGrpc.
28
  EnvoyGrpc
29
};
30

            
31
/**
32
 * Contains upstream context information essential for the injectContext process.
33
 *
34
 * @param host Optional reference to the upstream host description.
35
 * @param cluster Optional reference to the upstream cluster information.
36
 * @param service_type The type of service the upstream context relates to.
37
 * @param async_client_span Indicates if the injectContext originates from an asynchronous
38
 * client.
39
 */
40
struct UpstreamContext {
41
  UpstreamContext(const Upstream::HostDescription* host = nullptr,
42
                  const Upstream::ClusterInfo* cluster = nullptr,
43
                  const ServiceType service_type = ServiceType::Unknown,
44
                  const bool async_client_span = false)
45
51902
      : host_(makeOptRefFromPtr(host)), cluster_(makeOptRefFromPtr(cluster)),
46
51902
        service_type_(service_type), async_client_span_(async_client_span) {}
47

            
48
  OptRef<const Upstream::HostDescription> host_;
49
  OptRef<const Upstream::ClusterInfo> cluster_;
50
  const ServiceType service_type_;
51

            
52
  // TODO(botengyao): further distinction for the shared upstream code path can be
53
  // added if needed. Setting this flag to true only means it is called from async
54
  // client at current stage.
55
  const bool async_client_span_;
56
};
57

            
58
/**
59
 * Basic abstraction for span.
60
 */
61
class Span {
62
public:
63
18247
  virtual ~Span() = default;
64

            
65
  /**
66
   * Set the operation name.
67
   * @param operation the operation name
68
   */
69
  virtual void setOperation(absl::string_view operation) PURE;
70

            
71
  /**
72
   * Attach metadata to a Span, to be handled in an implementation-dependent fashion.
73
   * @param name the name of the tag
74
   * @param value the value to associate with the tag
75
   */
76
  virtual void setTag(absl::string_view name, absl::string_view value) PURE;
77

            
78
  /**
79
   * Record an event associated with a span, to be handled in an implementation-dependent fashion.
80
   * @param timestamp the time of the event.
81
   * @param event the name of the event.
82
   */
83
  virtual void log(SystemTime timestamp, const std::string& event) PURE;
84

            
85
  /**
86
   * Capture the final duration for this Span and carry out any work necessary to complete it.
87
   * Once this method is called, the Span may be safely discarded.
88
   */
89
  virtual void finishSpan() PURE;
90

            
91
  /**
92
   * Mutate the provided headers with the context necessary to propagate this
93
   * (implementation-specific) trace.
94
   * @param request_headers the headers to which propagation context will be added
95
   * @param upstream upstream context info
96
   */
97
  virtual void injectContext(TraceContext& trace_conext, const UpstreamContext& upstream) PURE;
98

            
99
  /**
100
   * Create and start a child Span, with this Span as its parent in the trace.
101
   * @param config the tracing configuration
102
   * @param name operation name captured by the spawned child
103
   * @param start_time initial start time for the operation captured by the child
104
   */
105
  virtual SpanPtr spawnChild(const Config& config, const std::string& name,
106
                             SystemTime start_time) PURE;
107

            
108
  /**
109
   * This method overrides any previous sampling decision associated with the trace instance.
110
   * If the sampled parameter is false, this span and any subsequent child spans
111
   * are not reported to the tracing system.
112
   * @param sampled whether the span and any subsequent child spans should be sampled
113
   */
114
  virtual void setSampled(bool sampled) PURE;
115

            
116
  /**
117
   * When the startSpan() of tracer is called, the Envoy tracing decision is passed to the
118
   * tracer to help determine whether the span should be sampled.
119
   *
120
   * But note that the tracer may have its own sampling decision logic (e.g. custom sampler,
121
   * external tracing context, etc.), and it may not use the Envoy tracing decision at all,
122
   * then the desicion may be ignored by the tracer.
123
   *
124
   * The method is used to return whether the Envoy tracing decision is used by the tracer
125
   * or not.
126
   *
127
   * When the Envoy tracing decision is refreshed becase route refresh or other reasons, if
128
   * the Envoy tracing decision is used by the tracer, the sampled value will be updated
129
   * by the HTTP connection manager based on the new Envoy tracing decision.
130
   */
131
  virtual bool useLocalDecision() const PURE;
132

            
133
  /**
134
   * Retrieve a key's value from the span's baggage.
135
   * This baggage data could've been set by this span or any parent spans.
136
   * @param key baggage key
137
   * @return the baggage's value for the given input key
138
   */
139
  virtual std::string getBaggage(absl::string_view key) PURE;
140

            
141
  /**
142
   * Set a key/value pair in the current span's baggage.
143
   * All subsequent child spans will have access to this baggage.
144
   * @param key baggage key
145
   * @param key baggage value
146
   */
147
  virtual void setBaggage(absl::string_view key, absl::string_view value) PURE;
148

            
149
  /**
150
   * Retrieve the trace ID associated with this span.
151
   * The trace id may be generated for this span, propagated by parent spans, or
152
   * not created yet.
153
   * @return trace ID
154
   */
155
  virtual std::string getTraceId() const PURE;
156

            
157
  /**
158
   * Retrieve the span's identifier.
159
   * @return span ID as a hex string
160
   */
161
  virtual std::string getSpanId() const PURE;
162
};
163

            
164
/**
165
 * Tracing driver is responsible for span creation.
166
 */
167
class Driver {
168
public:
169
177
  virtual ~Driver() = default;
170

            
171
  /**
172
   * Start driver specific span.
173
   */
174
  virtual SpanPtr startSpan(const Config& config, TraceContext& trace_context,
175
                            const StreamInfo::StreamInfo& stream_info,
176
                            const std::string& operation_name,
177
                            Tracing::Decision tracing_decision) PURE;
178
};
179

            
180
using DriverPtr = std::unique_ptr<Driver>;
181
using DriverSharedPtr = std::shared_ptr<Driver>;
182

            
183
} // namespace Tracing
184
} // namespace Envoy