1
1
// Copyright The OpenTelemetry Authors
2
2
// SPDX-License-Identifier: Apache-2.0
3
3
4
+ #include < chrono>
5
+ #include < ctime>
6
+ #include < nlohmann/json.hpp>
7
+ #include < string>
8
+
4
9
#include " opentelemetry/exporters/elasticsearch/es_log_recordable.h"
5
10
#include " opentelemetry/logs/severity.h"
11
+ #include " opentelemetry/nostd/variant.h"
6
12
#include " opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
7
13
#include " opentelemetry/sdk/resource/resource.h"
8
14
#include " opentelemetry/trace/span_id.h"
9
15
#include " opentelemetry/trace/trace_flags.h"
10
16
#include " opentelemetry/trace/trace_id.h"
11
17
18
+ namespace nlohmann
19
+ {
20
+ template <>
21
+ struct adl_serializer <opentelemetry::sdk::common::OwnedAttributeValue>
22
+ {
23
+ static void to_json (json &j, const opentelemetry::sdk::common::OwnedAttributeValue &v)
24
+ {
25
+ opentelemetry::nostd::visit ([&j](const auto &value) { j = value; }, v);
26
+ }
27
+ };
28
+
29
+ template <>
30
+ struct adl_serializer <opentelemetry::common::AttributeValue>
31
+ {
32
+ static void to_json (json &j, const opentelemetry::common::AttributeValue &v)
33
+ {
34
+ opentelemetry::nostd::visit ([&j](const auto &value) { j = value; }, v);
35
+ }
36
+ };
37
+ } // namespace nlohmann
38
+
12
39
OPENTELEMETRY_BEGIN_NAMESPACE
13
40
namespace exporter
14
41
{
@@ -18,146 +45,13 @@ void ElasticSearchRecordable::WriteValue(
18
45
const opentelemetry::sdk::common::OwnedAttributeValue &value,
19
46
const std::string &name)
20
47
{
21
- namespace common = opentelemetry::sdk::common;
22
- switch (value.index ())
23
- {
24
- case common::kTypeBool :
25
- json_[name] = opentelemetry::nostd::get<bool >(value) ? true : false ;
26
- return ;
27
- case common::kTypeInt :
28
- json_[name] = opentelemetry::nostd::get<int >(value);
29
- return ;
30
- case common::kTypeInt64 :
31
- json_[name] = opentelemetry::nostd::get<int64_t >(value);
32
- return ;
33
- case common::kTypeUInt :
34
- json_[name] = opentelemetry::nostd::get<unsigned int >(value);
35
- return ;
36
- case common::kTypeUInt64 :
37
- json_[name] = opentelemetry::nostd::get<uint64_t >(value);
38
- return ;
39
- case common::kTypeDouble :
40
- json_[name] = opentelemetry::nostd::get<double >(value);
41
- return ;
42
- case common::kTypeString :
43
- json_[name] = opentelemetry::nostd::get<std::string>(value).data ();
44
- return ;
45
- default :
46
- return ;
47
- }
48
+ json_[name] = value;
48
49
}
49
50
50
51
void ElasticSearchRecordable::WriteValue (const opentelemetry::common::AttributeValue &value,
51
52
const std::string &name)
52
53
{
53
-
54
- // Assert size of variant to ensure that this method gets updated if the variant
55
- // definition changes
56
-
57
- if (nostd::holds_alternative<bool >(value))
58
- {
59
- json_[name] = opentelemetry::nostd::get<bool >(value) ? true : false ;
60
- }
61
- else if (nostd::holds_alternative<int >(value))
62
- {
63
- json_[name] = opentelemetry::nostd::get<int >(value);
64
- }
65
- else if (nostd::holds_alternative<int64_t >(value))
66
- {
67
- json_[name] = opentelemetry::nostd::get<int64_t >(value);
68
- }
69
- else if (nostd::holds_alternative<unsigned int >(value))
70
- {
71
- json_[name] = opentelemetry::nostd::get<unsigned int >(value);
72
- }
73
- else if (nostd::holds_alternative<uint64_t >(value))
74
- {
75
- json_[name] = opentelemetry::nostd::get<uint64_t >(value);
76
- }
77
- else if (nostd::holds_alternative<double >(value))
78
- {
79
- json_[name] = opentelemetry::nostd::get<double >(value);
80
- }
81
- else if (nostd::holds_alternative<const char *>(value))
82
- {
83
- json_[name] = std::string (nostd::get<const char *>(value));
84
- }
85
- else if (nostd::holds_alternative<nostd::string_view>(value))
86
- {
87
- json_[name] = static_cast <std::string>(opentelemetry::nostd::get<nostd::string_view>(value));
88
- }
89
- else if (nostd::holds_alternative<nostd::span<const uint8_t >>(value))
90
- {
91
- nlohmann::json array_value = nlohmann::json::array ();
92
- for (const auto &val : nostd::get<nostd::span<const uint8_t >>(value))
93
- {
94
- array_value.push_back (val);
95
- }
96
- json_[name] = array_value;
97
- }
98
- else if (nostd::holds_alternative<nostd::span<const bool >>(value))
99
- {
100
- nlohmann::json array_value = nlohmann::json::array ();
101
- for (const auto &val : nostd::get<nostd::span<const bool >>(value))
102
- {
103
- array_value.push_back (val);
104
- }
105
- json_[name] = array_value;
106
- }
107
- else if (nostd::holds_alternative<nostd::span<const int >>(value))
108
- {
109
- nlohmann::json array_value = nlohmann::json::array ();
110
- for (const auto &val : nostd::get<nostd::span<const int >>(value))
111
- {
112
- array_value.push_back (val);
113
- }
114
- json_[name] = array_value;
115
- }
116
- else if (nostd::holds_alternative<nostd::span<const int64_t >>(value))
117
- {
118
- nlohmann::json array_value = nlohmann::json::array ();
119
- for (const auto &val : nostd::get<nostd::span<const int64_t >>(value))
120
- {
121
- array_value.push_back (val);
122
- }
123
- json_[name] = array_value;
124
- }
125
- else if (nostd::holds_alternative<nostd::span<const unsigned int >>(value))
126
- {
127
- nlohmann::json array_value = nlohmann::json::array ();
128
- for (const auto &val : nostd::get<nostd::span<const unsigned int >>(value))
129
- {
130
- array_value.push_back (val);
131
- }
132
- json_[name] = array_value;
133
- }
134
- else if (nostd::holds_alternative<nostd::span<const uint64_t >>(value))
135
- {
136
- nlohmann::json array_value = nlohmann::json::array ();
137
- for (const auto &val : nostd::get<nostd::span<const uint64_t >>(value))
138
- {
139
- array_value.push_back (val);
140
- }
141
- json_[name] = array_value;
142
- }
143
- else if (nostd::holds_alternative<nostd::span<const double >>(value))
144
- {
145
- nlohmann::json array_value = nlohmann::json::array ();
146
- for (const auto &val : nostd::get<nostd::span<const double >>(value))
147
- {
148
- array_value.push_back (val);
149
- }
150
- json_[name] = array_value;
151
- }
152
- else if (nostd::holds_alternative<nostd::span<const nostd::string_view>>(value))
153
- {
154
- nlohmann::json array_value = nlohmann::json::array ();
155
- for (const auto &val : nostd::get<nostd::span<const nostd::string_view>>(value))
156
- {
157
- array_value.push_back (static_cast <std::string>(val));
158
- }
159
- json_[name] = array_value;
160
- }
54
+ json_[name] = value;
161
55
}
162
56
163
57
ElasticSearchRecordable::ElasticSearchRecordable () noexcept : sdk::logs::Recordable()
@@ -180,27 +74,19 @@ void ElasticSearchRecordable::SetTimestamp(
180
74
#if __cplusplus >= 202002L
181
75
const std::string dateStr = std::format (" {:%FT%T%Ez}" , timePoint);
182
76
#else
183
- const static int dateToSecondsSize = 19 ;
184
- const static int millisecondsSize = 8 ;
185
- const static int timeZoneSize = 1 ;
186
- const static int dateSize = dateToSecondsSize + millisecondsSize + timeZoneSize;
187
-
188
77
std::time_t time = std::chrono::system_clock::to_time_t (timePoint);
189
78
std::tm tm = *std::gmtime (&time);
190
-
191
- char bufferDate[dateSize]; // example: 2024-10-18T07:26:00.123456Z
192
- std::strftime (bufferDate, sizeof (bufferDate), " %Y-%m-%dT%H:%M:%S" , &tm);
193
79
auto microseconds =
194
80
std::chrono::duration_cast<std::chrono::microseconds>(timePoint.time_since_epoch ()) %
195
81
std::chrono::seconds (1 );
196
82
197
- char bufferMilliseconds[millisecondsSize];
198
- std::snprintf (bufferMilliseconds, sizeof (bufferMilliseconds), " .%06ld" ,
83
+ // `sizeof()` includes the null terminator
84
+ constexpr auto dateSize = sizeof (" YYYY-MM-DDTHH:MM:SS.uuuuuuZ" );
85
+ char bufferDate[dateSize];
86
+ auto offset = std::strftime (bufferDate, sizeof (bufferDate), " %Y-%m-%dT%H:%M:%S" , &tm);
87
+ std::snprintf (bufferDate + offset, sizeof (bufferDate) - offset, " .%06ldZ" ,
199
88
static_cast <long >(microseconds.count ()));
200
89
201
- std::strcat (bufferDate, bufferMilliseconds);
202
- std::strcat (bufferDate, " Z" );
203
-
204
90
const std::string dateStr (bufferDate);
205
91
#endif
206
92
@@ -221,9 +107,8 @@ void ElasticSearchRecordable::SetSeverity(opentelemetry::logs::Severity severity
221
107
std::uint32_t severity_index = static_cast <std::uint32_t >(severity);
222
108
if (severity_index >= std::extent<decltype (opentelemetry::logs::SeverityNumToText)>::value)
223
109
{
224
- std::stringstream sout;
225
- sout << " Invalid severity(" << severity_index << " )" ;
226
- severityField = sout.str ();
110
+ severityField =
111
+ std::string (" Invalid severity(" ).append (std::to_string (severity_index)).append (" )" );
227
112
}
228
113
else
229
114
{
@@ -240,7 +125,7 @@ void ElasticSearchRecordable::SetTraceId(const opentelemetry::trace::TraceId &tr
240
125
{
241
126
if (trace_id.IsValid ())
242
127
{
243
- char trace_buf[32 ];
128
+ char trace_buf[opentelemetry::trace::TraceId:: kSize * 2 ];
244
129
trace_id.ToLowerBase16 (trace_buf);
245
130
json_[" traceid" ] = std::string (trace_buf, sizeof (trace_buf));
246
131
}
@@ -254,7 +139,7 @@ void ElasticSearchRecordable::SetSpanId(const opentelemetry::trace::SpanId &span
254
139
{
255
140
if (span_id.IsValid ())
256
141
{
257
- char span_buf[16 ];
142
+ char span_buf[opentelemetry::trace::SpanId:: kSize * 2 ];
258
143
span_id.ToLowerBase16 (span_buf);
259
144
json_[" spanid" ] = std::string (span_buf, sizeof (span_buf));
260
145
}
@@ -282,7 +167,7 @@ void ElasticSearchRecordable::SetAttribute(
282
167
void ElasticSearchRecordable::SetResource (
283
168
const opentelemetry::sdk::resource::Resource &resource) noexcept
284
169
{
285
- for (auto &attribute : resource.GetAttributes ())
170
+ for (const auto &attribute : resource.GetAttributes ())
286
171
{
287
172
WriteValue (attribute.second , attribute.first );
288
173
}
0 commit comments