Skip to content

Commit

Permalink
Add Links and Events to OStreamSpanExporter (#663)
Browse files Browse the repository at this point in the history
* Add Links and Events to OStreamSpanExporter

Previously these were just ignored. Summary of changes:

- Moved print methods into the translation unit
- Added new print methods for links and events
- Refactored tests
  - Added new convenience OStream capture utility
  - Restructured tests to focus on stream tests and feature tests
- Added new tests for links and events

* Add new test utility to bazel build
  • Loading branch information
eyjohn authored Apr 8, 2021
1 parent 364c5cb commit 7a0745d
Show file tree
Hide file tree
Showing 5 changed files with 358 additions and 163 deletions.
11 changes: 11 additions & 0 deletions exporters/ostream/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,21 @@ cc_library(
],
)

cc_library(
name = "ostream_capture",
hdrs = [
"test/ostream_capture.h",
],
deps = [
"//api",
],
)

cc_test(
name = "ostream_span_test",
srcs = ["test/ostream_span_test.cc"],
deps = [
":ostream_capture",
":ostream_span_exporter",
"@com_google_googletest//:gtest_main",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class OStreamSpanExporter final : public sdktrace::SpanExporter

#endif

void print_value(sdkcommon::OwnedAttributeValue &value)
void print_value(const sdkcommon::OwnedAttributeValue &value)
{
#if __cplusplus < 201402L
nostd::visit(OwnedAttributeValueVisitor(*this), value);
Expand All @@ -104,17 +104,13 @@ class OStreamSpanExporter final : public sdktrace::SpanExporter
#endif
}

void printAttributes(std::unordered_map<std::string, sdkcommon::OwnedAttributeValue> map)
{
size_t size = map.size();
// size_t i = 1;
for (auto kv : map)
{
sout_ << "\t" << kv.first << ": ";
print_value(kv.second);
sout_ << std::endl;
}
}
// various print helpers
void printAttributes(const std::unordered_map<std::string, sdkcommon::OwnedAttributeValue> &map,
const std::string prefix = "\n\t");

void printEvents(const std::vector<sdktrace::SpanDataEvent> &events);

void printLinks(const std::vector<sdktrace::SpanDataLink> &links);
};
} // namespace trace
} // namespace exporter
Expand Down
52 changes: 49 additions & 3 deletions exporters/ostream/src/span_exporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,14 @@ sdktrace::ExportResult OStreamSpanExporter::Export(
<< "\n duration : " << span->GetDuration().count()
<< "\n description : " << span->GetDescription()
<< "\n span kind : " << span->GetSpanKind()
<< "\n status : " << statusMap[int(span->GetStatus())] << "\n attributes : "
<< "\n";
<< "\n status : " << statusMap[int(span->GetStatus())]
<< "\n attributes : ";
printAttributes(span->GetAttributes());
sout_ << "}\n";
sout_ << "\n events : ";
printEvents(span->GetEvents());
sout_ << "\n links : ";
printLinks(span->GetLinks());
sout_ << "\n}\n";
}
}

Expand All @@ -85,6 +89,48 @@ bool OStreamSpanExporter::Shutdown(std::chrono::microseconds timeout) noexcept
return true;
}

void OStreamSpanExporter::printAttributes(
const std::unordered_map<std::string, sdkcommon::OwnedAttributeValue> &map,
const std::string prefix)
{
for (const auto &kv : map)
{
sout_ << prefix << kv.first << ": ";
print_value(kv.second);
}
}

void OStreamSpanExporter::printEvents(const std::vector<sdktrace::SpanDataEvent> &events)
{
for (const auto &event : events)
{
sout_ << "\n\t{"
<< "\n\t name : " << event.GetName()
<< "\n\t timestamp : " << event.GetTimestamp().time_since_epoch().count()
<< "\n\t attributes : ";
printAttributes(event.GetAttributes(), "\n\t\t");
sout_ << "\n\t}";
}
}

void OStreamSpanExporter::printLinks(const std::vector<sdktrace::SpanDataLink> &links)
{
for (const auto &link : links)
{
char trace_id[32] = {0};
char span_id[16] = {0};
link.GetSpanContext().trace_id().ToLowerBase16(trace_id);
link.GetSpanContext().span_id().ToLowerBase16(span_id);
sout_ << "\n\t{"
<< "\n\t trace_id : " << std::string(trace_id, 32)
<< "\n\t span_id : " << std::string(span_id, 16)
<< "\n\t tracestate : " << link.GetSpanContext().trace_state()->ToHeader()
<< "\n\t attributes : ";
printAttributes(link.GetAttributes(), "\n\t\t");
sout_ << "\n\t}";
}
}

} // namespace trace
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
57 changes: 57 additions & 0 deletions exporters/ostream/test/ostream_capture.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

#include <iostream>
#include <sstream>
#include <string>

OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter
{
namespace ostream
{
namespace test
{
/**
* The OStreamCapture captures from the specified stream for its lifetime
*/
class OStreamCapture
{
public:
/**
* Create a OStreamCapture which will capture the output of the ostream that it was constructed
* with for the lifetime of the instance.
*/
OStreamCapture(std::ostream &ostream) : stream_(ostream), buf_(ostream.rdbuf())
{
stream_.rdbuf(captured_.rdbuf());
}

~OStreamCapture() { stream_.rdbuf(buf_); }

/**
* Returns the captured data from the stream.
*/
std::string GetCaptured() const { return captured_.str(); }

private:
std::ostream &stream_;
std::streambuf *buf_;
std::stringstream captured_;
};

/**
* Helper method to invoke the passed func while recording the output of the specified stream and
* return the output afterwards.
*/
template <typename Func>
std::string WithOStreamCapture(std::ostream &stream, Func func)
{
OStreamCapture capture(stream);
func();
return capture.GetCaptured();
}

} // namespace test
} // namespace ostream
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
Loading

0 comments on commit 7a0745d

Please sign in to comment.