Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,28 @@ Increment the:
* [CMAKE] Remove include_directories usage and rely on target properties
[#3426](https://github.com/open-telemetry/opentelemetry-cpp/pull/3426)

* [EXPORTER] ostream log exporter, fixed memory ownership issues
[#3417](https://github.com/open-telemetry/opentelemetry-cpp/pull/3417)

Important changes:

* [EXPORTER] ostream log exporter, fixed memory ownership issues
[#3417](https://github.com/open-telemetry/opentelemetry-cpp/pull/3417)

* In the SDK, the following classes implementation has changed:

* opentelemetry::sdk::logs::ReadableLogRecord
* opentelemetry::sdk::logs::ReadWriteLogRecord

* An application implementing a custom log record exporter,
that reuses these classes from the opentelemetry-cpp SDK,
will need code adjustments, in particular for methods:

* GetBody()
* GetAttributes()

* Applications not using these SDK classes directly are not affected.

## [1.20 2025-04-01]

* [BUILD] Update opentelemetry-proto version
Expand Down
10 changes: 5 additions & 5 deletions sdk/include/opentelemetry/sdk/logs/read_write_log_record.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class ReadWriteLogRecord final : public ReadableLogRecord
* Get body field of this log.
* @return the body field for this log.
*/
const opentelemetry::common::AttributeValue &GetBody() const noexcept override;
const opentelemetry::sdk::common::OwnedAttributeValue &GetBody() const noexcept override;

/**
* Set the Event Id object
Expand Down Expand Up @@ -151,8 +151,8 @@ class ReadWriteLogRecord final : public ReadableLogRecord
* Get attributes of this log.
* @return the body field of this log
*/
const std::unordered_map<std::string, opentelemetry::common::AttributeValue> &GetAttributes()
const noexcept override;
const std::unordered_map<std::string, opentelemetry::sdk::common::OwnedAttributeValue> &
GetAttributes() const noexcept override;

/**
* Get resource of this log
Expand Down Expand Up @@ -187,8 +187,8 @@ class ReadWriteLogRecord final : public ReadableLogRecord
const opentelemetry::sdk::resource::Resource *resource_;
const opentelemetry::sdk::instrumentationscope::InstrumentationScope *instrumentation_scope_;

std::unordered_map<std::string, opentelemetry::common::AttributeValue> attributes_map_;
opentelemetry::common::AttributeValue body_;
std::unordered_map<std::string, opentelemetry::sdk::common::OwnedAttributeValue> attributes_map_;
opentelemetry::sdk::common::OwnedAttributeValue body_;
opentelemetry::common::SystemTimestamp timestamp_;
opentelemetry::common::SystemTimestamp observed_timestamp_;

Expand Down
4 changes: 2 additions & 2 deletions sdk/include/opentelemetry/sdk/logs/readable_log_record.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class ReadableLogRecord : public Recordable
* Get body field of this log.
* @return the body field for this log.
*/
virtual const opentelemetry::common::AttributeValue &GetBody() const noexcept = 0;
virtual const opentelemetry::sdk::common::OwnedAttributeValue &GetBody() const noexcept = 0;

/**
* Get the Event id.
Expand Down Expand Up @@ -111,7 +111,7 @@ class ReadableLogRecord : public Recordable
* Get attributes of this log.
* @return the body field of this log
*/
virtual const std::unordered_map<std::string, opentelemetry::common::AttributeValue> &
virtual const std::unordered_map<std::string, opentelemetry::sdk::common::OwnedAttributeValue> &
GetAttributes() const noexcept = 0;

/**
Expand Down
14 changes: 9 additions & 5 deletions sdk/src/logs/read_write_log_record.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "opentelemetry/logs/severity.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/variant.h"
#include "opentelemetry/sdk/common/attribute_utils.h"
#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
#include "opentelemetry/sdk/logs/read_write_log_record.h"
#include "opentelemetry/sdk/resource/resource.h"
Expand All @@ -30,7 +31,7 @@ ReadWriteLogRecord::ReadWriteLogRecord()
: severity_(opentelemetry::logs::Severity::kInvalid),
resource_(nullptr),
instrumentation_scope_(nullptr),
body_(nostd::string_view()),
body_(std::string()),
observed_timestamp_(std::chrono::system_clock::now()),
event_id_(0),
event_name_("")
Expand Down Expand Up @@ -71,10 +72,11 @@ opentelemetry::logs::Severity ReadWriteLogRecord::GetSeverity() const noexcept

void ReadWriteLogRecord::SetBody(const opentelemetry::common::AttributeValue &message) noexcept
{
body_ = message;
opentelemetry::sdk::common::AttributeConverter converter;
body_ = nostd::visit(converter, message);
}

const opentelemetry::common::AttributeValue &ReadWriteLogRecord::GetBody() const noexcept
const opentelemetry::sdk::common::OwnedAttributeValue &ReadWriteLogRecord::GetBody() const noexcept
{
return body_;
}
Expand Down Expand Up @@ -161,10 +163,12 @@ const opentelemetry::trace::TraceFlags &ReadWriteLogRecord::GetTraceFlags() cons
void ReadWriteLogRecord::SetAttribute(nostd::string_view key,
const opentelemetry::common::AttributeValue &value) noexcept
{
attributes_map_[static_cast<std::string>(key)] = value;
std::string safe_key(key);
opentelemetry::sdk::common::AttributeConverter converter;
attributes_map_[safe_key] = nostd::visit(converter, value);
}

const std::unordered_map<std::string, opentelemetry::common::AttributeValue> &
const std::unordered_map<std::string, opentelemetry::sdk::common::OwnedAttributeValue> &
ReadWriteLogRecord::GetAttributes() const noexcept
{
return attributes_map_;
Expand Down
77 changes: 32 additions & 45 deletions sdk/test/logs/log_record_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "opentelemetry/common/attribute_value.h"
#include "opentelemetry/common/key_value_iterable.h"
#include "opentelemetry/common/timestamp.h"
#include "opentelemetry/logs/log_record.h"
Expand All @@ -22,6 +22,7 @@
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/nostd/variant.h"
#include "opentelemetry/sdk/common/attribute_utils.h"
#include "opentelemetry/sdk/logs/read_write_log_record.h"
#include "opentelemetry/sdk/resource/resource.h"
#include "opentelemetry/trace/span_id.h"
Expand Down Expand Up @@ -72,13 +73,9 @@ TEST(ReadWriteLogRecord, SetAndGet)

// Test that all fields match what was set
ASSERT_EQ(record.GetSeverity(), logs_api::Severity::kInvalid);
if (nostd::holds_alternative<const char *>(record.GetBody()))
if (nostd::holds_alternative<std::string>(record.GetBody()))
{
ASSERT_EQ(std::string(nostd::get<const char *>(record.GetBody())), "Message");
}
else if (nostd::holds_alternative<nostd::string_view>(record.GetBody()))
{
ASSERT_TRUE(nostd::get<nostd::string_view>(record.GetBody()) == "Message");
ASSERT_EQ(std::string(nostd::get<std::string>(record.GetBody())), "Message");
}
ASSERT_TRUE(nostd::get<bool>(record.GetResource().GetAttributes().at("res1")));
ASSERT_EQ(nostd::get<int64_t>(record.GetAttributes().at("attr1")), 314159);
Expand Down Expand Up @@ -109,13 +106,13 @@ class TestBodyLogger : public opentelemetry::logs::Logger
}
}

const opentelemetry::common::AttributeValue &GetLastLogRecord() const noexcept
const opentelemetry::sdk::common::OwnedAttributeValue &GetLastLogRecord() const noexcept
{
return last_body_;
}

private:
opentelemetry::common::AttributeValue last_body_;
opentelemetry::sdk::common::OwnedAttributeValue last_body_;
};

// Define a basic LoggerProvider class that returns an instance of the logger class defined above
Expand Down Expand Up @@ -173,28 +170,19 @@ TEST(LogBody, BodyConversation)

real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, "128");
ASSERT_TRUE(
opentelemetry::nostd::holds_alternative<const char *>(real_logger->GetLastLogRecord()) ||
opentelemetry::nostd::holds_alternative<nostd::string_view>(real_logger->GetLastLogRecord()));
if (opentelemetry::nostd::holds_alternative<const char *>(real_logger->GetLastLogRecord()))
{
ASSERT_EQ(nostd::string_view{"128"},
opentelemetry::nostd::get<const char *>(real_logger->GetLastLogRecord()));
}
else
{
ASSERT_EQ(nostd::string_view{"128"},
opentelemetry::nostd::get<nostd::string_view>(real_logger->GetLastLogRecord()));
}
opentelemetry::nostd::holds_alternative<std::string>(real_logger->GetLastLogRecord()));
ASSERT_EQ(nostd::string_view{"128"},
opentelemetry::nostd::get<std::string>(real_logger->GetLastLogRecord()));

{
bool data[] = {true, false, true};
nostd::span<const bool> data_span = data;
real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span);
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<nostd::span<const bool>>(
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::vector<bool>>(
real_logger->GetLastLogRecord()));

nostd::span<const bool> output =
opentelemetry::nostd::get<nostd::span<const bool>>(real_logger->GetLastLogRecord());
std::vector<bool> output =
opentelemetry::nostd::get<std::vector<bool>>(real_logger->GetLastLogRecord());

ASSERT_EQ(data_span.size(), output.size());

Expand All @@ -208,11 +196,11 @@ TEST(LogBody, BodyConversation)
int32_t data[] = {221, 222, 223};
nostd::span<const int32_t> data_span = data;
real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span);
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<nostd::span<const int32_t>>(
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::vector<int32_t>>(
real_logger->GetLastLogRecord()));

nostd::span<const int32_t> output =
opentelemetry::nostd::get<nostd::span<const int32_t>>(real_logger->GetLastLogRecord());
opentelemetry::nostd::get<std::vector<int32_t>>(real_logger->GetLastLogRecord());

ASSERT_EQ(data_span.size(), output.size());

Expand All @@ -226,11 +214,11 @@ TEST(LogBody, BodyConversation)
uint32_t data[] = {231, 232, 233};
nostd::span<const uint32_t> data_span = data;
real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span);
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<nostd::span<const uint32_t>>(
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::vector<uint32_t>>(
real_logger->GetLastLogRecord()));

nostd::span<const uint32_t> output =
opentelemetry::nostd::get<nostd::span<const uint32_t>>(real_logger->GetLastLogRecord());
std::vector<uint32_t> output =
opentelemetry::nostd::get<std::vector<uint32_t>>(real_logger->GetLastLogRecord());

ASSERT_EQ(data_span.size(), output.size());

Expand All @@ -244,11 +232,11 @@ TEST(LogBody, BodyConversation)
int64_t data[] = {241, 242, 243};
nostd::span<const int64_t> data_span = data;
real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span);
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<nostd::span<const int64_t>>(
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::vector<int64_t>>(
real_logger->GetLastLogRecord()));

nostd::span<const int64_t> output =
opentelemetry::nostd::get<nostd::span<const int64_t>>(real_logger->GetLastLogRecord());
std::vector<int64_t> output =
opentelemetry::nostd::get<std::vector<int64_t>>(real_logger->GetLastLogRecord());

ASSERT_EQ(data_span.size(), output.size());

Expand All @@ -262,11 +250,11 @@ TEST(LogBody, BodyConversation)
uint64_t data[] = {251, 252, 253};
nostd::span<const uint64_t> data_span = data;
real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span);
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<nostd::span<const uint64_t>>(
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::vector<uint64_t>>(
real_logger->GetLastLogRecord()));

nostd::span<const uint64_t> output =
opentelemetry::nostd::get<nostd::span<const uint64_t>>(real_logger->GetLastLogRecord());
std::vector<uint64_t> output =
opentelemetry::nostd::get<std::vector<uint64_t>>(real_logger->GetLastLogRecord());

ASSERT_EQ(data_span.size(), output.size());

Expand All @@ -280,11 +268,11 @@ TEST(LogBody, BodyConversation)
uint8_t data[] = {161, 162, 163};
nostd::span<const uint8_t> data_span = data;
real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span);
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<nostd::span<const uint8_t>>(
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::vector<uint8_t>>(
real_logger->GetLastLogRecord()));

nostd::span<const uint8_t> output =
opentelemetry::nostd::get<nostd::span<const uint8_t>>(real_logger->GetLastLogRecord());
std::vector<uint8_t> output =
opentelemetry::nostd::get<std::vector<uint8_t>>(real_logger->GetLastLogRecord());

ASSERT_EQ(data_span.size(), output.size());

Expand All @@ -298,11 +286,11 @@ TEST(LogBody, BodyConversation)
double data[] = {271.0, 272.0, 273.0};
nostd::span<const double> data_span = data;
real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span);
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<nostd::span<const double>>(
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::vector<double>>(
real_logger->GetLastLogRecord()));

nostd::span<const double> output =
opentelemetry::nostd::get<nostd::span<const double>>(real_logger->GetLastLogRecord());
std::vector<double> output =
opentelemetry::nostd::get<std::vector<double>>(real_logger->GetLastLogRecord());

ASSERT_EQ(data_span.size(), output.size());

Expand All @@ -317,12 +305,11 @@ TEST(LogBody, BodyConversation)
nostd::string_view data[] = {data_origin[0], data_origin[1], data_origin[2]};
nostd::span<const nostd::string_view> data_span = data;
real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span);
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<nostd::span<const nostd::string_view>>(
ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::vector<std::string>>(
real_logger->GetLastLogRecord()));

nostd::span<const nostd::string_view> output =
opentelemetry::nostd::get<nostd::span<const nostd::string_view>>(
real_logger->GetLastLogRecord());
std::vector<std::string> output =
opentelemetry::nostd::get<std::vector<std::string>>(real_logger->GetLastLogRecord());

ASSERT_EQ(data_span.size(), output.size());

Expand Down
Loading