Skip to content

Commit 7225046

Browse files
authored
Merge branch 'main' into cmake-config-find-dependencies
2 parents b92f316 + 5e62859 commit 7225046

File tree

5 files changed

+56
-235
lines changed

5 files changed

+56
-235
lines changed

api/include/opentelemetry/nostd/internal/absl/meta/type_traits.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -106,18 +106,6 @@ struct VoidTImpl {
106106
using type = void;
107107
};
108108

109-
// This trick to retrieve a default alignment is necessary for our
110-
// implementation of aligned_storage_t to be consistent with any implementation
111-
// of std::aligned_storage.
112-
template <size_t Len, typename T = std::aligned_storage<Len>>
113-
struct default_alignment_of_aligned_storage;
114-
115-
template <size_t Len, size_t Align>
116-
struct default_alignment_of_aligned_storage<Len,
117-
std::aligned_storage<Len, Align>> {
118-
static constexpr size_t value = Align;
119-
};
120-
121109
////////////////////////////////
122110
// Library Fundamentals V2 TS //
123111
////////////////////////////////
@@ -619,10 +607,6 @@ using remove_extent_t = typename std::remove_extent<T>::type;
619607
template <typename T>
620608
using remove_all_extents_t = typename std::remove_all_extents<T>::type;
621609

622-
template <size_t Len, size_t Align = type_traits_internal::
623-
default_alignment_of_aligned_storage<Len>::value>
624-
using aligned_storage_t = typename std::aligned_storage<Len, Align>::type;
625-
626610
template <typename T>
627611
using decay_t = typename std::decay<T>::type;
628612

exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class ElasticSearchRecordable final : public sdk::logs::Recordable
4242
void WriteValue(const opentelemetry::common::AttributeValue &value, const std::string &name);
4343

4444
public:
45+
ElasticSearchRecordable() noexcept;
46+
4547
/**
4648
* Returns a JSON object contain the log information
4749
*/

exporters/elasticsearch/src/es_log_recordable.cc

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ void ElasticSearchRecordable::WriteValue(const opentelemetry::common::AttributeV
197197
}
198198
}
199199

200+
ElasticSearchRecordable::ElasticSearchRecordable() noexcept : sdk::logs::Recordable()
201+
{
202+
json_["ecs"]["version"] = "8.11.0";
203+
}
204+
200205
nlohmann::json ElasticSearchRecordable::GetJSON() noexcept
201206
{
202207
return json_;
@@ -205,7 +210,38 @@ nlohmann::json ElasticSearchRecordable::GetJSON() noexcept
205210
void ElasticSearchRecordable::SetTimestamp(
206211
opentelemetry::common::SystemTimestamp timestamp) noexcept
207212
{
208-
json_["timestamp"] = timestamp.time_since_epoch().count();
213+
const std::chrono::system_clock::time_point timePoint{timestamp};
214+
215+
// If built with with at least cpp 20 then use std::format
216+
// Otherwise use the old style to format the timestamp in UTC
217+
#if __cplusplus >= 202002L
218+
const std::string dateStr = std::format("{:%FT%T%Ez}", timePoint);
219+
#else
220+
const static int dateToSecondsSize = 19;
221+
const static int millisecondsSize = 8;
222+
const static int timeZoneSize = 1;
223+
const static int dateSize = dateToSecondsSize + millisecondsSize + timeZoneSize;
224+
225+
std::time_t time = std::chrono::system_clock::to_time_t(timePoint);
226+
std::tm tm = *std::gmtime(&time);
227+
228+
char bufferDate[dateSize]; // example: 2024-10-18T07:26:00.123456Z
229+
std::strftime(bufferDate, sizeof(bufferDate), "%Y-%m-%dT%H:%M:%S", &tm);
230+
auto microseconds =
231+
std::chrono::duration_cast<std::chrono::microseconds>(timePoint.time_since_epoch()) %
232+
std::chrono::seconds(1);
233+
234+
char bufferMilliseconds[millisecondsSize];
235+
std::snprintf(bufferMilliseconds, sizeof(bufferMilliseconds), ".%06ld",
236+
static_cast<long>(microseconds.count()));
237+
238+
std::strcat(bufferDate, bufferMilliseconds);
239+
std::strcat(bufferDate, "Z");
240+
241+
const std::string dateStr(bufferDate);
242+
#endif
243+
244+
json_["@timestamp"] = dateStr;
209245
}
210246

211247
void ElasticSearchRecordable::SetObservedTimestamp(
@@ -216,23 +252,25 @@ void ElasticSearchRecordable::SetObservedTimestamp(
216252

217253
void ElasticSearchRecordable::SetSeverity(opentelemetry::logs::Severity severity) noexcept
218254
{
255+
auto &severityField = json_["log"]["level"];
256+
219257
// Convert the severity enum to a string
220258
std::uint32_t severity_index = static_cast<std::uint32_t>(severity);
221259
if (severity_index >= std::extent<decltype(opentelemetry::logs::SeverityNumToText)>::value)
222260
{
223261
std::stringstream sout;
224262
sout << "Invalid severity(" << severity_index << ")";
225-
json_["severity"] = sout.str();
263+
severityField = sout.str();
226264
}
227265
else
228266
{
229-
json_["severity"] = opentelemetry::logs::SeverityNumToText[severity_index];
267+
severityField = opentelemetry::logs::SeverityNumToText[severity_index];
230268
}
231269
}
232270

233271
void ElasticSearchRecordable::SetBody(const opentelemetry::common::AttributeValue &message) noexcept
234272
{
235-
WriteValue(message, "body");
273+
WriteValue(message, "message");
236274
}
237275

238276
void ElasticSearchRecordable::SetTraceId(const opentelemetry::trace::TraceId &trace_id) noexcept
@@ -275,7 +313,7 @@ void ElasticSearchRecordable::SetAttribute(
275313
nostd::string_view key,
276314
const opentelemetry::common::AttributeValue &value) noexcept
277315
{
278-
WriteKeyValue(key, value, "attributes");
316+
WriteValue(value, key.data());
279317
}
280318

281319
void ElasticSearchRecordable::SetResource(
@@ -291,7 +329,7 @@ void ElasticSearchRecordable::SetInstrumentationScope(
291329
const opentelemetry::sdk::instrumentationscope::InstrumentationScope
292330
&instrumentation_scope) noexcept
293331
{
294-
json_["name"] = instrumentation_scope.GetName();
332+
json_["log"]["logger"] = instrumentation_scope.GetName();
295333
}
296334

297335
} // namespace logs

exporters/etw/README.md

Lines changed: 2 additions & 212 deletions
Original file line numberDiff line numberDiff line change
@@ -12,215 +12,5 @@ subsequent data recording or forwarding to alternate pipelines and flows.
1212
Windows Event Tracing infrastructure is available to any vendor or application
1313
being deployed on Windows.
1414

15-
## API support
16-
17-
These are the features planned to be supported by ETW exporter:
18-
19-
- [x] OpenTelemetry Tracing API and SDK headers are **stable** and moving
20-
towards GA.
21-
- [ ] OpenTelemetry Logging API is work-in-progress, pending implementation of
22-
[Latest Logging API spec
23-
here](https://github.com/open-telemetry/oteps/pull/150)
24-
- [ ] OpenTelemetry Metrics API is not implemented yet.
25-
26-
Implementation of OpenTelemetry C++ SDK ETW exporter on Windows OS is `header
27-
only` :
28-
29-
- full definitions of all macros, functions and classes comprising the library
30-
are visible to the compiler in a header file form.
31-
- implementation does not need to be separately compiled, packaged and installed
32-
in order to be used.
33-
34-
All that is required is to point the compiler at the location of the headers,
35-
and then `#include` the header files into the application source. Compiler's
36-
optimizer can do a much better job when all the library's source code is
37-
available. Several options below may be turned on to optimize the code with the
38-
usage of standard C++ library, Microsoft Guidelines Support library, Google
39-
Abseil Variant library. Or enabling support for non-standard features, such as
40-
8-bit byte arrays support that enables performance-efficient representation of
41-
binary blobs on ETW wire.
42-
43-
## Example project
44-
45-
The following include directories are required, relative to the top-level source
46-
tree of OpenTelemetry C++ repo:
47-
48-
- api/include/
49-
- exporters/etw/include/
50-
- sdk/include/
51-
52-
Code that instantiates ETW TracerProvider, subsequently obtaining a Tracer bound
53-
to `OpenTelemetry-ETW-Provider`, and emitting a span named `MySpan` with
54-
attributes on it, as well as `MyEvent` within that span.
55-
56-
```cpp
57-
58-
#include <map>
59-
#include <string>
60-
61-
#include "opentelemetry/exporters/etw/etw_tracer_exporter.h"
62-
63-
using namespace OPENTELEMETRY_NAMESPACE;
64-
using namespace opentelemetry::exporter::etw;
65-
66-
// Supply unique instrumentation name (ETW Provider Name) here:
67-
std::string providerName = "OpenTelemetry-ETW-Provider";
68-
69-
exporter::etw::TracerProvider tp;
70-
71-
int main(int argc, const char* argv[])
72-
{
73-
// Obtain a Tracer object for instrumentation name.
74-
// Each Tracer is associated with unique TraceId.
75-
auto tracer = tp.GetTracer(providerName, "TLD");
76-
77-
// Properties is a helper class in ETW namespace that is otherwise compatible
78-
// with Key-Value Iterable accepted by OpenTelemetry API. Using Properties
79-
// should enable more efficient data transfer without unnecessary memcpy.
80-
81-
// Span attributes
82-
Properties attribs =
83-
{
84-
{"attrib1", 1},
85-
{"attrib2", 2}
86-
};
87-
88-
// Start Span with attributes
89-
auto span = tracer->StartSpan("MySpan", attribs);
90-
91-
// Emit an event on Span
92-
std::string eventName = "MyEvent1";
93-
Properties event =
94-
{
95-
{"uint32Key", (uint32_t)1234},
96-
{"uint64Key", (uint64_t)1234567890},
97-
{"strKey", "someValue"}
98-
};
99-
span->AddEvent(eventName, event);
100-
101-
// End Span.
102-
span->End();
103-
104-
// Close the Tracer on application stop.
105-
tracer->CloseWithMicroseconds(0);
106-
107-
return 0;
108-
}
109-
```
110-
111-
Note that different `Tracer` objects may be bound to different ETW destinations.
112-
113-
## Build options and Compiler Defines
114-
115-
While including OpenTelemetry C++ SDK with ETW exporter, the customers are in
116-
complete control of what options they would like to enable for their project
117-
using `Preprocessor Definitions`.
118-
119-
These options affect how "embedded in application" OpenTelemetry C++ SDK code is
120-
compiled:
121-
122-
| Name | Description |
123-
|---------------------|------------------------------------------------------------------------------------------------------------------------|
124-
| OPENTELEMETRY_STL_VERSION | Use STL classes for API surface. C++20 is recommended. Some customers may benefit from STL library provided with the compiler instead of using custom OpenTelemetry `nostd::` implementation due to security and performance considerations. |
125-
| HAVE_GSL | Use [Microsoft GSL](https://github.com/microsoft/GSL) for `gsl::span` implementation. Library must be in include path. Microsoft GSL claims to be the most feature-complete implementation of `std::span`. It may be used instead of `nostd::span` implementation in projects that statically link OpenTelemetry SDK. |
126-
| HAVE_TLD | Use ETW/TraceLogging Dynamic protocol. This is the default implementation compatible with existing C# "listeners" / "decoders" of ETW events. This option requires an additional optional Microsoft MIT-licensed `TraceLoggingDynamic.h` header. |
127-
128-
## Debugging
129-
130-
### ETW TraceLogging Dynamic Events
131-
132-
ETW supports a mode that is called "Dynamic Manifest", where event may contain
133-
strongly-typed key-value pairs, with primitive types such as `integer`,
134-
`double`, `string`, etc. This mode requires `TraceLoggingDynamic.h` header.
135-
Please refer to upstream repository containining [Microsoft TraceLogging Dynamic
136-
framework](https://github.com/microsoft/tracelogging-dynamic-windows) licensed
137-
under [MIT
138-
License](https://github.com/microsoft/tracelogging-dynamic-windows/blob/main/LICENSE).
139-
140-
Complete [list of ETW
141-
types](https://docs.microsoft.com/en-us/windows/win32/wes/eventmanifestschema-outputtype-complextype#remarks).
142-
143-
OpenTelemetry C++ ETW exporter implements the following type mapping:
144-
145-
| OpenTelemetry C++ API type | ETW type |
146-
|----------------------------|-----------------|
147-
| bool | xs:byte |
148-
| int (32-bit) | xs:int |
149-
| int (64-bit) | xs:long |
150-
| uint (32-bit) | xs:unsignedInt |
151-
| uint (64-bit) | xs:unsignedLong |
152-
| double | xs:double |
153-
| string | win:Utf8 |
154-
155-
Support for arrays of primitive types is not implemented yet.
156-
157-
Visual Studio 2019 allows to use `View -> Other Windows -> Diagnostic Events` to
158-
capture events that are emitted by instrumented application and sent to ETW
159-
provider in a live view. Instrumentation name passed to `GetTracer` API above
160-
corresponds to `ETW Provider Name`. If Instrumentation name contains a GUID -
161-
starts with a curly brace, e.g. `{deadbeef-fade-dead-c0de-cafebabefeed}` then
162-
the parameter is assumed to be `ETW Provider GUID`.
163-
164-
Click on `Settings` and add the provider to monitor either by its Name or by
165-
GUID. In above example, the provider name is `OpenTelemetry-ETW-Provider`.
166-
Please refer to Diagnostic Events usage instructions
167-
[here](https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-diagnostics-how-to-monitor-and-diagnose-services-locally#view-service-fabric-system-events-in-visual-studio)
168-
to learn more. Note that running ETW Listener in Visual Studio requires
169-
Elevation, i.e. Visual Studio would prompt you to confirm that you accept to run
170-
the ETW Listener process as Administrator. This is a limitation of ETW
171-
Listeners, they must be run as privileged process.
172-
173-
### ETW events encoded in MessagePack
174-
175-
OpenTelemetry ETW exporter optionally allows to encode the incoming event
176-
payload using [MessagePack](https://msgpack.org/index.html) compact binary
177-
protocol. ETW/MsgPack encoding requires
178-
[nlohmann/json](https://github.com/nlohmann/json) library to be included in the
179-
build of OpenTelemetry ETW exporter. Any recent version of `nlohmann/json` is
180-
compatible with ETW exporter. For example, the version included in
181-
`third_party/nlohmann-json` directory may be used.
182-
183-
There is currently **no built-in decoder available** for this format. However,
184-
there is ongoing effort to include the ETW/MsgPack decoder in
185-
[Azure/diagnostics-eventflow](https://github.com/Azure/diagnostics-eventflow)
186-
project, which may be used as a side-car listener to forward incoming
187-
ETW/MsgPack events to many other destinations, such as:
188-
189-
- StdOutput (console output)
190-
- HTTP (json via http)
191-
- Application Insights
192-
- Azure EventHub
193-
- Elasticsearch
194-
- Azure Monitor Logs
195-
196-
And community-contributed exporters:
197-
198-
- Google Big Query output
199-
- SQL Server output
200-
- ReflectInsight output
201-
- Splunk output
202-
203-
[This PR](https://github.com/Azure/diagnostics-eventflow/pull/382) implements
204-
the `Input adapter` for OpenTelemetry ETW/MsgPack protocol encoded events for
205-
Azure EventFlow.
206-
207-
Other standard tools for processing ETW events on Windows OS, such as:
208-
209-
- [PerfView](https://github.com/microsoft/perfview)
210-
- [PerfViewJS](https://github.com/microsoft/perfview/tree/main/src/PerfViewJS)
211-
212-
will be augmented in future with support for ETW/MsgPack encoding.
213-
214-
## Addendum
215-
216-
This document needs to be supplemented with additional information:
217-
218-
- [ ] mapping between OpenTelemetry fields and concepts and their corresponding
219-
ETW counterparts
220-
- [ ] links to E2E instrumentation example and ETW listener
221-
- [ ] Logging API example
222-
- [ ] Metrics API example (once Metrics spec is finalized)
223-
- [ ] example how ETW Listener may employ OpenTelemetry .NET SDK to 1-1
224-
transform from ETW events back to OpenTelemetry flow
225-
- [ ] links to NuGet package that contains the source code of SDK that includes
226-
OpenTelemetry SDK and ETW exporter
15+
It is recommended to consume this exporter via
16+
[vcpkg](https://vcpkg.io/en/package/opentelemetry-cpp).

exporters/otlp/src/otlp_grpc_client.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ static sdk::common::ExportResult InternalDelegateAsyncExport(
207207
stub->experimental_async()
208208
# endif
209209
->Export(call_data->grpc_context.get(), call_data->request, call_data->response,
210-
[call_data, async_data](::grpc::Status grpc_status) {
210+
[call_data, async_data, export_data_name](::grpc::Status grpc_status) {
211211
--async_data->running_requests;
212212
++async_data->finished_request_counter;
213213

@@ -216,6 +216,13 @@ static sdk::common::ExportResult InternalDelegateAsyncExport(
216216
{
217217
call_data->export_result = opentelemetry::sdk::common::ExportResult::kSuccess;
218218
}
219+
else
220+
{
221+
OTEL_INTERNAL_LOG_ERROR("[OTLP GRPC Client] ERROR: Export "
222+
<< export_data_name << " failed with status_code: \""
223+
<< grpc_status.error_code() << "\" error_message: \""
224+
<< grpc_status.error_message() << "\"");
225+
}
219226

220227
if (call_data->grpc_async_callback)
221228
{

0 commit comments

Comments
 (0)