]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/ext/include/opentelemetry/ext/zpages/tracez_data_aggregator.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / ext / include / opentelemetry / ext / zpages / tracez_data_aggregator.h
1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3
4 #pragma once
5
6 #include <array>
7 #include <atomic>
8 #include <condition_variable>
9 #include <list>
10 #include <map>
11 #include <mutex>
12 #include <string>
13 #include <thread>
14 #include <unordered_set>
15
16 #include "opentelemetry/ext/zpages/latency_boundaries.h"
17 #include "opentelemetry/ext/zpages/tracez_data.h"
18 #include "opentelemetry/ext/zpages/tracez_shared_data.h"
19 #include "opentelemetry/nostd/span.h"
20 #include "opentelemetry/nostd/string_view.h"
21 #include "opentelemetry/sdk/trace/span_data.h"
22 #include "opentelemetry/trace/canonical_code.h"
23
24 using opentelemetry::trace::CanonicalCode;
25
26 OPENTELEMETRY_BEGIN_NAMESPACE
27 namespace ext
28 {
29 namespace zpages
30 {
31 /**
32 * TracezDataAggregator object is responsible for collecting raw data and
33 * converting it to useful information that can be made available to
34 * display on the tracez zpage.
35 *
36 * When this object is created it starts a thread that calls a function
37 * periodically to update the aggregated data with new spans.
38 *
39 * The only exposed function is a getter that returns a copy of the aggregated
40 * data when requested. This function is ensured to be called in sequence to the
41 * aggregate spans function which is called periodically.
42 *
43 * TODO: Consider a singleton pattern for this class, not sure if multiple
44 * instances of this class should exist.
45 */
46 class TracezDataAggregator
47 {
48 public:
49 /**
50 * Constructor creates a thread that calls a function to aggregate span data
51 * at regular intervals.
52 * @param shared_data is the shared set of spans to expose.
53 * @param update_interval the time duration for updating the aggregated data.
54 */
55 TracezDataAggregator(std::shared_ptr<TracezSharedData> shared_data,
56 milliseconds update_interval = milliseconds(10));
57
58 /** Ends the thread set up in the constructor and destroys the object **/
59 ~TracezDataAggregator();
60
61 /**
62 * GetAggregatedTracezData returns a copy of the updated data.
63 * @returns a map with the span name as key and the tracez span data as value.
64 */
65 std::map<std::string, TracezData> GetAggregatedTracezData();
66
67 private:
68 /**
69 * AggregateSpans is the function that is called to update the aggregated data
70 * with newly completed and running span data
71 */
72 void AggregateSpans();
73
74 /**
75 * AggregateCompletedSpans is the function that is called to update the
76 * aggregation with the data of newly completed spans.
77 * @param completed_spans are the newly completed spans.
78 */
79 void AggregateCompletedSpans(std::vector<std::unique_ptr<ThreadsafeSpanData>> &completed_spans);
80
81 /**
82 * AggregateRunningSpans aggregates the data for all running spans received
83 * from the span processor. Running spans are not cleared by the span
84 * processor and multiple calls to this function may contain running spans for
85 * which data has already been collected in a previous call. Additionally,
86 * span names can change while span is running and there seems to be
87 * no trivial to way to know if it is a new or old running span so at every
88 * call to this function the available running span data is reset and
89 * recalculated. At this time there is no unique way to identify a span
90 * object once this is done, there might be some better ways to do this.
91 * TODO : SpanProcessor is never notified when a span name is changed while it
92 * is running and that is propogated to the data aggregator. The running span
93 * name if changed while it is running will not be updated in the data
94 * aggregator till the span is completed.
95 * @param running_spans is the running spans to be aggregated.
96 */
97 void AggregateRunningSpans(std::unordered_set<ThreadsafeSpanData *> &running_spans);
98
99 /**
100 * AggregateStatusOKSpans is the function called to update the data of spans
101 * with status code OK.
102 * @param ok_span is the span who's data is to be aggregated
103 */
104 void AggregateStatusOKSpan(std::unique_ptr<ThreadsafeSpanData> &ok_span);
105
106 /**
107 * AggregateStatusErrorSpans is the function that is called to update the
108 * data of error spans
109 * @param error_span is the error span who's data is to be aggregated
110 */
111 void AggregateStatusErrorSpan(std::unique_ptr<ThreadsafeSpanData> &error_span);
112
113 /**
114 * ClearRunningSpanData is a function that is used to clear all running span
115 * at the beginning of a call to AggregateSpan data.
116 * Running span data has to be cleared before aggregation because running
117 * span data is recalculated at every call to AggregateSpans.
118 */
119 void ClearRunningSpanData();
120
121 /**
122 * FindLatencyBoundary finds the latency boundary to which the duration of
123 * the given span_data belongs to
124 * @ param span_data is the ThreadsafeSpanData whose duration for which the latency
125 * boundary is to be found
126 * @ returns LatencyBoundary is the latency boundary that the duration belongs
127 * to
128 */
129 LatencyBoundary FindLatencyBoundary(std::unique_ptr<ThreadsafeSpanData> &ok_span);
130
131 /**
132 * InsertIntoSampleSpanList is a helper function that is called to insert
133 * a given span into a sample span list. A function is used for insertion
134 * because list size is to be limited at a set maximum.
135 * @param sample_spans the sample span list into which span is to be inserted
136 * @param span_data the span_data to be inserted into list
137 */
138 void InsertIntoSampleSpanList(std::list<ThreadsafeSpanData> &sample_spans,
139 ThreadsafeSpanData &span_data);
140
141 /** Instance of shared spans used to collect raw data **/
142 std::shared_ptr<TracezSharedData> tracez_shared_data_;
143
144 /**
145 * Tree map with key being the name of the span and value being a unique ptr
146 * that stores the tracez span data for the given span name
147 * A tree map is preferred to a hash map because the the data is to be ordered
148 * in alphabetical order of span name.
149 * TODO : A possible memory concern if there are too many unique
150 * span names, one solution could be to implement a LRU cache that trims the
151 * DS based on frequency of usage of a span name.
152 */
153 std::map<std::string, TracezData> aggregated_tracez_data_;
154 std::mutex mtx_;
155
156 /** A boolean that is set to true in the constructor and false in the
157 * destructor to start and end execution of aggregate spans **/
158 std::atomic<bool> execute_;
159
160 /** Thread that executes aggregate spans at regurlar intervals during this
161 object's lifetime**/
162 std::thread aggregate_spans_thread_;
163
164 /** Condition variable that notifies the thread when object is about to be
165 destroyed **/
166 std::condition_variable cv_;
167 };
168
169 } // namespace zpages
170 } // namespace ext
171 OPENTELEMETRY_END_NAMESPACE