Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions api/include/opentelemetry/common/attribute_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ namespace common
/// - Homogenous arrays of primitive type values.
///
/// \warning The OpenTelemetry C++ API does not support the following attribute:
/// uint64_t, nostd::span<const uint64_t>, and nostd::span<uint8_t> types.
/// uint64_t, nostd::span<const uint64_t>, and nostd::span<const uint8_t> types.
/// \parblock The OpenTelemetry C++ API currently supports several attribute
/// value types that are not covered by the OpenTelemetry specification:
/// - \c uint64_t
/// - \c nostd::span<const uint64_t>
/// - \c nostd::span<uint8_t>
/// - \c nostd::span<const uint8_t>
///
/// Those types are reserved for future use and currently should not be
/// used. There are no guarantees around how those values are handled by
Expand All @@ -55,8 +55,6 @@ using AttributeValue =
// Not currently supported by the specification, but reserved for future use.
// Added to provide support for all primitive C++ types.
nostd::span<const uint64_t>,
// Not currently supported by the specification, but reserved for future use.
// See https://github.com/open-telemetry/opentelemetry-specification/issues/780
nostd::span<const uint8_t>>;

enum AttributeType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,22 @@ class OtlpPopulateAttributeUtils
&instrumentation_scope) noexcept;

static void PopulateAnyValue(opentelemetry::proto::common::v1::AnyValue *proto_value,
const opentelemetry::common::AttributeValue &value) noexcept;
const opentelemetry::common::AttributeValue &value,
bool allow_bytes) noexcept;

static void PopulateAnyValue(
opentelemetry::proto::common::v1::AnyValue *proto_value,
const opentelemetry::sdk::common::OwnedAttributeValue &value) noexcept;
static void PopulateAnyValue(opentelemetry::proto::common::v1::AnyValue *proto_value,
const opentelemetry::sdk::common::OwnedAttributeValue &value,
bool allow_bytes) noexcept;

static void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute,
nostd::string_view key,
const opentelemetry::common::AttributeValue &value) noexcept;
const opentelemetry::common::AttributeValue &value,
bool allow_bytes) noexcept;

static void PopulateAttribute(
opentelemetry::proto::common::v1::KeyValue *attribute,
nostd::string_view key,
const opentelemetry::sdk::common::OwnedAttributeValue &value) noexcept;
static void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute,
nostd::string_view key,
const opentelemetry::sdk::common::OwnedAttributeValue &value,
bool allow_bytes) noexcept;
};

} // namespace otlp
Expand Down
4 changes: 2 additions & 2 deletions exporters/otlp/src/otlp_log_recordable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ void OtlpLogRecordable::SetSeverity(opentelemetry::logs::Severity severity) noex

void OtlpLogRecordable::SetBody(const opentelemetry::common::AttributeValue &message) noexcept
{
OtlpPopulateAttributeUtils::PopulateAnyValue(proto_record_.mutable_body(), message);
OtlpPopulateAttributeUtils::PopulateAnyValue(proto_record_.mutable_body(), message, true);
}

void OtlpLogRecordable::SetEventId(int64_t /* id */, nostd::string_view event_name) noexcept
Expand Down Expand Up @@ -236,7 +236,7 @@ void OtlpLogRecordable::SetTraceFlags(const opentelemetry::trace::TraceFlags &tr
void OtlpLogRecordable::SetAttribute(opentelemetry::nostd::string_view key,
const opentelemetry::common::AttributeValue &value) noexcept
{
OtlpPopulateAttributeUtils::PopulateAttribute(proto_record_.add_attributes(), key, value);
OtlpPopulateAttributeUtils::PopulateAttribute(proto_record_.add_attributes(), key, value, true);
}

void OtlpLogRecordable::SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept
Expand Down
8 changes: 4 additions & 4 deletions exporters/otlp/src/otlp_metric_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void OtlpMetricUtils::ConvertSumMetric(const metric_sdk::MetricData &metric_data
for (auto &kv_attr : point_data_with_attributes.attributes)
{
OtlpPopulateAttributeUtils::PopulateAttribute(proto_sum_point_data->add_attributes(),
kv_attr.first, kv_attr.second);
kv_attr.first, kv_attr.second, false);
}
}
}
Expand Down Expand Up @@ -180,7 +180,7 @@ void OtlpMetricUtils::ConvertHistogramMetric(
for (auto &kv_attr : point_data_with_attributes.attributes)
{
OtlpPopulateAttributeUtils::PopulateAttribute(proto_histogram_point_data->add_attributes(),
kv_attr.first, kv_attr.second);
kv_attr.first, kv_attr.second, false);
}
}
}
Expand Down Expand Up @@ -244,7 +244,7 @@ void OtlpMetricUtils::ConvertExponentialHistogramMetric(
for (auto &kv_attr : point_data_with_attributes.attributes)
{
OtlpPopulateAttributeUtils::PopulateAttribute(proto_histogram_point_data->add_attributes(),
kv_attr.first, kv_attr.second);
kv_attr.first, kv_attr.second, false);
}
}
}
Expand Down Expand Up @@ -274,7 +274,7 @@ void OtlpMetricUtils::ConvertGaugeMetric(const opentelemetry::sdk::metrics::Metr
for (auto &kv_attr : point_data_with_attributes.attributes)
{
OtlpPopulateAttributeUtils::PopulateAttribute(proto_gauge_point_data->add_attributes(),
kv_attr.first, kv_attr.second);
kv_attr.first, kv_attr.second, false);
}
}
}
Expand Down
54 changes: 43 additions & 11 deletions exporters/otlp/src/otlp_populate_attribute_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ const int kOwnedAttributeValueSize = 15;

void OtlpPopulateAttributeUtils::PopulateAnyValue(
opentelemetry::proto::common::v1::AnyValue *proto_value,
const opentelemetry::common::AttributeValue &value) noexcept
const opentelemetry::common::AttributeValue &value,
bool allow_bytes) noexcept
{
if (nullptr == proto_value)
{
Expand Down Expand Up @@ -89,10 +90,19 @@ void OtlpPopulateAttributeUtils::PopulateAnyValue(
}
else if (nostd::holds_alternative<nostd::span<const uint8_t>>(value))
{
auto array_value = proto_value->mutable_array_value();
for (const auto &val : nostd::get<nostd::span<const uint8_t>>(value))
if (allow_bytes)
{
array_value->add_values()->set_int_value(val);
proto_value->set_bytes_value(
reinterpret_cast<const void *>(nostd::get<nostd::span<const uint8_t>>(value).data()),
nostd::get<nostd::span<const uint8_t>>(value).size());
}
else
{
auto array_value = proto_value->mutable_array_value();
for (const auto &val : nostd::get<nostd::span<const uint8_t>>(value))
{
array_value->add_values()->set_int_value(val);
}
}
}
else if (nostd::holds_alternative<nostd::span<const bool>>(value))
Expand Down Expand Up @@ -156,7 +166,8 @@ void OtlpPopulateAttributeUtils::PopulateAnyValue(

void OtlpPopulateAttributeUtils::PopulateAnyValue(
opentelemetry::proto::common::v1::AnyValue *proto_value,
const opentelemetry::sdk::common::OwnedAttributeValue &value) noexcept
const opentelemetry::sdk::common::OwnedAttributeValue &value,
bool allow_bytes) noexcept
{
if (nullptr == proto_value)
{
Expand Down Expand Up @@ -194,6 +205,23 @@ void OtlpPopulateAttributeUtils::PopulateAnyValue(
{
proto_value->set_double_value(nostd::get<double>(value));
}
else if (nostd::holds_alternative<std::vector<uint8_t>>(value))
{
if (allow_bytes)
{
const std::vector<uint8_t> &byte_array = nostd::get<std::vector<uint8_t>>(value);
proto_value->set_bytes_value(reinterpret_cast<const void *>(byte_array.data()),
byte_array.size());
}
else
{
auto array_value = proto_value->mutable_array_value();
for (const auto &val : nostd::get<std::vector<uint8_t>>(value))
{
array_value->add_values()->set_int_value(val);
}
}
}
else if (nostd::holds_alternative<std::string>(value))
{
proto_value->set_string_value(nostd::get<std::string>(value));
Expand Down Expand Up @@ -261,7 +289,8 @@ void OtlpPopulateAttributeUtils::PopulateAnyValue(
void OtlpPopulateAttributeUtils::PopulateAttribute(
opentelemetry::proto::common::v1::KeyValue *attribute,
nostd::string_view key,
const opentelemetry::common::AttributeValue &value) noexcept
const opentelemetry::common::AttributeValue &value,
bool allow_bytes) noexcept
{
if (nullptr == attribute)
{
Expand All @@ -275,14 +304,15 @@ void OtlpPopulateAttributeUtils::PopulateAttribute(
"AttributeValue contains unknown type");

attribute->set_key(key.data(), key.size());
PopulateAnyValue(attribute->mutable_value(), value);
PopulateAnyValue(attribute->mutable_value(), value, allow_bytes);
}

/** Maps from C++ attribute into OTLP proto attribute. */
void OtlpPopulateAttributeUtils::PopulateAttribute(
opentelemetry::proto::common::v1::KeyValue *attribute,
nostd::string_view key,
const opentelemetry::sdk::common::OwnedAttributeValue &value) noexcept
const opentelemetry::sdk::common::OwnedAttributeValue &value,
bool allow_bytes) noexcept
{
if (nullptr == attribute)
{
Expand All @@ -296,7 +326,7 @@ void OtlpPopulateAttributeUtils::PopulateAttribute(
"OwnedAttributeValue contains unknown type");

attribute->set_key(key.data(), key.size());
PopulateAnyValue(attribute->mutable_value(), value);
PopulateAnyValue(attribute->mutable_value(), value, allow_bytes);
}

void OtlpPopulateAttributeUtils::PopulateAttribute(
Expand All @@ -310,7 +340,8 @@ void OtlpPopulateAttributeUtils::PopulateAttribute(

for (const auto &kv : resource.GetAttributes())
{
OtlpPopulateAttributeUtils::PopulateAttribute(proto->add_attributes(), kv.first, kv.second);
OtlpPopulateAttributeUtils::PopulateAttribute(proto->add_attributes(), kv.first, kv.second,
false);
}
}

Expand All @@ -321,7 +352,8 @@ void OtlpPopulateAttributeUtils::PopulateAttribute(
{
for (const auto &kv : instrumentation_scope.GetAttributes())
{
OtlpPopulateAttributeUtils::PopulateAttribute(proto->add_attributes(), kv.first, kv.second);
OtlpPopulateAttributeUtils::PopulateAttribute(proto->add_attributes(), kv.first, kv.second,
false);
}
}

Expand Down
6 changes: 3 additions & 3 deletions exporters/otlp/src/otlp_recordable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ void OtlpRecordable::SetAttribute(nostd::string_view key,
const common::AttributeValue &value) noexcept
{
auto *attribute = span_.add_attributes();
OtlpPopulateAttributeUtils::PopulateAttribute(attribute, key, value);
OtlpPopulateAttributeUtils::PopulateAttribute(attribute, key, value, false);
}

void OtlpRecordable::AddEvent(nostd::string_view name,
Expand All @@ -133,7 +133,7 @@ void OtlpRecordable::AddEvent(nostd::string_view name,
event->set_time_unix_nano(timestamp.time_since_epoch().count());

attributes.ForEachKeyValue([&](nostd::string_view key, common::AttributeValue value) noexcept {
OtlpPopulateAttributeUtils::PopulateAttribute(event->add_attributes(), key, value);
OtlpPopulateAttributeUtils::PopulateAttribute(event->add_attributes(), key, value, false);
return true;
});
}
Expand All @@ -148,7 +148,7 @@ void OtlpRecordable::AddLink(const trace::SpanContext &span_context,
trace::SpanId::kSize);
link->set_trace_state(span_context.trace_state()->ToHeader());
attributes.ForEachKeyValue([&](nostd::string_view key, common::AttributeValue value) noexcept {
OtlpPopulateAttributeUtils::PopulateAttribute(link->add_attributes(), key, value);
OtlpPopulateAttributeUtils::PopulateAttribute(link->add_attributes(), key, value, false);
return true;
});
}
Expand Down
27 changes: 26 additions & 1 deletion exporters/otlp/test/otlp_log_recordable_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <gtest/gtest.h>
#include <stdint.h>
#include <chrono>
#include <cstring>
#include <string>
#include <utility>

Expand Down Expand Up @@ -73,6 +74,16 @@ TEST(OtlpLogRecordable, Basic)
EXPECT_EQ(rec.log_record().body().string_value(), name);
EXPECT_EQ(rec.log_record().trace_id(), expected_trace_id_bytes);
EXPECT_EQ(rec.log_record().span_id(), expected_span_id_bytes);

// Test bytes body
uint8_t byte_arr[] = {'T', 'e', '\0', 's', 't'};
common::AttributeValue byte_val(
nostd::span<const uint8_t>{reinterpret_cast<const uint8_t *>(byte_arr), 5});
rec.SetBody(byte_val);
EXPECT_TRUE(0 ==
memcmp(reinterpret_cast<const void *>(rec.log_record().body().bytes_value().data()),
reinterpret_cast<const void *>(byte_arr), 5));
EXPECT_EQ(rec.log_record().body().bytes_value().size(), 5);
}

TEST(OtlpLogRecordable, GetResource)
Expand Down Expand Up @@ -111,6 +122,12 @@ TEST(OtlpLogRecordable, SetSingleAttribute)
common::AttributeValue str_val(nostd::string_view("Test"));
rec.SetAttribute(str_key, str_val);

nostd::string_view byte_key = "byte_attr";
uint8_t byte_arr[] = {'T', 'e', 's', 't'};
common::AttributeValue byte_val(
nostd::span<const uint8_t>{reinterpret_cast<const uint8_t *>(byte_arr), 4});
rec.SetAttribute(byte_key, byte_val);

int checked_attributes = 0;
for (auto &attribute : rec.log_record().attributes())
{
Expand All @@ -129,8 +146,16 @@ TEST(OtlpLogRecordable, SetSingleAttribute)
++checked_attributes;
EXPECT_EQ(attribute.value().string_value(), nostd::get<nostd::string_view>(str_val).data());
}
else if (attribute.key() == byte_key)
{
++checked_attributes;
EXPECT_TRUE(0 ==
memcmp(reinterpret_cast<const void *>(attribute.value().bytes_value().data()),
reinterpret_cast<const void *>(byte_arr), 4));
EXPECT_EQ(attribute.value().bytes_value().size(), 4);
}
}
EXPECT_EQ(3, checked_attributes);
EXPECT_EQ(4, checked_attributes);
}

// Test non-int array types. Int array types are tested using templates (see IntAttributeTest)
Expand Down
Loading
Loading