Skip to content

Commit

Permalink
Implement links and event attributes in OTLP Recordable (open-telemet…
Browse files Browse the repository at this point in the history
  • Loading branch information
nadiaciobanu authored Jul 27, 2020
1 parent ed69456 commit 60f6920
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 7 deletions.
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
}

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

0 comments on commit 60f6920

Please sign in to comment.