Update use of published_at_ns in process context C/C++ implementation + some small fixes#66
Conversation
This variant happens when `memfd_create` fails and we fall back to an anonymous mapping. See [upstream spec](open-telemetry/opentelemetry-specification@25f2ea7) for more details.
The previous naming was mostly a leftover of older versions of the spec.
These `extra_attributes` are for providing attributes that are not part of the Resource. See `process_context.proto` and open-telemetry/opentelemetry-specification#4719 for details.
MFD_NOEXEC_SEAL is a newer Linux flag; kernels that don't support it return EINVAL because unused bits in flags must be 0. On first failure, retry with only MFD_CLOEXEC | MFD_ALLOW_SEALING so older kernels can still use memfd for the OTEL process context.
This ensures the reader doesn't get confused.
With the introduction of `update`, we decided to use `published_at_ns` as the synchronization field for readers. But, for publish, the signature was instead doing that work. To simplify readers, let's always use the `published_at_ns` to synchronize both on `publish` as well as `update`.
…ntext **What does this PR do?** This PR adds support for the `threadlocal.schema_version` and `threadlocal.attribute_key_map` extra attributes to be used by the process context, as per https://docs.google.com/document/d/1eatbHpEXXhWZEPrXZpfR58-5RIx-81mUgF69Zpn3Rz4/edit?tab=t.bmgoq3yor67o **Motivation:** Having these keys being supported makes it easy to experiment with thread context sharing. **Additional Notes:** As discussion around the thread context evolves, it's quite likely these keys might need to change a bit still. I'm stacking this PR on top of open-telemetry#66 to avoid piling more stuff on top of that one, but they are otherwise mostly independent. Reading these extra elements is a bit verbose but since the reader code can be disabled and is mostly only for testing I guess it's still fine? **How to test the change?** As usual, the example has been updated to match!
This variant happens when `memfd_create` fails and we fall back to an anonymous mapping. See [upstream spec](open-telemetry/opentelemetry-specification@25f2ea7) for more details.
| static uint64_t time_now_ns(void) { | ||
| struct timespec ts; | ||
| if (clock_gettime(CLOCK_REALTIME, &ts) == -1) return 0; | ||
| return ts.tv_sec * 1000000000ULL + ts.tv_nsec; | ||
| } |
There was a problem hiding this comment.
I just saw that you updated the specification in the OTEP to dictate a monotonic clock. As a follow-up, we should also switch to a monotonic clock here.
There are two main ways to go about it (which IIRC we haven't previously clarified):
- Switch
CLOCK_REALTIMEtoCLOCK_BOOTTIMEorCLOCK_MONOTONIC - Calculate a delta between monotonic and realtime clock (once, on startup, fixed for lifetime of process) and add it to each subsequent monotonic measurement (from
CLOCK_BOOTTIMEorCLOCK_MONOTONIC).
1 gives us a monotonic counter but loses the correlation with a realtime clock as the resulting nanosecond values have no specified base (starting point).
2 gives us a monotonic counter which can also be interpreted as nanoseconds-since-the-epoch.
For an example of 2 in the eBPF profiler, see here.
No need to do this in this PR, whatever you prefer.
There was a problem hiding this comment.
Ah, right, I called it out in open-telemetry/opentelemetry-specification#4719 (comment) and I meant to open a PR with this as follow-up to avoid piling on this one that had already been reviewed
There was a problem hiding this comment.
Thanks. I went ahead with the merge since you said it's not blocking for this PR, but I'm sure @ivoanjo will take a look shortly.
There was a problem hiding this comment.
So the change I already have locally and was going to open a PR with next used approach 1, not 2....
There are two main ways to go about it (which IIRC we haven't previously clarified):
...No need to do this in this PR, whatever you prefer.
...and the reason I'm slightly leaning towards 1, because I think if we want 2, we should update the spec as well to effectively codify there the approach you've linked to from the eBPF profiler.
Otherwise, if only some implementations do 2, then it's harder to rely on the value being something sane.
I guess let me know your thoughts either here or on that follow-up PR and we can adjust :)
…ntext **What does this PR do?** This PR adds support for the `threadlocal.schema_version` and `threadlocal.attribute_key_map` extra attributes to be used by the process context, as per https://docs.google.com/document/d/1eatbHpEXXhWZEPrXZpfR58-5RIx-81mUgF69Zpn3Rz4/edit?tab=t.bmgoq3yor67o **Motivation:** Having these keys being supported makes it easy to experiment with thread context sharing. **Additional Notes:** As discussion around the thread context evolves, it's quite likely these keys might need to change a bit still. I'm stacking this PR on top of open-telemetry#66 to avoid piling more stuff on top of that one, but they are otherwise mostly independent. Reading these extra elements is a bit verbose but since the reader code can be disabled and is mostly only for testing I guess it's still fine? **How to test the change?** As usual, the example has been updated to match!
…ntext (#67) **What does this PR do?** This PR adds support for the `threadlocal.schema_version` and `threadlocal.attribute_key_map` extra attributes to be used by the process context, as per https://docs.google.com/document/d/1eatbHpEXXhWZEPrXZpfR58-5RIx-81mUgF69Zpn3Rz4/edit?tab=t.bmgoq3yor67o . I can't stack this PR on top of #66 because both of the branches are on my fork, but only the last commit (implementing thread context) differs between them. Once #66 is merged a quick rebase should clean things up. **Motivation:** Having these keys being supported makes it easy to experiment with thread context sharing. **Additional Notes:** As discussion around the thread context evolves, it's quite likely these keys might need to change a bit still. Reading these extra elements is a bit verbose but since the reader code can be disabled and is mostly only for testing I guess it's still fine? **How to test the change?** As usual, the example has been updated to match!
…` in process context C/C++ impl **What does this PR do?** This PR updates the process context C/C++ implementation to match the change in the upstream specification in open-telemetry/opentelemetry-specification@15256ee to adopt a monotonic clock. **Motivation:** Using a monotonic clock means that readers can't get confused by clocks going backward, and we can trivially about the ABA issue (because if the clock can't ever go back, we can always add 1 to a previous read to ensure no two timestamps are ever the same). **Additional Notes:** In open-telemetry#66 (comment) we discussed that this could be implemented by directly using the `CLOCK_MONOTONIC`, or alternatively we could map the monotonic clock back to a regular ns from epoch. I had this commit already ready and it takes the first approach, but let's discuss? ;) **How to test the change?** In practice readers don't really need to change unless they were trying to interpret the timestamp and pretty-print it (as the bash script was).
… in process context C/C++ impl (#79) **What does this PR do?** This PR updates the process context C/C++ implementation to match the change in the upstream specification in open-telemetry/opentelemetry-specification@15256ee to adopt a monotonic clock. **Motivation:** Using a monotonic clock means that readers can't get confused by clocks going backward, and we can trivially about the ABA issue (because if the clock can't ever go back, we can always add 1 to a previous read to ensure no two timestamps are ever the same). **Additional Notes:** In #66 (comment) we discussed that this could be implemented by directly using the `CLOCK_MONOTONIC`, or alternatively we could map the monotonic clock back to a regular ns from epoch. I had this commit already ready and it takes the first approach, but let's discuss? ;) **How to test the change?** In practice readers don't really need to change unless they were trying to interpret the timestamp and pretty-print it (as the bash script was).
What does this PR do?
This PR collects a number of fixes to the process context C/C++ implementation. I recommend reviewing it commit-by-commit (and let me know if this is too annoying to review, I can break it down further).
The changes around "MFD_NOEXEC_SEAL on failure" and "Change publish synchronization to use timestamp instead of signature" I haven't yet pushed the change to the upstream spec, I'll do that next, but I wanted to have a working version first :)
Motivation:
Improve implementation/spec :)
Additional Notes:
N/A
How to test the change?
The built-in decoder and otel_process_ctx_dump.sh have been updated to match.