1
#pragma once
2

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

            
8
#include "envoy/common/optref.h"
9
#include "envoy/config/typed_config.h"
10
#include "envoy/server/tracer_config.h"
11
#include "envoy/tracing/trace_context.h"
12

            
13
#include "source/extensions/tracers/opentelemetry/otlp_utils.h"
14

            
15
#include "absl/types/optional.h"
16

            
17
namespace Envoy {
18
namespace Extensions {
19
namespace Tracers {
20
namespace OpenTelemetry {
21

            
22
class SpanContext;
23

            
24
enum class Decision {
25
  // IsRecording will be false, the Span will not be recorded and all events and attributes will be
26
  // dropped.
27
  Drop,
28
  // IsRecording will be true, but the Sampled flag MUST NOT be set.
29
  RecordOnly,
30
  // IsRecording will be true and the Sampled flag MUST be set.
31
  RecordAndSample
32
};
33

            
34
struct SamplingResult {
35
  /// @see Decision
36
  Decision decision;
37
  // A set of span Attributes that will also be added to the Span. Can be nullptr.
38
  std::unique_ptr<const OtelAttributes> attributes;
39
  // A Tracestate that will be associated with the Span. If the sampler
40
  // returns an empty Tracestate here, the Tracestate will be cleared, so samplers SHOULD normally
41
  // return the passed-in Tracestate if they do not intend to change it
42
  std::string tracestate;
43

            
44
303
  inline bool isRecording() const {
45
303
    return decision == Decision::RecordOnly || decision == Decision::RecordAndSample;
46
303
  }
47

            
48
1333
  inline bool isSampled() const { return decision == Decision::RecordAndSample; }
49
};
50

            
51
/**
52
 * @brief The base type for all samplers
53
 * see https://opentelemetry.io/docs/specs/otel/trace/sdk/#sampler
54
 *
55
 */
56
class Sampler {
57
public:
58
507
  virtual ~Sampler() = default;
59

            
60
  /**
61
   * @brief Decides if a trace should be sampled.
62
   *
63
   * @param parent_context Span context describing the parent span. The Span's SpanContext may be
64
   * invalid to indicate a root span.
65
   * @param trace_id Trace id of the Span to be created. If the parent SpanContext contains a valid
66
   * TraceId, they MUST always match.
67
   * @param name Name of the Span to be created.
68
   * @param spankind Span kind of the Span to be created.
69
   * @param trace_context TraceContext containing potential initial span attributes
70
   * @param links Collection of links that will be associated with the Span to be created.
71
   * @return SamplingResult @see SamplingResult
72
   */
73
  virtual SamplingResult shouldSample(const StreamInfo::StreamInfo& stream_info,
74
                                      const absl::optional<SpanContext> parent_context,
75
                                      const std::string& trace_id, const std::string& name,
76
                                      OTelSpanKind spankind,
77
                                      OptRef<const Tracing::TraceContext> trace_context,
78
                                      const std::vector<SpanContext>& links) PURE;
79

            
80
  /**
81
   * @brief Returns a sampler description or name.
82
   *
83
   * @return The sampler name or short description with the configuration.
84
   */
85
  virtual std::string getDescription() const PURE;
86
};
87

            
88
using SamplerSharedPtr = std::shared_ptr<Sampler>;
89

            
90
/*
91
 * A factory for creating a sampler
92
 */
93
class SamplerFactory : public Envoy::Config::TypedFactory {
94
public:
95
5
  ~SamplerFactory() override = default;
96

            
97
  /**
98
   * @brief Creates a sampler
99
   * @param config The sampler protobuf config.
100
   * @param context The TracerFactoryContext.
101
   * @return SamplerSharedPtr A sampler.
102
   */
103
  virtual SamplerSharedPtr createSampler(const Protobuf::Message& config,
104
                                         Server::Configuration::TracerFactoryContext& context) PURE;
105

            
106
54
  std::string category() const override { return "envoy.tracers.opentelemetry.samplers"; }
107
};
108

            
109
using SamplerFactoryPtr = std::unique_ptr<SamplerFactory>;
110

            
111
} // namespace OpenTelemetry
112
} // namespace Tracers
113
} // namespace Extensions
114
} // namespace Envoy