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
27 changes: 21 additions & 6 deletions exporters/otlp/src/recordable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ void Recordable::SetIds(trace::TraceId trace_id,
trace::SpanId::kSize);
}

void Recordable::SetAttribute(nostd::string_view key,
const opentelemetry::common::AttributeValue &value) noexcept
void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute,
nostd::string_view key,
const opentelemetry::common::AttributeValue &value)
{
// Assert size of variant to ensure that this method gets updated if the variant
// definition changes
static_assert(
nostd::variant_size<opentelemetry::common::AttributeValue>::value == kAttributeValueSize,
"AttributeValue contains unknown type");

auto *attribute = span_.add_attributes();
attribute->set_key(key.data(), key.size());

if (nostd::holds_alternative<bool>(value))
Expand Down Expand Up @@ -111,21 +111,36 @@ void Recordable::SetAttribute(nostd::string_view key,
}
}

void Recordable::SetAttribute(nostd::string_view key,
const opentelemetry::common::AttributeValue &value) noexcept
{
auto *attribute = span_.add_attributes();
PopulateAttribute(attribute, key, value);
}

void Recordable::AddEvent(nostd::string_view name,
core::SystemTimestamp timestamp,
const trace::KeyValueIterable &attributes) noexcept
{
auto *event = span_.add_events();
event->set_name(name.data(), name.size());
event->set_time_unix_nano(timestamp.time_since_epoch().count());
// TODO: handle attributes

attributes.ForEachKeyValue([&](nostd::string_view key, common::AttributeValue value) noexcept {
PopulateAttribute(event->add_attributes(), key, value);
return true;
});
}

void Recordable::AddLink(opentelemetry::trace::SpanContext span_context,
const trace::KeyValueIterable &attributes) noexcept
{
(void)span_context;
(void)attributes;
auto *link = span_.add_links();
attributes.ForEachKeyValue([&](nostd::string_view key, common::AttributeValue value) noexcept {
PopulateAttribute(link->add_attributes(), key, value);
return true;
});
// TODO: Populate trace_id, span_id and trace_state when these are supported by SpanContext
Comment thread
nadiaciobanu marked this conversation as resolved.
}

void Recordable::SetStatus(trace::CanonicalCode code, nostd::string_view description) noexcept
Expand Down
41 changes: 40 additions & 1 deletion exporters/otlp/test/recordable_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ TEST(Recordable, SetStatus)
EXPECT_EQ(rec.span().status().message(), description);
}

TEST(Recordable, AddEvents)
TEST(Recordable, AddEventDefault)
{
Recordable rec;
nostd::string_view name = "Test Event";
Expand All @@ -93,6 +93,45 @@ TEST(Recordable, AddEvents)

EXPECT_EQ(rec.span().events(0).name(), name);
EXPECT_EQ(rec.span().events(0).time_unix_nano(), unix_event_time);
EXPECT_EQ(rec.span().events(0).attributes().size(), 0);
}

TEST(Recordable, AddEventWithAttributes)
{
Recordable rec;
const int kNumAttributes = 3;
std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3"};
int values[kNumAttributes] = {4, 7, 23};
std::map<std::string, int> attributes = {
{keys[0], values[0]}, {keys[1], values[1]}, {keys[2], values[2]}};

rec.AddEvent("Test Event", std::chrono::system_clock::now(),
trace::KeyValueIterableView<std::map<std::string, int>>(attributes));

for (int i = 0; i < kNumAttributes; i++)
{
EXPECT_EQ(rec.span().events(0).attributes(i).key(), keys[i]);
EXPECT_EQ(rec.span().events(0).attributes(i).value().int_value(), values[i]);
}
}

TEST(Recordable, AddLink)
{
Recordable rec;
const int kNumAttributes = 3;
std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3"};
int values[kNumAttributes] = {5, 12, 40};
std::map<std::string, int> attributes = {
{keys[0], values[0]}, {keys[1], values[1]}, {keys[2], values[2]}};

rec.AddLink(trace::SpanContext(false, false),
trace::KeyValueIterableView<std::map<std::string, int>>(attributes));

for (int i = 0; i < kNumAttributes; i++)
{
EXPECT_EQ(rec.span().links(0).attributes(i).key(), keys[i]);
EXPECT_EQ(rec.span().links(0).attributes(i).value().int_value(), values[i]);
}
}

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