1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
4 #include "opentelemetry/exporters/otlp/otlp_recordable_utils.h"
6 #include "opentelemetry/exporters/otlp/protobuf_include_prefix.h"
8 #include "opentelemetry/proto/logs/v1/logs.pb.h"
9 #include "opentelemetry/proto/trace/v1/trace.pb.h"
11 #include "opentelemetry/exporters/otlp/protobuf_include_suffix.h"
13 #include "opentelemetry/exporters/otlp/otlp_log_recordable.h"
14 #include "opentelemetry/exporters/otlp/otlp_recordable.h"
17 #include <unordered_map>
19 namespace nostd
= opentelemetry::nostd
;
21 OPENTELEMETRY_BEGIN_NAMESPACE
29 struct InstrumentationLibraryPointerHasher
31 std::size_t operator()(const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
32 *instrumentation
) const noexcept
34 return instrumentation
->HashCode();
38 struct InstrumentationLibraryPointerEqual
40 std::size_t operator()(
41 const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
*left
,
42 const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
*right
)
45 return *left
== *right
;
51 // See `attribute_value.h` for details.
53 const int kAttributeValueSize
= 16;
54 const int kOwnedAttributeValueSize
= 15;
56 void OtlpRecordableUtils::PopulateAttribute(
57 opentelemetry::proto::common::v1::KeyValue
*attribute
,
58 nostd::string_view key
,
59 const opentelemetry::common::AttributeValue
&value
) noexcept
61 if (nullptr == attribute
)
66 // Assert size of variant to ensure that this method gets updated if the variant
69 nostd::variant_size
<opentelemetry::common::AttributeValue
>::value
== kAttributeValueSize
,
70 "AttributeValue contains unknown type");
72 attribute
->set_key(key
.data(), key
.size());
74 if (nostd::holds_alternative
<bool>(value
))
76 attribute
->mutable_value()->set_bool_value(nostd::get
<bool>(value
));
78 else if (nostd::holds_alternative
<int>(value
))
80 attribute
->mutable_value()->set_int_value(nostd::get
<int>(value
));
82 else if (nostd::holds_alternative
<int64_t>(value
))
84 attribute
->mutable_value()->set_int_value(nostd::get
<int64_t>(value
));
86 else if (nostd::holds_alternative
<unsigned int>(value
))
88 attribute
->mutable_value()->set_int_value(nostd::get
<unsigned int>(value
));
90 else if (nostd::holds_alternative
<uint64_t>(value
))
92 attribute
->mutable_value()->set_int_value(nostd::get
<uint64_t>(value
));
94 else if (nostd::holds_alternative
<double>(value
))
96 attribute
->mutable_value()->set_double_value(nostd::get
<double>(value
));
98 else if (nostd::holds_alternative
<const char *>(value
))
100 attribute
->mutable_value()->set_string_value(nostd::get
<const char *>(value
));
102 else if (nostd::holds_alternative
<nostd::string_view
>(value
))
104 attribute
->mutable_value()->set_string_value(nostd::get
<nostd::string_view
>(value
).data(),
105 nostd::get
<nostd::string_view
>(value
).size());
107 else if (nostd::holds_alternative
<nostd::span
<const uint8_t>>(value
))
109 for (const auto &val
: nostd::get
<nostd::span
<const uint8_t>>(value
))
111 attribute
->mutable_value()->mutable_array_value()->add_values()->set_int_value(val
);
114 else if (nostd::holds_alternative
<nostd::span
<const bool>>(value
))
116 for (const auto &val
: nostd::get
<nostd::span
<const bool>>(value
))
118 attribute
->mutable_value()->mutable_array_value()->add_values()->set_bool_value(val
);
121 else if (nostd::holds_alternative
<nostd::span
<const int>>(value
))
123 for (const auto &val
: nostd::get
<nostd::span
<const int>>(value
))
125 attribute
->mutable_value()->mutable_array_value()->add_values()->set_int_value(val
);
128 else if (nostd::holds_alternative
<nostd::span
<const int64_t>>(value
))
130 for (const auto &val
: nostd::get
<nostd::span
<const int64_t>>(value
))
132 attribute
->mutable_value()->mutable_array_value()->add_values()->set_int_value(val
);
135 else if (nostd::holds_alternative
<nostd::span
<const unsigned int>>(value
))
137 for (const auto &val
: nostd::get
<nostd::span
<const unsigned int>>(value
))
139 attribute
->mutable_value()->mutable_array_value()->add_values()->set_int_value(val
);
142 else if (nostd::holds_alternative
<nostd::span
<const uint64_t>>(value
))
144 for (const auto &val
: nostd::get
<nostd::span
<const uint64_t>>(value
))
146 attribute
->mutable_value()->mutable_array_value()->add_values()->set_int_value(val
);
149 else if (nostd::holds_alternative
<nostd::span
<const double>>(value
))
151 for (const auto &val
: nostd::get
<nostd::span
<const double>>(value
))
153 attribute
->mutable_value()->mutable_array_value()->add_values()->set_double_value(val
);
156 else if (nostd::holds_alternative
<nostd::span
<const nostd::string_view
>>(value
))
158 for (const auto &val
: nostd::get
<nostd::span
<const nostd::string_view
>>(value
))
160 attribute
->mutable_value()->mutable_array_value()->add_values()->set_string_value(val
.data(),
166 /** Maps from C++ attribute into OTLP proto attribute. */
167 void OtlpRecordableUtils::PopulateAttribute(
168 opentelemetry::proto::common::v1::KeyValue
*attribute
,
169 nostd::string_view key
,
170 const opentelemetry::sdk::common::OwnedAttributeValue
&value
) noexcept
172 if (nullptr == attribute
)
177 // Assert size of variant to ensure that this method gets updated if the variant
178 // definition changes
179 static_assert(nostd::variant_size
<opentelemetry::sdk::common::OwnedAttributeValue
>::value
==
180 kOwnedAttributeValueSize
,
181 "OwnedAttributeValue contains unknown type");
183 attribute
->set_key(key
.data(), key
.size());
185 if (nostd::holds_alternative
<bool>(value
))
187 attribute
->mutable_value()->set_bool_value(nostd::get
<bool>(value
));
189 else if (nostd::holds_alternative
<int32_t>(value
))
191 attribute
->mutable_value()->set_int_value(nostd::get
<int32_t>(value
));
193 else if (nostd::holds_alternative
<int64_t>(value
))
195 attribute
->mutable_value()->set_int_value(nostd::get
<int64_t>(value
));
197 else if (nostd::holds_alternative
<uint32_t>(value
))
199 attribute
->mutable_value()->set_int_value(nostd::get
<uint32_t>(value
));
201 else if (nostd::holds_alternative
<uint64_t>(value
))
203 attribute
->mutable_value()->set_int_value(nostd::get
<uint64_t>(value
));
205 else if (nostd::holds_alternative
<double>(value
))
207 attribute
->mutable_value()->set_double_value(nostd::get
<double>(value
));
209 else if (nostd::holds_alternative
<std::string
>(value
))
211 attribute
->mutable_value()->set_string_value(nostd::get
<std::string
>(value
));
213 else if (nostd::holds_alternative
<std::vector
<bool>>(value
))
215 for (const auto &val
: nostd::get
<std::vector
<bool>>(value
))
217 attribute
->mutable_value()->mutable_array_value()->add_values()->set_bool_value(val
);
220 else if (nostd::holds_alternative
<std::vector
<int32_t>>(value
))
222 for (const auto &val
: nostd::get
<std::vector
<int32_t>>(value
))
224 attribute
->mutable_value()->mutable_array_value()->add_values()->set_int_value(val
);
227 else if (nostd::holds_alternative
<std::vector
<uint32_t>>(value
))
229 for (const auto &val
: nostd::get
<std::vector
<uint32_t>>(value
))
231 attribute
->mutable_value()->mutable_array_value()->add_values()->set_int_value(val
);
234 else if (nostd::holds_alternative
<std::vector
<int64_t>>(value
))
236 for (const auto &val
: nostd::get
<std::vector
<int64_t>>(value
))
238 attribute
->mutable_value()->mutable_array_value()->add_values()->set_int_value(val
);
241 else if (nostd::holds_alternative
<std::vector
<uint64_t>>(value
))
243 for (const auto &val
: nostd::get
<std::vector
<uint64_t>>(value
))
245 attribute
->mutable_value()->mutable_array_value()->add_values()->set_int_value(val
);
248 else if (nostd::holds_alternative
<std::vector
<double>>(value
))
250 for (const auto &val
: nostd::get
<std::vector
<double>>(value
))
252 attribute
->mutable_value()->mutable_array_value()->add_values()->set_double_value(val
);
255 else if (nostd::holds_alternative
<std::vector
<std::string
>>(value
))
257 for (const auto &val
: nostd::get
<std::vector
<std::string
>>(value
))
259 attribute
->mutable_value()->mutable_array_value()->add_values()->set_string_value(val
);
264 void OtlpRecordableUtils::PopulateAttribute(
265 opentelemetry::proto::resource::v1::Resource
*proto
,
266 const opentelemetry::sdk::resource::Resource
&resource
) noexcept
268 if (nullptr == proto
)
273 for (const auto &kv
: resource
.GetAttributes())
275 OtlpRecordableUtils::PopulateAttribute(proto
->add_attributes(), kv
.first
, kv
.second
);
279 void OtlpRecordableUtils::PopulateRequest(
280 const nostd::span
<std::unique_ptr
<opentelemetry::sdk::trace::Recordable
>> &spans
,
281 proto::collector::trace::v1::ExportTraceServiceRequest
*request
) noexcept
283 if (nullptr == request
)
288 for (auto &recordable
: spans
)
290 auto rec
= std::unique_ptr
<OtlpRecordable
>(static_cast<OtlpRecordable
*>(recordable
.release()));
291 auto resource_span
= request
->add_resource_spans();
292 auto instrumentation_lib
= resource_span
->add_instrumentation_library_spans();
294 *instrumentation_lib
->add_spans() = std::move(rec
->span());
295 *instrumentation_lib
->mutable_instrumentation_library() = rec
->GetProtoInstrumentationLibrary();
297 instrumentation_lib
->set_schema_url(rec
->GetInstrumentationLibrarySchemaURL());
299 *resource_span
->mutable_resource() = rec
->ProtoResource();
300 resource_span
->set_schema_url(rec
->GetResourceSchemaURL());
304 #ifdef ENABLE_LOGS_PREVIEW
305 void OtlpRecordableUtils::PopulateRequest(
306 const nostd::span
<std::unique_ptr
<opentelemetry::sdk::logs::Recordable
>> &logs
,
307 proto::collector::logs::v1::ExportLogsServiceRequest
*request
) noexcept
309 if (nullptr == request
)
314 using logs_index_by_instrumentation_type
=
315 std::unordered_map
<const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
*,
316 std::list
<std::unique_ptr
<OtlpLogRecordable
>>,
317 InstrumentationLibraryPointerHasher
, InstrumentationLibraryPointerEqual
>;
318 std::unordered_map
<const opentelemetry::sdk::resource::Resource
*,
319 logs_index_by_instrumentation_type
>
320 logs_index_by_resource
;
322 for (auto &recordable
: logs
)
325 std::unique_ptr
<OtlpLogRecordable
>(static_cast<OtlpLogRecordable
*>(recordable
.release()));
326 auto instrumentation
= &rec
->GetInstrumentationLibrary();
327 auto resource
= &rec
->GetResource();
329 logs_index_by_resource
[resource
][instrumentation
].emplace_back(std::move(rec
));
332 for (auto &input_resource_log
: logs_index_by_resource
)
334 auto output_resource_log
= request
->add_resource_logs();
335 for (auto &input_scope_log
: input_resource_log
.second
)
337 auto output_scope_log
= output_resource_log
->add_scope_logs();
338 for (auto &input_log_record
: input_scope_log
.second
)
340 if (!output_resource_log
->has_resource())
342 *output_resource_log
->mutable_resource() = input_log_record
->ProtoResource();
343 output_resource_log
->set_schema_url(input_resource_log
.first
->GetSchemaURL());
346 if (!output_scope_log
->has_scope())
348 output_scope_log
->mutable_scope()->set_name(input_scope_log
.first
->GetName());
349 output_scope_log
->mutable_scope()->set_version(input_scope_log
.first
->GetVersion());
350 output_scope_log
->set_schema_url(input_scope_log
.first
->GetSchemaURL());
353 *output_scope_log
->add_log_records() = std::move(input_log_record
->log_record());
361 } // namespace exporter
362 OPENTELEMETRY_END_NAMESPACE