1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
4 #ifdef ENABLE_LOGS_PREVIEW
5 # include "opentelemetry/exporters/ostream/log_exporter.h"
7 # include "opentelemetry/exporters/ostream/common_utils.h"
8 # include "opentelemetry/sdk_config.h"
11 # include <type_traits>
13 namespace nostd
= opentelemetry::nostd
;
14 namespace sdklogs
= opentelemetry::sdk::logs
;
15 namespace sdkcommon
= opentelemetry::sdk::common
;
16 OPENTELEMETRY_BEGIN_NAMESPACE
22 /*********************** Constructor ***********************/
24 OStreamLogExporter::OStreamLogExporter(std::ostream
&sout
) noexcept
: sout_(sout
) {}
26 /*********************** Exporter methods ***********************/
28 std::unique_ptr
<sdklogs::Recordable
> OStreamLogExporter::MakeRecordable() noexcept
30 return std::unique_ptr
<sdklogs::Recordable
>(new sdklogs::LogRecord());
33 sdk::common::ExportResult
OStreamLogExporter::Export(
34 const nostd::span
<std::unique_ptr
<sdklogs::Recordable
>> &records
) noexcept
38 OTEL_INTERNAL_LOG_ERROR("[Ostream Log Exporter] Exporting "
39 << records
.size() << " log(s) failed, exporter is shutdown");
40 return sdk::common::ExportResult::kFailure
;
43 for (auto &record
: records
)
45 // Convert recordable to a LogRecord so that the getters of the LogRecord can be used
47 std::unique_ptr
<sdklogs::LogRecord
>(static_cast<sdklogs::LogRecord
*>(record
.release()));
49 if (log_record
== nullptr)
51 // TODO: Log Internal SDK error "recordable data was lost"
55 // Convert trace, spanid, traceflags into exportable representation
56 constexpr int trace_id_len
= 32;
57 constexpr int span_id__len
= 16;
58 constexpr int trace_flags_len
= 2;
60 char trace_id
[trace_id_len
] = {0};
61 char span_id
[span_id__len
] = {0};
62 char trace_flags
[trace_flags_len
] = {0};
64 log_record
->GetTraceId().ToLowerBase16(trace_id
);
65 log_record
->GetSpanId().ToLowerBase16(span_id
);
66 log_record
->GetTraceFlags().ToLowerBase16(trace_flags
);
68 // Print out each field of the log record, noting that severity is separated
69 // into severity_num and severity_text
71 << " timestamp : " << log_record
->GetTimestamp().time_since_epoch().count() << "\n"
72 << " severity_num : " << static_cast<std::uint32_t>(log_record
->GetSeverity()) << "\n"
73 << " severity_text : ";
75 std::uint32_t severity_index
= static_cast<std::uint32_t>(log_record
->GetSeverity());
76 if (severity_index
>= std::extent
<decltype(opentelemetry::logs::SeverityNumToText
)>::value
)
78 sout_
<< "Invalid severity(" << severity_index
<< ")\n";
82 sout_
<< opentelemetry::logs::SeverityNumToText
[severity_index
] << "\n";
85 sout_
<< " body : " << log_record
->GetBody() << "\n"
88 printAttributes(log_record
->GetResource().GetAttributes());
93 printAttributes(log_record
->GetAttributes());
96 << " trace_id : " << std::string(trace_id
, trace_id_len
) << "\n"
97 << " span_id : " << std::string(span_id
, span_id__len
) << "\n"
98 << " trace_flags : " << std::string(trace_flags
, trace_flags_len
) << "\n"
102 return sdk::common::ExportResult::kSuccess
;
105 bool OStreamLogExporter::Shutdown(std::chrono::microseconds timeout
) noexcept
107 const std::lock_guard
<opentelemetry::common::SpinLockMutex
> locked(lock_
);
112 bool OStreamLogExporter::isShutdown() const noexcept
114 const std::lock_guard
<opentelemetry::common::SpinLockMutex
> locked(lock_
);
118 void OStreamLogExporter::printAttributes(
119 const std::unordered_map
<std::string
, sdkcommon::OwnedAttributeValue
> &map
,
120 const std::string prefix
)
122 for (const auto &kv
: map
)
124 sout_
<< prefix
<< kv
.first
<< ": ";
125 opentelemetry::exporter::ostream_common::print_value(kv
.second
, sout_
);
130 } // namespace exporter
131 OPENTELEMETRY_END_NAMESPACE