diff --git a/exporters/elasticsearch/src/es_log_record_exporter.cc b/exporters/elasticsearch/src/es_log_record_exporter.cc index 1ec786a198..cb7386f3da 100644 --- a/exporters/elasticsearch/src/es_log_record_exporter.cc +++ b/exporters/elasticsearch/src/es_log_record_exporter.cc @@ -63,7 +63,7 @@ class ResponseHandler : public http_client::EventHandler { log_message = BuildResponseLogMessage(response, body_); - OTEL_INTERNAL_LOG_ERROR("ES Log Exporter] Export failed, " << log_message); + OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] Export failed, " << log_message); } if (console_debug_) diff --git a/exporters/elasticsearch/src/es_log_recordable.cc b/exporters/elasticsearch/src/es_log_recordable.cc index 3412a8cc61..0e7c3b0344 100644 --- a/exporters/elasticsearch/src/es_log_recordable.cc +++ b/exporters/elasticsearch/src/es_log_recordable.cc @@ -1,14 +1,41 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#include +#include +#include +#include + #include "opentelemetry/exporters/elasticsearch/es_log_recordable.h" #include "opentelemetry/logs/severity.h" +#include "opentelemetry/nostd/variant.h" #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.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" +namespace nlohmann +{ +template <> +struct adl_serializer +{ + static void to_json(json &j, const opentelemetry::sdk::common::OwnedAttributeValue &v) + { + opentelemetry::nostd::visit([&j](const auto &value) { j = value; }, v); + } +}; + +template <> +struct adl_serializer +{ + static void to_json(json &j, const opentelemetry::common::AttributeValue &v) + { + opentelemetry::nostd::visit([&j](const auto &value) { j = value; }, v); + } +}; +} // namespace nlohmann + OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter { @@ -18,146 +45,13 @@ void ElasticSearchRecordable::WriteValue( const opentelemetry::sdk::common::OwnedAttributeValue &value, const std::string &name) { - namespace common = opentelemetry::sdk::common; - switch (value.index()) - { - case common::kTypeBool: - json_[name] = opentelemetry::nostd::get(value) ? true : false; - return; - case common::kTypeInt: - json_[name] = opentelemetry::nostd::get(value); - return; - case common::kTypeInt64: - json_[name] = opentelemetry::nostd::get(value); - return; - case common::kTypeUInt: - json_[name] = opentelemetry::nostd::get(value); - return; - case common::kTypeUInt64: - json_[name] = opentelemetry::nostd::get(value); - return; - case common::kTypeDouble: - json_[name] = opentelemetry::nostd::get(value); - return; - case common::kTypeString: - json_[name] = opentelemetry::nostd::get(value).data(); - return; - default: - return; - } + json_[name] = value; } void ElasticSearchRecordable::WriteValue(const opentelemetry::common::AttributeValue &value, const std::string &name) { - - // Assert size of variant to ensure that this method gets updated if the variant - // definition changes - - if (nostd::holds_alternative(value)) - { - json_[name] = opentelemetry::nostd::get(value) ? true : false; - } - else if (nostd::holds_alternative(value)) - { - json_[name] = opentelemetry::nostd::get(value); - } - else if (nostd::holds_alternative(value)) - { - json_[name] = opentelemetry::nostd::get(value); - } - else if (nostd::holds_alternative(value)) - { - json_[name] = opentelemetry::nostd::get(value); - } - else if (nostd::holds_alternative(value)) - { - json_[name] = opentelemetry::nostd::get(value); - } - else if (nostd::holds_alternative(value)) - { - json_[name] = opentelemetry::nostd::get(value); - } - else if (nostd::holds_alternative(value)) - { - json_[name] = std::string(nostd::get(value)); - } - else if (nostd::holds_alternative(value)) - { - json_[name] = static_cast(opentelemetry::nostd::get(value)); - } - else if (nostd::holds_alternative>(value)) - { - nlohmann::json array_value = nlohmann::json::array(); - for (const auto &val : nostd::get>(value)) - { - array_value.push_back(val); - } - json_[name] = array_value; - } - else if (nostd::holds_alternative>(value)) - { - nlohmann::json array_value = nlohmann::json::array(); - for (const auto &val : nostd::get>(value)) - { - array_value.push_back(val); - } - json_[name] = array_value; - } - else if (nostd::holds_alternative>(value)) - { - nlohmann::json array_value = nlohmann::json::array(); - for (const auto &val : nostd::get>(value)) - { - array_value.push_back(val); - } - json_[name] = array_value; - } - else if (nostd::holds_alternative>(value)) - { - nlohmann::json array_value = nlohmann::json::array(); - for (const auto &val : nostd::get>(value)) - { - array_value.push_back(val); - } - json_[name] = array_value; - } - else if (nostd::holds_alternative>(value)) - { - nlohmann::json array_value = nlohmann::json::array(); - for (const auto &val : nostd::get>(value)) - { - array_value.push_back(val); - } - json_[name] = array_value; - } - else if (nostd::holds_alternative>(value)) - { - nlohmann::json array_value = nlohmann::json::array(); - for (const auto &val : nostd::get>(value)) - { - array_value.push_back(val); - } - json_[name] = array_value; - } - else if (nostd::holds_alternative>(value)) - { - nlohmann::json array_value = nlohmann::json::array(); - for (const auto &val : nostd::get>(value)) - { - array_value.push_back(val); - } - json_[name] = array_value; - } - else if (nostd::holds_alternative>(value)) - { - nlohmann::json array_value = nlohmann::json::array(); - for (const auto &val : nostd::get>(value)) - { - array_value.push_back(static_cast(val)); - } - json_[name] = array_value; - } + json_[name] = value; } ElasticSearchRecordable::ElasticSearchRecordable() noexcept : sdk::logs::Recordable() @@ -180,27 +74,19 @@ void ElasticSearchRecordable::SetTimestamp( #if __cplusplus >= 202002L const std::string dateStr = std::format("{:%FT%T%Ez}", timePoint); #else - const static int dateToSecondsSize = 19; - const static int millisecondsSize = 8; - const static int timeZoneSize = 1; - const static int dateSize = dateToSecondsSize + millisecondsSize + timeZoneSize; - std::time_t time = std::chrono::system_clock::to_time_t(timePoint); std::tm tm = *std::gmtime(&time); - - char bufferDate[dateSize]; // example: 2024-10-18T07:26:00.123456Z - std::strftime(bufferDate, sizeof(bufferDate), "%Y-%m-%dT%H:%M:%S", &tm); auto microseconds = std::chrono::duration_cast(timePoint.time_since_epoch()) % std::chrono::seconds(1); - char bufferMilliseconds[millisecondsSize]; - std::snprintf(bufferMilliseconds, sizeof(bufferMilliseconds), ".%06ld", + // `sizeof()` includes the null terminator + constexpr auto dateSize = sizeof("YYYY-MM-DDTHH:MM:SS.uuuuuuZ"); + char bufferDate[dateSize]; + auto offset = std::strftime(bufferDate, sizeof(bufferDate), "%Y-%m-%dT%H:%M:%S", &tm); + std::snprintf(bufferDate + offset, sizeof(bufferDate) - offset, ".%06ldZ", static_cast(microseconds.count())); - std::strcat(bufferDate, bufferMilliseconds); - std::strcat(bufferDate, "Z"); - const std::string dateStr(bufferDate); #endif @@ -221,9 +107,8 @@ void ElasticSearchRecordable::SetSeverity(opentelemetry::logs::Severity severity std::uint32_t severity_index = static_cast(severity); if (severity_index >= std::extent::value) { - std::stringstream sout; - sout << "Invalid severity(" << severity_index << ")"; - severityField = sout.str(); + severityField = + std::string("Invalid severity(").append(std::to_string(severity_index)).append(")"); } else { @@ -240,7 +125,7 @@ void ElasticSearchRecordable::SetTraceId(const opentelemetry::trace::TraceId &tr { if (trace_id.IsValid()) { - char trace_buf[32]; + char trace_buf[opentelemetry::trace::TraceId::kSize * 2]; trace_id.ToLowerBase16(trace_buf); json_["traceid"] = std::string(trace_buf, sizeof(trace_buf)); } @@ -254,7 +139,7 @@ void ElasticSearchRecordable::SetSpanId(const opentelemetry::trace::SpanId &span { if (span_id.IsValid()) { - char span_buf[16]; + char span_buf[opentelemetry::trace::SpanId::kSize * 2]; span_id.ToLowerBase16(span_buf); json_["spanid"] = std::string(span_buf, sizeof(span_buf)); } @@ -282,7 +167,7 @@ void ElasticSearchRecordable::SetAttribute( void ElasticSearchRecordable::SetResource( const opentelemetry::sdk::resource::Resource &resource) noexcept { - for (auto &attribute : resource.GetAttributes()) + for (const auto &attribute : resource.GetAttributes()) { WriteValue(attribute.second, attribute.first); }