diff --git a/exporters/ostream/src/log_record_exporter.cc b/exporters/ostream/src/log_record_exporter.cc index 26266161c3..a5e7dd3b1d 100644 --- a/exporters/ostream/src/log_record_exporter.cc +++ b/exporters/ostream/src/log_record_exporter.cc @@ -22,7 +22,7 @@ #include "opentelemetry/sdk/common/exporter_utils.h" #include "opentelemetry/sdk/common/global_log_handler.h" #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" -#include "opentelemetry/sdk/logs/read_write_log_record.h" +#include "opentelemetry/sdk/logs/log_record_data.h" #include "opentelemetry/sdk/logs/recordable.h" #include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/trace/span_id.h" @@ -47,7 +47,7 @@ OStreamLogRecordExporter::OStreamLogRecordExporter(std::ostream &sout) noexcept std::unique_ptr OStreamLogRecordExporter::MakeRecordable() noexcept { - return std::unique_ptr(new sdklogs::ReadWriteLogRecord()); + return std::unique_ptr(new sdklogs::LogRecordData()); } sdk::common::ExportResult OStreamLogRecordExporter::Export( @@ -62,8 +62,8 @@ sdk::common::ExportResult OStreamLogRecordExporter::Export( for (auto &record : records) { - auto log_record = std::unique_ptr( - static_cast(record.release())); + auto log_record = std::unique_ptr( + static_cast(record.release())); if (log_record == nullptr) { diff --git a/exporters/ostream/test/ostream_log_test.cc b/exporters/ostream/test/ostream_log_test.cc index 552b7d1983..e90090c79a 100644 --- a/exporters/ostream/test/ostream_log_test.cc +++ b/exporters/ostream/test/ostream_log_test.cc @@ -28,6 +28,7 @@ #include "opentelemetry/nostd/utility.h" #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" #include "opentelemetry/sdk/logs/exporter.h" +#include "opentelemetry/sdk/logs/log_record_data.h" #include "opentelemetry/sdk/logs/logger_provider.h" #include "opentelemetry/sdk/logs/processor.h" #include "opentelemetry/sdk/logs/read_write_log_record.h" @@ -82,7 +83,7 @@ TEST(OStreamLogRecordExporter, Shutdown) // After processor/exporter is shutdown, no logs should be sent to stream auto record = exporter->MakeRecordable(); - static_cast(record.get())->SetBody("Log record not empty"); + static_cast(record.get())->SetBody("Log record not empty"); exporter->Export(nostd::span>(&record, 1)); // Restore original stringstream buffer @@ -171,12 +172,12 @@ TEST(OStreamLogRecordExporter, SimpleLogToCout) // Create a log record and manually timestamp, severity, name, message common::SystemTimestamp now(std::chrono::system_clock::now()); - auto record = std::unique_ptr(new sdklogs::ReadWriteLogRecord()); - static_cast(record.get())->SetTimestamp(now); - static_cast(record.get())->SetObservedTimestamp(now); - static_cast(record.get()) + auto record = std::unique_ptr(new sdklogs::LogRecordData()); + static_cast(record.get())->SetTimestamp(now); + static_cast(record.get())->SetObservedTimestamp(now); + static_cast(record.get()) ->SetSeverity(logs_api::Severity::kTrace); // kTrace has enum value of 1 - static_cast(record.get())->SetBody("Message"); + static_cast(record.get())->SetBody("Message"); opentelemetry::sdk::instrumentationscope::InstrumentationScope instrumentation_scope = GetTestInstrumentationScope(); @@ -248,10 +249,10 @@ TEST(OStreamLogRecordExporter, LogWithStringAttributesToCerr) // Set resources for this log record only of type auto resource = opentelemetry::sdk::resource::Resource::Create({{"key1", "val1"}}); - static_cast(record.get())->SetResource(resource); + static_cast(record.get())->SetResource(resource); // Set attributes to this log record of type - static_cast(record.get())->SetAttribute("a", true); + static_cast(record.get())->SetAttribute("a", true); opentelemetry::sdk::instrumentationscope::InstrumentationScope instrumentation_scope = GetTestInstrumentationScope(); @@ -326,12 +327,12 @@ TEST(OStreamLogRecordExporter, LogWithVariantTypesToClog) nostd::span data1{array1.data(), array1.size()}; auto resource = opentelemetry::sdk::resource::Resource::Create({{"res1", data1}}); - static_cast(record.get())->SetResource(resource); + static_cast(record.get())->SetResource(resource); // Set resources for this log record of bool types as the value // e.g. key/value is a par of type std::array array = {false, true, false}; - static_cast(record.get()) + static_cast(record.get()) ->SetAttribute("attr1", nostd::span{array.data(), array.size()}); opentelemetry::sdk::instrumentationscope::InstrumentationScope instrumentation_scope = diff --git a/sdk/include/opentelemetry/sdk/common/attribute_utils.h b/sdk/include/opentelemetry/sdk/common/attribute_utils.h index c2d0209a7d..b43f2d29ef 100644 --- a/sdk/include/opentelemetry/sdk/common/attribute_utils.h +++ b/sdk/include/opentelemetry/sdk/common/attribute_utils.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,8 @@ using OwnedAttributeValue = nostd::variant, std::vector>; +using OwnedAttributeView = nostd::variant, std::unique_ptr>; + enum OwnedAttributeType { kTypeBool, @@ -298,6 +301,248 @@ class OrderedAttributeMap : public std::map AttributeConverter converter_; }; +/** + * Class for storing attributes. + */ +struct MixedAttributeMapStorage +{ + std::unordered_map attributes; + AttributeMap owned_attributes; + std::unordered_map owened_attributes_view; +}; + +/** + * Set an owned copy (OwnedAttributeValue) and attribute view of a non-owning AttributeValue. + */ +class MixedAttributeViewSetter +{ +public: + inline MixedAttributeViewSetter(const nostd::string_view &key, + MixedAttributeMapStorage &storage, + AttributeConverter &converter) noexcept + : key_(&key), storage_(&storage), converter_(&converter) + {} + + void operator()(bool v) + { + storage_->owned_attributes[std::string(*key_)] = (*converter_)(v); + storage_->attributes[std::string(*key_)] = v; + } + + void operator()(int32_t v) + { + storage_->owned_attributes[std::string(*key_)] = (*converter_)(v); + storage_->attributes[std::string(*key_)] = v; + } + + void operator()(uint32_t v) + { + storage_->owned_attributes[std::string(*key_)] = (*converter_)(v); + storage_->attributes[std::string(*key_)] = v; + } + + void operator()(int64_t v) + { + storage_->owned_attributes[std::string(*key_)] = (*converter_)(v); + storage_->attributes[std::string(*key_)] = v; + } + + void operator()(uint64_t v) + { + storage_->owned_attributes[std::string(*key_)] = (*converter_)(v); + storage_->attributes[std::string(*key_)] = v; + } + + void operator()(double v) + { + storage_->owned_attributes[std::string(*key_)] = (*converter_)(v); + storage_->attributes[std::string(*key_)] = v; + } + + void operator()(nostd::string_view v) + { + auto &owned_value = storage_->owned_attributes[std::string(*key_)]; + owned_value = (*converter_)(v); + storage_->attributes[std::string(*key_)] = nostd::get(owned_value); + } + + void operator()(const char *v) + { + auto &owned_value = storage_->owned_attributes[std::string(*key_)]; + owned_value = (*converter_)(v); + storage_->attributes[std::string(*key_)] = nostd::get(owned_value).c_str(); + } + + void operator()(nostd::span v) + { + auto &owned_value = storage_->owned_attributes[std::string(*key_)]; + owned_value = (*converter_)(v); + storage_->attributes[std::string(*key_)] = nostd::get>(owned_value); + } + + void operator()(nostd::span v) + { + storage_->owned_attributes[std::string(*key_)] = (*converter_)(v); + if (v.empty()) + { + storage_->attributes[std::string(*key_)] = nostd::span{}; + } + else + { + std::unique_ptr owned_view{new bool[v.size()]}; + for (size_t i = 0; i < v.size(); i++) + { + owned_view[i] = v[i]; + } + + storage_->attributes[std::string(*key_)] = + nostd::span{owned_view.get(), v.size()}; + storage_->owened_attributes_view[std::string(*key_)] = std::move(owned_view); + } + } + + void operator()(nostd::span v) + { + auto &owned_value = storage_->owned_attributes[std::string(*key_)]; + owned_value = (*converter_)(v); + storage_->attributes[std::string(*key_)] = nostd::get>(owned_value); + } + + void operator()(nostd::span v) + { + auto &owned_value = storage_->owned_attributes[std::string(*key_)]; + owned_value = (*converter_)(v); + storage_->attributes[std::string(*key_)] = nostd::get>(owned_value); + } + + void operator()(nostd::span v) + { + auto &owned_value = storage_->owned_attributes[std::string(*key_)]; + owned_value = (*converter_)(v); + storage_->attributes[std::string(*key_)] = nostd::get>(owned_value); + } + + void operator()(nostd::span v) + { + auto &owned_value = storage_->owned_attributes[std::string(*key_)]; + owned_value = (*converter_)(v); + storage_->attributes[std::string(*key_)] = nostd::get>(owned_value); + } + + void operator()(nostd::span v) + { + auto &owned_value = storage_->owned_attributes[std::string(*key_)]; + owned_value = (*converter_)(v); + storage_->attributes[std::string(*key_)] = nostd::get>(owned_value); + } + + void operator()(nostd::span v) + { + auto &owned_value = storage_->owned_attributes[std::string(*key_)]; + owned_value = (*converter_)(v); + + if (v.empty()) + { + storage_->attributes[std::string(*key_)] = nostd::span{}; + } + else + { + auto &owned_view = storage_->owened_attributes_view[std::string(*key_)]; + owned_view = std::vector{}; + auto &owned_vector = nostd::get>(owned_view); + + owned_vector.reserve(v.size()); + for (auto &data : nostd::get>(owned_value)) + { + owned_vector.push_back(data); + } + + storage_->attributes[std::string(*key_)] = + nostd::span{owned_vector.data(), owned_vector.size()}; + } + } + +private: + const nostd::string_view *key_; + MixedAttributeMapStorage *storage_; + AttributeConverter *converter_; +}; + +/** + * Class for storing attributes and attribute view. + */ +class MixedAttributeMap +{ +public: + // Construct empty attribute map + MixedAttributeMap() {} + + // Construct attribute map and populate with attributes + MixedAttributeMap(const opentelemetry::common::KeyValueIterable &attributes) : MixedAttributeMap() + { + attributes.ForEachKeyValue( + [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { + nostd::visit(MixedAttributeViewSetter(key, storage_, converter_), value); + return true; + }); + } + + // Construct attribute map and populate with optional attributes + MixedAttributeMap(const opentelemetry::common::KeyValueIterable *attributes) : MixedAttributeMap() + { + if (attributes != nullptr) + { + attributes->ForEachKeyValue( + [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { + nostd::visit(MixedAttributeViewSetter(key, storage_, converter_), value); + return true; + }); + } + } + + // Construct map from initializer list by applying `SetAttribute` transform for every attribute + MixedAttributeMap( + std::initializer_list> + attributes) + : MixedAttributeMap() + { + for (auto &kv : attributes) + { + nostd::visit(MixedAttributeViewSetter(kv.first, storage_, converter_), kv.second); + } + } + + // Returns a reference to this map + const std::unordered_map &GetAttributes() + const noexcept + { + return storage_.attributes; + } + + const AttributeMap &GetOwnedAttributes() const noexcept { return storage_.owned_attributes; } + + // Convert non-owning key-value to owning std::string(key) and OwnedAttributeValue(value) + void SetAttribute(nostd::string_view key, + const opentelemetry::common::AttributeValue &value) noexcept + { + nostd::visit(MixedAttributeViewSetter(key, storage_, converter_), value); + } + + void Reserve(AttributeMap::size_type size) + { + storage_.attributes.reserve(size); + storage_.owned_attributes.reserve(size); + } + + AttributeMap::size_type Size() const noexcept { return storage_.attributes.size(); } + + bool Empty() const noexcept { return storage_.attributes.empty(); } + +private: + MixedAttributeMapStorage storage_; + AttributeConverter converter_; +}; + } // namespace common } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/logs/exporter.h b/sdk/include/opentelemetry/sdk/logs/exporter.h index 5e83fe4609..b540092561 100644 --- a/sdk/include/opentelemetry/sdk/logs/exporter.h +++ b/sdk/include/opentelemetry/sdk/logs/exporter.h @@ -28,8 +28,8 @@ class OPENTELEMETRY_EXPORT LogRecordExporter /** * Create a log recordable. This object will be used to record log data and * will subsequently be passed to LogRecordExporter::Export. Vendors can implement - * custom recordables or use the default ReadWriteLogRecord recordable provided by the - * SDK. + * custom recordables or use the default ReadWriteLogRecord/LogRecordData recordable provided by + * the SDK. * @return a newly initialized Recordable object * * Note: This method must be callable from multiple threads. diff --git a/sdk/include/opentelemetry/sdk/logs/log_record_data.h b/sdk/include/opentelemetry/sdk/logs/log_record_data.h new file mode 100644 index 0000000000..2f03c7a742 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/logs/log_record_data.h @@ -0,0 +1,210 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include +#include + +#include "opentelemetry/common/attribute_value.h" +#include "opentelemetry/common/key_value_iterable.h" +#include "opentelemetry/common/timestamp.h" +#include "opentelemetry/logs/log_record.h" +#include "opentelemetry/logs/severity.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/sdk/common/attribute_utils.h" +#include "opentelemetry/sdk/logs/readable_log_record.h" +#include "opentelemetry/trace/span_id.h" +#include "opentelemetry/trace/trace_flags.h" +#include "opentelemetry/trace/trace_id.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace logs +{ +/** + * Maintains a representation of a log in a format that can be processed by a recorder. + * + * This class is thread-compatible. + */ +class LogRecordData final : public ReadableLogRecord +{ +public: + LogRecordData(); + ~LogRecordData() override; + + /** + * Set the timestamp for this log. + * @param timestamp the timestamp to set + */ + void SetTimestamp(opentelemetry::common::SystemTimestamp timestamp) noexcept override; + + /** + * Get the timestamp of this log. + * @return the timestamp of this log + */ + opentelemetry::common::SystemTimestamp GetTimestamp() const noexcept override; + + /** + * Set the observed timestamp for this log. + * @param timestamp the timestamp to set + */ + void SetObservedTimestamp(opentelemetry::common::SystemTimestamp timestamp) noexcept override; + + /** + * Get the observed timestamp of this log. + * @return the observed timestamp of this log + */ + opentelemetry::common::SystemTimestamp GetObservedTimestamp() const noexcept override; + + /** + * Set the severity for this log. + * @param severity the severity of the event + */ + void SetSeverity(opentelemetry::logs::Severity severity) noexcept override; + + /** + * Get the severity of this log. + * @return the severity of this log + */ + opentelemetry::logs::Severity GetSeverity() const noexcept override; + + /** + * Set body field for this log. + * @param message the body to set + */ + void SetBody(const opentelemetry::common::AttributeValue &message) noexcept override; + + /** + * Get body field of this log. + * @return the body field for this log. + */ + const opentelemetry::common::AttributeValue &GetBody() const noexcept override; + + /** + * Set the Event Id object + * @param id the event Id to set + * @param name the event name to set + */ + void SetEventId(int64_t id, nostd::string_view name) noexcept override; + + /** + * Get event Id of this log. + * @return the event Id of this log. + */ + int64_t GetEventId() const noexcept override; + + /** + * Get event name of this log. + * @return the event name of this log. + */ + nostd::string_view GetEventName() const noexcept override; + + /** + * Set the trace id for this log. + * @param trace_id the trace id to set + */ + void SetTraceId(const opentelemetry::trace::TraceId &trace_id) noexcept override; + + /** + * Get the trace id of this log. + * @return the trace id of this log + */ + const opentelemetry::trace::TraceId &GetTraceId() const noexcept override; + + /** + * Set the span id for this log. + * @param span_id the span id to set + */ + void SetSpanId(const opentelemetry::trace::SpanId &span_id) noexcept override; + + /** + * Get the span id of this log. + * @return the span id of this log + */ + const opentelemetry::trace::SpanId &GetSpanId() const noexcept override; + + /** + * Inject trace_flags for this log. + * @param trace_flags the trace flags to set + */ + void SetTraceFlags(const opentelemetry::trace::TraceFlags &trace_flags) noexcept override; + + /** + * Inject trace_flags of this log. + * @return trace_flags of this log + */ + const opentelemetry::trace::TraceFlags &GetTraceFlags() const noexcept override; + + /** + * Set an attribute of a log. + * @param key the name of the attribute + * @param value the attribute value + */ + void SetAttribute(nostd::string_view key, + const opentelemetry::common::AttributeValue &value) noexcept override; + + /** + * Get attributes of this log. + * @return the body field of this log + */ + const std::unordered_map &GetAttributes() + const noexcept override; + + /** + * Get resource of this log + * @return the resource of this log + */ + const opentelemetry::sdk::resource::Resource &GetResource() const noexcept override; + + /** + * Set Resource of this log + * @param Resource the resource to set + */ + void SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept override; + + /** + * Get instrumentation_scope of this log. + * @return the instrumentation_scope of this log + */ + const opentelemetry::sdk::instrumentationscope::InstrumentationScope &GetInstrumentationScope() + const noexcept override; + + /** + * Set instrumentation_scope for this log. + * @param instrumentation_scope the instrumentation scope to set + */ + void SetInstrumentationScope(const opentelemetry::sdk::instrumentationscope::InstrumentationScope + &instrumentation_scope) noexcept override; + +private: + // Default values are set by the respective data structures' constructors for all fields, + // except the severity field, which must be set manually (an enum with no default value). + opentelemetry::logs::Severity severity_; + const opentelemetry::sdk::resource::Resource *resource_; + const opentelemetry::sdk::instrumentationscope::InstrumentationScope *instrumentation_scope_; + + common::MixedAttributeMap attributes_map_; + // We resue the same utility functions of MixedAttributeMap with key="" for the body field + common::MixedAttributeMap body_; + opentelemetry::common::SystemTimestamp timestamp_; + opentelemetry::common::SystemTimestamp observed_timestamp_; + + int64_t event_id_; + std::string event_name_; + + // We do not pay for trace state when not necessary + struct TraceState + { + opentelemetry::trace::TraceId trace_id; + opentelemetry::trace::SpanId span_id; + opentelemetry::trace::TraceFlags trace_flags; + }; + std::unique_ptr trace_state_; +}; +} // namespace logs +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/logs/read_write_log_record.h b/sdk/include/opentelemetry/sdk/logs/read_write_log_record.h index 9831eaa1c9..3f42093cd2 100644 --- a/sdk/include/opentelemetry/sdk/logs/read_write_log_record.h +++ b/sdk/include/opentelemetry/sdk/logs/read_write_log_record.h @@ -188,6 +188,7 @@ class ReadWriteLogRecord final : public ReadableLogRecord const opentelemetry::sdk::instrumentationscope::InstrumentationScope *instrumentation_scope_; std::unordered_map attributes_map_; + // We resue the same utility functions of MixedAttributeMap with key="" for the body field opentelemetry::common::AttributeValue body_; opentelemetry::common::SystemTimestamp timestamp_; opentelemetry::common::SystemTimestamp observed_timestamp_; diff --git a/sdk/src/logs/CMakeLists.txt b/sdk/src/logs/CMakeLists.txt index 71679a9a48..4aad18a0ad 100644 --- a/sdk/src/logs/CMakeLists.txt +++ b/sdk/src/logs/CMakeLists.txt @@ -16,6 +16,7 @@ add_library( batch_log_record_processor_factory.cc logger_context.cc logger_context_factory.cc + log_record_data.cc multi_log_record_processor.cc multi_log_record_processor_factory.cc multi_recordable.cc diff --git a/sdk/src/logs/log_record_data.cc b/sdk/src/logs/log_record_data.cc new file mode 100644 index 0000000000..6e5c6e9028 --- /dev/null +++ b/sdk/src/logs/log_record_data.cc @@ -0,0 +1,207 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include + +#include "opentelemetry/common/attribute_value.h" +#include "opentelemetry/common/timestamp.h" +#include "opentelemetry/logs/severity.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" +#include "opentelemetry/sdk/logs/log_record_data.h" +#include "opentelemetry/sdk/resource/resource.h" +#include "opentelemetry/trace/span_id.h" +#include "opentelemetry/trace/trace_flags.h" +#include "opentelemetry/trace/trace_id.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace logs +{ + +LogRecordData::LogRecordData() + : severity_(opentelemetry::logs::Severity::kInvalid), + resource_(nullptr), + instrumentation_scope_(nullptr), + observed_timestamp_(std::chrono::system_clock::now()), + event_id_(0), + event_name_("") +{ + body_.SetAttribute("", nostd::string_view()); +} + +LogRecordData::~LogRecordData() {} + +void LogRecordData::SetTimestamp(opentelemetry::common::SystemTimestamp timestamp) noexcept +{ + timestamp_ = timestamp; +} + +opentelemetry::common::SystemTimestamp LogRecordData::GetTimestamp() const noexcept +{ + return timestamp_; +} + +void LogRecordData::SetObservedTimestamp(opentelemetry::common::SystemTimestamp timestamp) noexcept +{ + observed_timestamp_ = timestamp; +} + +opentelemetry::common::SystemTimestamp LogRecordData::GetObservedTimestamp() const noexcept +{ + return observed_timestamp_; +} + +void LogRecordData::SetSeverity(opentelemetry::logs::Severity severity) noexcept +{ + severity_ = severity; +} + +opentelemetry::logs::Severity LogRecordData::GetSeverity() const noexcept +{ + return severity_; +} + +void LogRecordData::SetBody(const opentelemetry::common::AttributeValue &message) noexcept +{ + body_.SetAttribute("", message); +} + +const opentelemetry::common::AttributeValue &LogRecordData::GetBody() const noexcept +{ + return body_.GetAttributes().begin()->second; +} + +void LogRecordData::SetEventId(int64_t id, nostd::string_view name) noexcept +{ + event_id_ = id; + event_name_ = std::string{name}; +} + +int64_t LogRecordData::GetEventId() const noexcept +{ + return event_id_; +} + +nostd::string_view LogRecordData::GetEventName() const noexcept +{ + return nostd::string_view{event_name_}; +} + +void LogRecordData::SetTraceId(const opentelemetry::trace::TraceId &trace_id) noexcept +{ + if (!trace_state_) + { + trace_state_ = std::unique_ptr(new TraceState()); + } + + trace_state_->trace_id = trace_id; +} + +const opentelemetry::trace::TraceId &LogRecordData::GetTraceId() const noexcept +{ + if (trace_state_) + { + return trace_state_->trace_id; + } + + static opentelemetry::trace::TraceId empty; + return empty; +} + +void LogRecordData::SetSpanId(const opentelemetry::trace::SpanId &span_id) noexcept +{ + if (!trace_state_) + { + trace_state_ = std::unique_ptr(new TraceState()); + } + + trace_state_->span_id = span_id; +} + +const opentelemetry::trace::SpanId &LogRecordData::GetSpanId() const noexcept +{ + if (trace_state_) + { + return trace_state_->span_id; + } + + static opentelemetry::trace::SpanId empty; + return empty; +} + +void LogRecordData::SetTraceFlags(const opentelemetry::trace::TraceFlags &trace_flags) noexcept +{ + if (!trace_state_) + { + trace_state_ = std::unique_ptr(new TraceState()); + } + + trace_state_->trace_flags = trace_flags; +} + +const opentelemetry::trace::TraceFlags &LogRecordData::GetTraceFlags() const noexcept +{ + if (trace_state_) + { + return trace_state_->trace_flags; + } + + static opentelemetry::trace::TraceFlags empty; + return empty; +} + +void LogRecordData::SetAttribute(nostd::string_view key, + const opentelemetry::common::AttributeValue &value) noexcept +{ + attributes_map_.SetAttribute(key, value); +} + +const std::unordered_map & +LogRecordData::GetAttributes() const noexcept +{ + return attributes_map_.GetAttributes(); +} + +const opentelemetry::sdk::resource::Resource &LogRecordData::GetResource() const noexcept +{ + if OPENTELEMETRY_LIKELY_CONDITION (nullptr != resource_) + { + return *resource_; + } + + return GetDefaultResource(); +} + +void LogRecordData::SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept +{ + resource_ = &resource; +} + +const opentelemetry::sdk::instrumentationscope::InstrumentationScope & +LogRecordData::GetInstrumentationScope() const noexcept +{ + if OPENTELEMETRY_LIKELY_CONDITION (nullptr != instrumentation_scope_) + { + return *instrumentation_scope_; + } + + return GetDefaultInstrumentationScope(); +} + +void LogRecordData::SetInstrumentationScope( + const opentelemetry::sdk::instrumentationscope::InstrumentationScope + &instrumentation_scope) noexcept +{ + instrumentation_scope_ = &instrumentation_scope; +} +} // namespace logs +} // namespace sdk + +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/logs/read_write_log_record.cc b/sdk/src/logs/read_write_log_record.cc index 48c9a2699d..8935a06b2e 100644 --- a/sdk/src/logs/read_write_log_record.cc +++ b/sdk/src/logs/read_write_log_record.cc @@ -160,7 +160,7 @@ const opentelemetry::trace::TraceFlags &ReadWriteLogRecord::GetTraceFlags() cons void ReadWriteLogRecord::SetAttribute(nostd::string_view key, const opentelemetry::common::AttributeValue &value) noexcept { - attributes_map_[static_cast(key)] = value; + attributes_map_[std::string(key)] = value; } const std::unordered_map & diff --git a/sdk/test/common/attribute_utils_test.cc b/sdk/test/common/attribute_utils_test.cc index da303643d0..f92b8bfb22 100644 --- a/sdk/test/common/attribute_utils_test.cc +++ b/sdk/test/common/attribute_utils_test.cc @@ -13,6 +13,82 @@ #include "opentelemetry/nostd/variant.h" #include "opentelemetry/sdk/common/attribute_utils.h" +namespace +{ + +template +static void CheckExceptOneValue(const opentelemetry::sdk::common::MixedAttributeMap &data, + opentelemetry::nostd::string_view key, + DataType value) +{ + auto iter1 = data.GetAttributes().find(std::string(key)); + EXPECT_TRUE(iter1 != data.GetAttributes().end()); + + auto iter2 = data.GetOwnedAttributes().find(std::string(key)); + EXPECT_TRUE(iter2 != data.GetOwnedAttributes().end()); + + EXPECT_EQ(opentelemetry::nostd::get(iter1->second), value); + EXPECT_EQ(opentelemetry::nostd::get(iter2->second), value); +} + +template +static void CheckExceptOneStringView(const opentelemetry::sdk::common::MixedAttributeMap &data, + opentelemetry::nostd::string_view key, + opentelemetry::nostd::string_view value) +{ + auto iter1 = data.GetAttributes().find(std::string(key)); + EXPECT_TRUE(iter1 != data.GetAttributes().end()); + + auto iter2 = data.GetOwnedAttributes().find(std::string(key)); + EXPECT_TRUE(iter2 != data.GetOwnedAttributes().end()); + + EXPECT_EQ(opentelemetry::nostd::get(iter1->second), value); + EXPECT_EQ(opentelemetry::nostd::get(iter2->second), value); +} + +template +static void CheckExceptArrayValue(const opentelemetry::sdk::common::MixedAttributeMap &data, + opentelemetry::nostd::string_view key, + DataType (&value)[DataSize]) +{ + auto iter1 = data.GetAttributes().find(std::string(key)); + EXPECT_TRUE(iter1 != data.GetAttributes().end()); + + auto iter2 = data.GetOwnedAttributes().find(std::string(key)); + EXPECT_TRUE(iter2 != data.GetOwnedAttributes().end()); + + for (size_t i = 0; i < DataSize; ++i) + { + EXPECT_EQ( + opentelemetry::nostd::get>(iter1->second)[i], + value[i]); + EXPECT_EQ(opentelemetry::nostd::get>(iter2->second)[i], value[i]); + } +} + +template +static void CheckExceptArrayString(const opentelemetry::sdk::common::MixedAttributeMap &data, + opentelemetry::nostd::string_view key, + opentelemetry::nostd::string_view (&value)[DataSize]) +{ + auto iter1 = data.GetAttributes().find(std::string(key)); + EXPECT_TRUE(iter1 != data.GetAttributes().end()); + + auto iter2 = data.GetOwnedAttributes().find(std::string(key)); + EXPECT_TRUE(iter2 != data.GetOwnedAttributes().end()); + + for (size_t i = 0; i < DataSize; ++i) + { + EXPECT_EQ( + opentelemetry::nostd::get< + opentelemetry::nostd::span>(iter1->second)[i], + value[i]); + EXPECT_EQ(opentelemetry::nostd::get>(iter2->second)[i], value[i]); + } +} + +} // namespace + TEST(AttributeMapTest, DefaultConstruction) { opentelemetry::sdk::common::AttributeMap attribute_map; @@ -59,6 +135,66 @@ TEST(OrderedAttributeMapTest, AttributesConstruction) } } +TEST(MixedAttributeMapTest, SetterAndGetter) +{ + opentelemetry::sdk::common::MixedAttributeMap attribute_map; + attribute_map.Reserve(16); + EXPECT_TRUE(attribute_map.Empty()); + + attribute_map.SetAttribute("bool", true); + attribute_map.SetAttribute("int32_t", static_cast(42)); + attribute_map.SetAttribute("int64_t", static_cast(43)); + attribute_map.SetAttribute("uint32_t", static_cast(44)); + attribute_map.SetAttribute("double", static_cast(45.0)); + attribute_map.SetAttribute("uint64_t", static_cast(46)); + attribute_map.SetAttribute("const char *", "const char *"); + attribute_map.SetAttribute("string_view", opentelemetry::nostd::string_view("string_view")); + + bool array_bool[] = {true, false, true}; + uint8_t array_uint8[] = {47, 48}; + int32_t array_int32[] = {48, 49}; + int64_t array_int64[] = {49, 50}; + uint32_t array_uint32[] = {50, 51}; + double array_double[] = {51.0, 52.0}; + uint64_t array_uint64[] = {52, 53}; + + attribute_map.SetAttribute("sbool", opentelemetry::nostd::span(array_bool)); + attribute_map.SetAttribute("suint8_t", opentelemetry::nostd::span(array_uint8)); + attribute_map.SetAttribute("sint32_t", opentelemetry::nostd::span(array_int32)); + attribute_map.SetAttribute("sint64_t", opentelemetry::nostd::span(array_int64)); + attribute_map.SetAttribute("suint32_t", opentelemetry::nostd::span(array_uint32)); + attribute_map.SetAttribute("sdouble", opentelemetry::nostd::span(array_double)); + attribute_map.SetAttribute("suint64_t", opentelemetry::nostd::span(array_uint64)); + + opentelemetry::nostd::string_view array_string_view[] = {"string_view1", "string_view2"}; + attribute_map.SetAttribute( + "sstring_view", + opentelemetry::nostd::span(array_string_view)); + + EXPECT_FALSE(attribute_map.Empty()); + EXPECT_EQ(attribute_map.Size(), 16); + + CheckExceptOneValue(attribute_map, "bool", true); + CheckExceptOneValue(attribute_map, "int32_t", static_cast(42)); + CheckExceptOneValue(attribute_map, "int64_t", static_cast(43)); + CheckExceptOneValue(attribute_map, "uint32_t", static_cast(44)); + CheckExceptOneValue(attribute_map, "double", static_cast(45.0)); + CheckExceptOneValue(attribute_map, "uint64_t", static_cast(46)); + + CheckExceptOneStringView(attribute_map, "const char *", "const char *"); + CheckExceptOneStringView(attribute_map, "string_view", + "string_view"); + + CheckExceptArrayValue(attribute_map, "sbool", array_bool); + CheckExceptArrayValue(attribute_map, "suint8_t", array_uint8); + CheckExceptArrayValue(attribute_map, "sint32_t", array_int32); + CheckExceptArrayValue(attribute_map, "sint64_t", array_int64); + CheckExceptArrayValue(attribute_map, "suint32_t", array_uint32); + CheckExceptArrayValue(attribute_map, "sdouble", array_double); + CheckExceptArrayValue(attribute_map, "suint64_t", array_uint64); + CheckExceptArrayString(attribute_map, "sstring_view", array_string_view); +} + TEST(AttributeEqualToVisitorTest, AttributeValueEqualTo) { namespace sdk = opentelemetry::sdk::common; diff --git a/sdk/test/logs/log_record_test.cc b/sdk/test/logs/log_record_test.cc index 74af102e10..334ffbbae7 100644 --- a/sdk/test/logs/log_record_test.cc +++ b/sdk/test/logs/log_record_test.cc @@ -22,12 +22,14 @@ #include "opentelemetry/nostd/unique_ptr.h" #include "opentelemetry/nostd/utility.h" #include "opentelemetry/nostd/variant.h" +#include "opentelemetry/sdk/logs/log_record_data.h" #include "opentelemetry/sdk/logs/read_write_log_record.h" #include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/trace/span_id.h" #include "opentelemetry/trace/trace_flags.h" #include "opentelemetry/trace/trace_id.h" +using opentelemetry::sdk::logs::LogRecordData; using opentelemetry::sdk::logs::ReadWriteLogRecord; namespace trace_api = opentelemetry::trace; namespace logs_api = opentelemetry::logs; @@ -89,6 +91,7 @@ TEST(ReadWriteLogRecord, SetAndGet) } // Define a basic Logger class +template class TestBodyLogger : public opentelemetry::logs::Logger { public: @@ -96,7 +99,7 @@ class TestBodyLogger : public opentelemetry::logs::Logger nostd::unique_ptr CreateLogRecord() noexcept override { - return nostd::unique_ptr(new ReadWriteLogRecord()); + return nostd::unique_ptr(new BackendLogger()); } using opentelemetry::logs::Logger::EmitLogRecord; @@ -105,20 +108,27 @@ class TestBodyLogger : public opentelemetry::logs::Logger { if (record) { - last_body_ = static_cast(record.get())->GetBody(); + last_body_.reset(static_cast(record.release())); } } const opentelemetry::common::AttributeValue &GetLastLogRecord() const noexcept { - return last_body_; + if (last_body_) + { + return last_body_->GetBody(); + } + + return empty_; } private: - opentelemetry::common::AttributeValue last_body_; + opentelemetry::common::AttributeValue empty_ = nostd::string_view(); + nostd::unique_ptr last_body_; }; // Define a basic LoggerProvider class that returns an instance of the logger class defined above +template class TestBodyProvider : public opentelemetry::logs::LoggerProvider { public: @@ -131,20 +141,20 @@ class TestBodyProvider : public opentelemetry::logs::LoggerProvider nostd::string_view /* schema_url */, const opentelemetry::common::KeyValueIterable & /* attributes */) override { - return nostd::shared_ptr(new TestBodyLogger()); + return nostd::shared_ptr(new TestBodyLogger()); } }; -TEST(LogBody, BodyConversation) +TEST(ReadWriteLogRecord, BodyConversation) { // Push the new loggerprovider class into the global singleton - TestBodyProvider lp; + TestBodyProvider lp; // Check that the implementation was pushed by calling TestLogger's GetName() nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.11.0"}; auto logger = lp.GetLogger("TestBodyProvider", "opentelelemtry_library", "", schema_url, {}); - auto real_logger = static_cast(logger.get()); + auto real_logger = static_cast *>(logger.get()); real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, true); ASSERT_TRUE(opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord())); @@ -176,9 +186,262 @@ TEST(LogBody, BodyConversation) opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord()) || opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord())); if (opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord())) + { + ASSERT_EQ(nostd::string_view{"128"}, nostd::string_view{opentelemetry::nostd::get( + real_logger->GetLastLogRecord())}); + } + else { ASSERT_EQ(nostd::string_view{"128"}, - opentelemetry::nostd::get(real_logger->GetLastLogRecord())); + opentelemetry::nostd::get(real_logger->GetLastLogRecord())); + } + + { + bool data[] = {true, false, true}; + nostd::span data_span = data; + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative>( + real_logger->GetLastLogRecord())); + + nostd::span output = + opentelemetry::nostd::get>(real_logger->GetLastLogRecord()); + + ASSERT_EQ(data_span.size(), output.size()); + + for (size_t i = 0; i < data_span.size(); ++i) + { + ASSERT_TRUE(data_span[i] == output[i]); + } + } + + { + int32_t data[] = {221, 222, 223}; + nostd::span data_span = data; + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative>( + real_logger->GetLastLogRecord())); + + nostd::span output = + opentelemetry::nostd::get>(real_logger->GetLastLogRecord()); + + ASSERT_EQ(data_span.size(), output.size()); + + for (size_t i = 0; i < data_span.size(); ++i) + { + EXPECT_EQ(data_span[i], output[i]); + } + } + + { + uint32_t data[] = {231, 232, 233}; + nostd::span data_span = data; + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative>( + real_logger->GetLastLogRecord())); + + nostd::span output = + opentelemetry::nostd::get>(real_logger->GetLastLogRecord()); + + ASSERT_EQ(data_span.size(), output.size()); + + for (size_t i = 0; i < data_span.size(); ++i) + { + EXPECT_EQ(data_span[i], output[i]); + } + } + + { + int64_t data[] = {241, 242, 243}; + nostd::span data_span = data; + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative>( + real_logger->GetLastLogRecord())); + + nostd::span output = + opentelemetry::nostd::get>(real_logger->GetLastLogRecord()); + + ASSERT_EQ(data_span.size(), output.size()); + + for (size_t i = 0; i < data_span.size(); ++i) + { + EXPECT_EQ(data_span[i], output[i]); + } + } + + { + uint64_t data[] = {251, 252, 253}; + nostd::span data_span = data; + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative>( + real_logger->GetLastLogRecord())); + + nostd::span output = + opentelemetry::nostd::get>(real_logger->GetLastLogRecord()); + + ASSERT_EQ(data_span.size(), output.size()); + + for (size_t i = 0; i < data_span.size(); ++i) + { + EXPECT_EQ(data_span[i], output[i]); + } + } + + { + uint8_t data[] = {161, 162, 163}; + nostd::span data_span = data; + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative>( + real_logger->GetLastLogRecord())); + + nostd::span output = + opentelemetry::nostd::get>(real_logger->GetLastLogRecord()); + + ASSERT_EQ(data_span.size(), output.size()); + + for (size_t i = 0; i < data_span.size(); ++i) + { + EXPECT_EQ(data_span[i], output[i]); + } + } + + { + double data[] = {271.0, 272.0, 273.0}; + nostd::span data_span = data; + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative>( + real_logger->GetLastLogRecord())); + + nostd::span output = + opentelemetry::nostd::get>(real_logger->GetLastLogRecord()); + + ASSERT_EQ(data_span.size(), output.size()); + + for (size_t i = 0; i < data_span.size(); ++i) + { + ASSERT_TRUE(std::abs(data_span[i] - output[i]) < 0.0001); + } + } + + { + std::string data_origin[] = {"281", "282", "283"}; + nostd::string_view data[] = {data_origin[0], data_origin[1], data_origin[2]}; + nostd::span data_span = data; + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, data_span); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative>( + real_logger->GetLastLogRecord())); + + nostd::span output = + opentelemetry::nostd::get>( + real_logger->GetLastLogRecord()); + + ASSERT_EQ(data_span.size(), output.size()); + + for (size_t i = 0; i < data_span.size(); ++i) + { + EXPECT_EQ(data_span[i], output[i]); + } + } +} + +// Test what a default LogRecordData with no fields set holds +TEST(LogRecordData, GetDefaultValues) +{ + trace_api::TraceId zero_trace_id; + trace_api::SpanId zero_span_id; + trace_api::TraceFlags zero_trace_flags; + LogRecordData record; + + ASSERT_EQ(record.GetSeverity(), logs_api::Severity::kInvalid); + ASSERT_NE(record.GetResource().GetAttributes().size(), 0); + ASSERT_EQ(record.GetAttributes().size(), 0); + ASSERT_EQ(record.GetTraceId(), zero_trace_id); + ASSERT_EQ(record.GetSpanId(), zero_span_id); + ASSERT_EQ(record.GetTraceFlags(), zero_trace_flags); + ASSERT_EQ(record.GetTimestamp().time_since_epoch(), std::chrono::nanoseconds(0)); +} + +// Test LogRecordData fields are properly set and get +TEST(LogRecordData, SetAndGet) +{ + trace_api::TraceId trace_id; + trace_api::SpanId span_id; + trace_api::TraceFlags trace_flags; + opentelemetry::common::SystemTimestamp now(std::chrono::system_clock::now()); + + // Set most fields of the LogRecordData + LogRecordData record; + auto resource = opentelemetry::sdk::resource::Resource::Create({{"res1", true}}); + record.SetSeverity(logs_api::Severity::kInvalid); + record.SetBody("Message"); + record.SetResource(resource); + record.SetAttribute("attr1", static_cast(314159)); + record.SetTraceId(trace_id); + record.SetSpanId(span_id); + record.SetTraceFlags(trace_flags); + record.SetTimestamp(now); + + // Test that all fields match what was set + ASSERT_EQ(record.GetSeverity(), logs_api::Severity::kInvalid); + if (nostd::holds_alternative(record.GetBody())) + { + ASSERT_EQ(std::string(nostd::get(record.GetBody())), "Message"); + } + else if (nostd::holds_alternative(record.GetBody())) + { + ASSERT_TRUE(nostd::get(record.GetBody()) == "Message"); + } + ASSERT_TRUE(nostd::get(record.GetResource().GetAttributes().at("res1"))); + ASSERT_EQ(nostd::get(record.GetAttributes().at("attr1")), 314159); + ASSERT_EQ(record.GetTraceId(), trace_id); + ASSERT_EQ(record.GetSpanId(), span_id); + ASSERT_EQ(record.GetTraceFlags(), trace_flags); + ASSERT_EQ(record.GetTimestamp().time_since_epoch(), now.time_since_epoch()); +} + +TEST(LogRecordData, BodyConversation) +{ + // Push the new loggerprovider class into the global singleton + TestBodyProvider lp; + + // Check that the implementation was pushed by calling TestLogger's GetName() + nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.11.0"}; + auto logger = lp.GetLogger("TestBodyProvider", "opentelelemtry_library", "", schema_url, {}); + + auto real_logger = static_cast *>(logger.get()); + + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, true); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord())); + ASSERT_TRUE(opentelemetry::nostd::get(real_logger->GetLastLogRecord())); + + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, static_cast(123)); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord())); + ASSERT_EQ(123, opentelemetry::nostd::get(real_logger->GetLastLogRecord())); + + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, static_cast(124)); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord())); + ASSERT_EQ(124, opentelemetry::nostd::get(real_logger->GetLastLogRecord())); + + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, static_cast(125)); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord())); + ASSERT_EQ(125, opentelemetry::nostd::get(real_logger->GetLastLogRecord())); + + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, static_cast(126)); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord())); + ASSERT_EQ(126, opentelemetry::nostd::get(real_logger->GetLastLogRecord())); + + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, static_cast(127.0)); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord())); + ASSERT_TRUE(std::abs(127.0 - opentelemetry::nostd::get(real_logger->GetLastLogRecord())) < + 0.0001); + + real_logger->EmitLogRecord(opentelemetry::logs::Severity::kInfo, "128"); + ASSERT_TRUE( + opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord()) || + opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord())); + if (opentelemetry::nostd::holds_alternative(real_logger->GetLastLogRecord())) + { + ASSERT_EQ(nostd::string_view{"128"}, nostd::string_view{opentelemetry::nostd::get( + real_logger->GetLastLogRecord())}); } else { @@ -200,7 +463,7 @@ TEST(LogBody, BodyConversation) for (size_t i = 0; i < data_span.size(); ++i) { - ASSERT_EQ(data_span[i], output[i]); + ASSERT_TRUE(data_span[i] == output[i]); } } @@ -218,7 +481,7 @@ TEST(LogBody, BodyConversation) for (size_t i = 0; i < data_span.size(); ++i) { - ASSERT_EQ(data_span[i], output[i]); + EXPECT_EQ(data_span[i], output[i]); } } @@ -236,7 +499,7 @@ TEST(LogBody, BodyConversation) for (size_t i = 0; i < data_span.size(); ++i) { - ASSERT_EQ(data_span[i], output[i]); + EXPECT_EQ(data_span[i], output[i]); } } @@ -254,7 +517,7 @@ TEST(LogBody, BodyConversation) for (size_t i = 0; i < data_span.size(); ++i) { - ASSERT_EQ(data_span[i], output[i]); + EXPECT_EQ(data_span[i], output[i]); } } @@ -272,7 +535,7 @@ TEST(LogBody, BodyConversation) for (size_t i = 0; i < data_span.size(); ++i) { - ASSERT_EQ(data_span[i], output[i]); + EXPECT_EQ(data_span[i], output[i]); } } @@ -290,7 +553,7 @@ TEST(LogBody, BodyConversation) for (size_t i = 0; i < data_span.size(); ++i) { - ASSERT_EQ(data_span[i], output[i]); + EXPECT_EQ(data_span[i], output[i]); } } @@ -328,7 +591,7 @@ TEST(LogBody, BodyConversation) for (size_t i = 0; i < data_span.size(); ++i) { - ASSERT_EQ(data_span[i], output[i]); + EXPECT_EQ(data_span[i], output[i]); } } } diff --git a/third_party/prometheus-cpp b/third_party/prometheus-cpp index e5fada4313..ad99e21f47 160000 --- a/third_party/prometheus-cpp +++ b/third_party/prometheus-cpp @@ -1 +1 @@ -Subproject commit e5fada43131d251e9c4786b04263ce98b6767ba5 +Subproject commit ad99e21f4706193670c42b36c9824dc997f4c475