-
Notifications
You must be signed in to change notification settings - Fork 438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding semantic-convention attributes for trace #868
Conversation
Codecov Report
@@ Coverage Diff @@
## main #868 +/- ##
=======================================
Coverage 95.36% 95.36%
=======================================
Files 159 159
Lines 6776 6776
=======================================
Hits 6461 6461
Misses 315 315
|
#include "opentelemetry/version.h" | ||
|
||
#define OTEL_TRACE_GENERATE_SEMCONV_METHOD(attribute_name, attribute_value) \ | ||
static const nostd::string_view Get##attribute_name() noexcept \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally this should be expressible as constexpr
- to return the value of it at compile time, without incurring the overhead of a static method call. I'm not sure if the getters give significant benefit, as in - better structure or something? From Google C++ style document: Global strings: if you require a global or static string constant, consider using a simple character array, or a char pointer to the first element of a string literal. String literals have static storage duration already and are usually sufficient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can we do it in an all header way without getters
? C++11 won't allow initializing static std::string
/nostd::string
within class definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You just don't use getters. Use constants with constexpr
definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or if you use getters, return straight the literal constant type without any class:
Thanks for your suggestions. I have modified the code to create the constrxpr
function and return literal. For another suggestion on using the constrxpr
variable, somehow, I don't see these getting optimized in different translation units by gcc compiler ( small pingy code to demonstrate that: https://www.onlinegdb.com/IjRRjLjZo ). But anyway preferred the constexpr
function as we don't need to depend on linker/compiler optimization here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To summarise the available options:
option1: constexpr static class methods
: The advantage of using these is that only those methods are generated (in .text segment) at compile time which are used across all the translation units. The rest of the unused methods are ignored.
option2: constexpr static global functions in the namespace
: This will create a copy of the used functions in each translation unit while ignoring the rest of the unused functions.
option3: constexpt static variables in the namespace
: This will create a local copy of all the variables in each of the translation units including the header, and it seems that the gcc compiler doesn't optimize it.
The right solution comes from the C++17 inline
variables, but option1
seems to be the correct approach for C++11 which is now implemented in this PR. We can discuss if there are any issues with the approach.
examples/http/server.cc
Outdated
options); | ||
auto span = get_tracer("http-server") | ||
->StartSpan(span_name, | ||
{{SemanticConventions::GetAttributeHttpServerName(), server_name}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks rather bulky, in my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. Do we have a better way of handling this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are several options:
- make methods
constexpr
and return a string literal constant, inited as const char * or char array - or just define all string constants in a dedicated namespace, that enables
using
for those who want to write it in a shorter form. Then for gcc / clang this scenario is already optimized, and for msvc we need to enable string pooling to combine all strings into one region of memory. These constants all have global static duration, there is no need to "get" them, they'd be efficiently compile-time optimized. Usingstring_view
for that is an overkill.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion. I did initially wanted to use the second option but wasn't aware of the compiler optimization of this static global across multiple translation units. Let me try that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in prev comment, have created the constexpr
function now.
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md | ||
|
||
// Genetal network connection attributes | ||
OTEL_TRACE_GENERATE_SEMCONV_METHOD(AttributeNetTransport, "net.transport") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expand Attribute
in name AttributeNetTransport
in the macro of OTEL_TRACE_GENERATE_SEMCONV_METHOD
instead of duplicating it for every macro call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Will do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is done now.
|
||
// Genetal network connection attributes | ||
OTEL_TRACE_GENERATE_SEMCONV_METHOD(AttributeNetTransport, "net.transport") | ||
OTEL_TRACE_GENERATE_SEMCONV_METHOD(AttributeNetPeerIp, "net.peer.ip") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we generate these definitions from the YAML definition of semantic conventions such as https://github.com/open-telemetry/opentelemetry-specification/blob/main/semantic_conventions/trace/http.yaml?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...and could we generate them, and make them constexpr
string constants? These would be encouraged by Google C++ coding style, and provide the most optimal compile-time optimization. Global strings: if you require a global or static string constant, consider using a simple character array, or a char pointer to the first element of a string literal. String literals have static storage duration already and are usually sufficient.
.. constexpr string literal or string array should work, with all of these constants having unique prefix. Rather than grouping them in class - we group them in namespace. There is also a compile time flag that allows string pooling, we use that to avoid bloating in case if the same header gets included in different compilation units. For Visual Studio compiler that is /GF (Eliminate Duplicate Strings)
. And for gcc / clang I think it's on by default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we generate these definitions from the YAML definition of semantic conventions such as
I did think of writing a script
to parse the yaml file and generate C++ code containing these consts
from that and add it as part of CI. But this data is not going to change on daily basis, and instead, it would be fine to modify our code a couple of times before GA to be consistent.
For otel-python and otel-go, they do have a script to generate code for these constants, along with other semantic data ( eg creating enums for allowable values for attributes, defining constraints of the list of attributes to be used etc) which we don't need to do. The current approach in this PR is as done by otel-dotnet
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ThomsonTan - Have created issue for automatic generation of these definitions : #873
Once we finalize the approach to use, first ( and probably initial few ) definitions can be committed manually while someone works on a script to generate code as per the finalized approach. Hope that works.
@maxgolov @ThomsonTan I have modified the current implementation in this PR as per the logic used for sem-conv for Resources in #872. Please review it again. Thanks., |
Fixes #566
Changes
This PR adds semantics as defined here:
https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions
This will let us use uniform attributes/events/exceptions names across services.
This is currently used in the HTTP and gRPC example. These may be used in exporters too, would create PR to replace there.
For significant contributions please make sure you have completed the following items:
CHANGELOG.md
updated for non-trivial changes