]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | // Copyright The OpenTelemetry Authors |
2 | // SPDX-License-Identifier: Apache-2.0 | |
3 | ||
4 | #include "opentelemetry/ext/zpages/tracez_http_server.h" | |
5 | ||
6 | OPENTELEMETRY_BEGIN_NAMESPACE | |
7 | namespace ext | |
8 | { | |
9 | namespace zpages | |
10 | { | |
11 | namespace nostd = opentelemetry::nostd; | |
12 | ||
13 | json TracezHttpServer::GetAggregations() | |
14 | { | |
15 | aggregated_data_ = data_aggregator_->GetAggregatedTracezData(); | |
16 | auto counts_json = json::array(); | |
17 | ||
18 | for (const auto &aggregation_group : aggregated_data_) | |
19 | { | |
20 | const auto &buckets = aggregation_group.second; | |
21 | const auto &complete_ok_counts = buckets.completed_span_count_per_latency_bucket; | |
22 | ||
23 | auto latency_counts = json::array(); | |
24 | for (unsigned int boundary = 0; boundary < kLatencyBoundaries.size(); boundary++) | |
25 | { | |
26 | latency_counts.push_back(complete_ok_counts[boundary]); | |
27 | } | |
28 | ||
29 | counts_json.push_back({{"name", aggregation_group.first}, | |
30 | {"error", buckets.error_span_count}, | |
31 | {"running", buckets.running_span_count}, | |
32 | {"latency", latency_counts}}); | |
33 | } | |
34 | return counts_json; | |
35 | } | |
36 | ||
37 | json TracezHttpServer::GetRunningSpansJSON(const std::string &name) | |
38 | { | |
39 | auto running_json = json::array(); | |
40 | ||
41 | auto grouping = aggregated_data_.find(name); | |
42 | ||
43 | if (grouping != aggregated_data_.end()) | |
44 | { | |
45 | const auto &running_samples = grouping->second.sample_running_spans; | |
46 | for (const auto &sample : running_samples) | |
47 | { | |
48 | running_json.push_back({ | |
49 | {"spanid", std::string(reinterpret_cast<const char *>(sample.GetSpanId().Id().data()))}, | |
50 | {"parentid", | |
51 | std::string(reinterpret_cast<const char *>(sample.GetParentSpanId().Id().data()))}, | |
52 | {"traceid", std::string(reinterpret_cast<const char *>(sample.GetTraceId().Id().data()))}, | |
53 | {"start", sample.GetStartTime().time_since_epoch().count()}, | |
54 | {"attributes", GetAttributesJSON(sample)}, | |
55 | }); | |
56 | } | |
57 | } | |
58 | return running_json; | |
59 | } | |
60 | ||
61 | json TracezHttpServer::GetErrorSpansJSON(const std::string &name) | |
62 | { | |
63 | auto error_json = json::array(); | |
64 | ||
65 | auto grouping = aggregated_data_.find(name); | |
66 | ||
67 | if (grouping != aggregated_data_.end()) | |
68 | { | |
69 | const auto &error_samples = grouping->second.sample_error_spans; | |
70 | for (const auto &sample : error_samples) | |
71 | { | |
72 | error_json.push_back({ | |
73 | {"spanid", std::string(reinterpret_cast<const char *>(sample.GetSpanId().Id().data()))}, | |
74 | {"parentid", | |
75 | std::string(reinterpret_cast<const char *>(sample.GetParentSpanId().Id().data()))}, | |
76 | {"traceid", std::string(reinterpret_cast<const char *>(sample.GetTraceId().Id().data()))}, | |
77 | {"start", sample.GetStartTime().time_since_epoch().count()}, | |
78 | {"status", (unsigned short)sample.GetStatus()}, | |
79 | {"attributes", GetAttributesJSON(sample)}, | |
80 | }); | |
81 | } | |
82 | } | |
83 | return error_json; | |
84 | } | |
85 | ||
86 | json TracezHttpServer::GetLatencySpansJSON(const std::string &name, int latency_range_index) | |
87 | { | |
88 | auto latency_json = json::array(); | |
89 | ||
90 | auto grouping = aggregated_data_.find(name); | |
91 | ||
92 | if (grouping != aggregated_data_.end()) | |
93 | { | |
94 | const auto &latency_samples = grouping->second.sample_latency_spans[latency_range_index]; | |
95 | for (const auto &sample : latency_samples) | |
96 | { | |
97 | latency_json.push_back({ | |
98 | {"spanid", std::string(reinterpret_cast<const char *>(sample.GetSpanId().Id().data()))}, | |
99 | {"parentid", | |
100 | std::string(reinterpret_cast<const char *>(sample.GetParentSpanId().Id().data()))}, | |
101 | {"traceid", std::string(reinterpret_cast<const char *>(sample.GetTraceId().Id().data()))}, | |
102 | {"start", sample.GetStartTime().time_since_epoch().count()}, | |
103 | {"duration", sample.GetDuration().count()}, | |
104 | {"attributes", GetAttributesJSON(sample)}, | |
105 | }); | |
106 | } | |
107 | } | |
108 | return latency_json; | |
109 | } | |
110 | ||
111 | json TracezHttpServer::GetAttributesJSON( | |
112 | const opentelemetry::ext::zpages::ThreadsafeSpanData &sample) | |
113 | { | |
114 | auto attributes_json = json::object(); | |
115 | for (const auto &sample_attribute : sample.GetAttributes()) | |
116 | { | |
117 | auto &key = sample_attribute.first; | |
118 | auto &val = sample_attribute.second; // OwnedAttributeValue | |
119 | ||
120 | /* Convert variant types to into their nonvariant form. This is done this way because | |
121 | the frontend and JSON doesn't care about type, and variant's get function only allows | |
122 | const integers or literals */ | |
123 | ||
124 | switch (val.index()) | |
125 | { | |
126 | case 0: | |
127 | attributes_json[key] = nostd::get<0>(val); | |
128 | break; | |
129 | case 1: | |
130 | attributes_json[key] = nostd::get<1>(val); | |
131 | break; | |
132 | case 2: | |
133 | attributes_json[key] = nostd::get<2>(val); | |
134 | break; | |
135 | case 3: | |
136 | attributes_json[key] = nostd::get<3>(val); | |
137 | break; | |
138 | case 4: | |
139 | attributes_json[key] = nostd::get<4>(val); | |
140 | break; | |
141 | case 5: | |
142 | attributes_json[key] = nostd::get<5>(val); | |
143 | break; | |
144 | case 6: | |
145 | attributes_json[key] = nostd::get<6>(val); | |
146 | break; | |
147 | case 7: | |
148 | attributes_json[key] = nostd::get<7>(val); | |
149 | break; | |
150 | case 8: | |
151 | attributes_json[key] = nostd::get<8>(val); | |
152 | break; | |
153 | case 9: | |
154 | attributes_json[key] = nostd::get<9>(val); | |
155 | break; | |
156 | } | |
157 | } | |
158 | return attributes_json; | |
159 | } | |
160 | ||
161 | } // namespace zpages | |
162 | } // namespace ext | |
163 | OPENTELEMETRY_END_NAMESPACE |