Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[v2][adjuster] Implement otel attribute adjuster to operate on otlp data model #6358

Merged
merged 15 commits into from
Dec 14, 2024

Conversation

mahadzaryab1
Copy link
Collaborator

Which problem is this PR solving?

Description of the changes

  • This PR implements the OTelTag adjuster to operate on the OTLP data model. In the OTLP model, tags are dubbed as attributes so the adjuster was renamed to OTELAttribute.

How was this change tested?

  • Added unit tests

Checklist

Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
spans := ss.Spans()
for k := 0; k < spans.Len(); k++ {
span := spans.At(k)
adjuster.adjust(span, resource)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, this is incorrect. You could, in theory, have two spans under the same Resource which have different library attributes, for whatever reason, which would require us to clone the resource. It should never happen in practice if the instrumentation is not messed up.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yurishkuro I see - do we want to fix that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than implementing the actual splitting of Resource I would go with soft validation - before copying attribute to Resource check if it already exists and if the value is the same. If the value is different then don't copy and instead add a warning to the span.

Copy link

codecov bot commented Dec 14, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 96.13%. Comparing base (c6fa1af) to head (3a2a8be).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6358   +/-   ##
=======================================
  Coverage   96.13%   96.13%           
=======================================
  Files         358      360    +2     
  Lines       20391    20429   +38     
=======================================
+ Hits        19602    19639   +37     
  Misses        603      603           
- Partials      186      187    +1     
Flag Coverage Δ
badger_v1 8.98% <ø> (ø)
badger_v2 1.63% <ø> (ø)
cassandra-4.x-v1-manual 14.96% <ø> (ø)
cassandra-4.x-v2-auto 1.57% <ø> (ø)
cassandra-4.x-v2-manual 1.57% <ø> (ø)
cassandra-5.x-v1-manual 14.96% <ø> (ø)
cassandra-5.x-v2-auto 1.57% <ø> (ø)
cassandra-5.x-v2-manual 1.57% <ø> (ø)
elasticsearch-6.x-v1 18.64% <ø> (-0.01%) ⬇️
elasticsearch-7.x-v1 18.73% <ø> (ø)
elasticsearch-8.x-v1 18.89% <ø> (ø)
elasticsearch-8.x-v2 1.62% <ø> (ø)
grpc_v1 10.49% <ø> (ø)
grpc_v2 7.92% <ø> (ø)
kafka-v1 9.30% <ø> (ø)
kafka-v2 1.63% <ø> (ø)
memory_v2 1.62% <ø> (-0.01%) ⬇️
opensearch-1.x-v1 18.77% <ø> (ø)
opensearch-2.x-v1 18.76% <ø> (-0.01%) ⬇️
opensearch-2.x-v2 1.63% <ø> (+<0.01%) ⬆️
tailsampling-processor 0.45% <ø> (ø)
unittests 95.01% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
// OTELAttribute creates an adjuster that removes the OpenTelemetry library attributes
// from spans and adds them to the attributes of a resource.
func OTELAttribute() Adjuster {
return Func(func(traces ptrace.Traces) (ptrace.Traces, error) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yurishkuro these adjusters are currently making modifications to the input traces - is that fine or do we want to make a copy of the traces before returning them?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine, the same happened with the v1 adjusters.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we could reflect that in the interface by making it not return anything.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good - i can do that in a follow-up PR

Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
} else {
v.CopyTo(resource.Attributes().PutEmpty(k))
}
span.Attributes().Remove(k)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yurishkuro we're always removing the attribute from the span - even if the value conflicts. Is that fine?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, in that case I would keep it. The design goal we observe is (a) capture input data into storage with as little rewrites as possible to assist in debugging of bad instrumentation, (b) at query time adjust the data as needed but still keep the originals visible in some way (since looking directly in storage is much harder than looking in the UI).

// from spans and adds them to the attributes of a resource.
func OTELAttribute() Adjuster {
return Func(func(traces ptrace.Traces) (ptrace.Traces, error) {
adjuster := otelAttributeAdjuster{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it feels rather convoluted, having a Func then a struct. Why not just return the struct from the public function and have it implement interface (and any helper methods) directly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done - I'll make the same change to the other adjusters in a follow-up PR

for k, v := range replace {
if existing, ok := resource.Attributes().Get(k); ok {
if existing.AsRaw() != v.AsRaw() {
span.Attributes().PutStr(adjusterWarningAttribute, "conflicting attribute values for "+k)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should have a shared util function (across all adjusters) for adding warnings to the span, and the type of the warning attribute should be []string, not a single string. It looks like you are overriding the same warnings attribute now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
for k, v := range replace {
existing, ok := resource.Attributes().Get(k)
if ok && existing.AsRaw() != v.AsRaw() {
addWarning(span, "conflicting attribute values for "+k)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
addWarning(span, "conflicting attribute values for "+k)
addWarning(span, "conflicting values between Span and Resource for attribute "+k)

)

const (
adjusterWarningAttribute = "jaeger.adjuster.warning"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
adjusterWarningAttribute = "jaeger.adjuster.warning"
warningsAttribute = "jaeger.internal.warnings"

we need this as a general mechanism for warnings, not specific to adjusters. The UI will only look in one place for these warnings.

BTW since we're adding this as Span attribute we need to alter otlp->model translation to look for this attribute and move it to the proper Span.Warnings place. I think we should find all instances of us calling OTLP<>model translations in the code and replace them with internal methods so that we always go through the same logic (i.e. call transformer from OTEL first and then run our additional transformers).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good - should this attribute constant still live in package adjuster?

Copy link
Collaborator Author

@mahadzaryab1 mahadzaryab1 Dec 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added an item for the otlp->model change to the tracking issue to address in a follow-up PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no it should not be in the adjuster, we need a neutral place across all modules. Maybe internal/model_v2

Copy link
Collaborator Author

@mahadzaryab1 mahadzaryab1 Dec 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yurishkuro do we want to introduce the name model for v2? it feels like model has been synonymous with v1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, I don't like it either. Any other ideas? jotlp?

mahadzaryab1 and others added 2 commits December 14, 2024 17:03
Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com>
@yurishkuro yurishkuro merged commit 10cb6a9 into jaegertracing:main Dec 14, 2024
54 checks passed
@mahadzaryab1 mahadzaryab1 deleted the otel-tag-adjuster branch January 6, 2025 00:42
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants