Skip to content

feat: add net_ldap instrumentation #1587

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

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

scbjans
Copy link
Contributor

@scbjans scbjans commented Jul 9, 2025

Largely based on prior work in #1432 by @Hareramrai and @jdehaan

Since that PR seems stale, I've updated it with some small edits to comply with release management using toys.

Should fix: github.com//issues/669

@@ -231,7 +237,8 @@ gems:

- name: opentelemetry-propagator-google_cloud_trace_context
directory: propagator/google_cloud_trace_context
version_constant: [OpenTelemetry, Propagator, GoogleCloudTraceContext, VERSION]
version_constant:
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did you add new lines to the GCP related definitions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your quick review @arielvalentin !

I guess this is from the format on save option in VSCode which I accidentally committed. I'll revert it.

I'll respond to the other comments this Friday.

module LDAP
# The Instrumentation class contains logic to detect and install the Net::LDAP
# instrumentation
class Instrumentation < OpenTelemetry::Instrumentation::Base
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a min version requirement?

Copy link

Choose a reason for hiding this comment

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

FYI: We tested the original implementation using gem 'net-ldap' 0.17.0 if that info helps in finding out some requirements. As it's a 0.x version we assumed all bets are off in this case....

Copy link
Contributor Author

@scbjans scbjans Jul 11, 2025

Choose a reason for hiding this comment

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

Thanks, I only tested this with net-ldap 0.19.0. I'm inclined to say we should set a minimal version to 0.17.1, since in that version Ruby3.x support was added (as in added to CI), since our minimum Ruby version is 3.1 (which is also EOL, shall I put up a PR for that as well?)
cb5f1c4

Copy link

Choose a reason for hiding this comment

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

That sounds very reasonable to me, we are also planning to upgrade anyways soon.

yield(payload).tap do |response|
annotate_span_with_response!(span, response)
end
rescue StandardError => e
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't in_span already handle Error Recording and setting the status?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it does, but it doesn't add the ldap.error_message attribute. I've updated this a bit, and in 0583992 we'll rescue specifically on a ::Net::LDAP::Error

LDAP::Instrumentation.instance.config
end

def annotate_span_with_response!(span, response)
Copy link
Contributor

Choose a reason for hiding this comment

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

Only add a ! if you have an existing method that does not have a !

Copy link
Contributor Author

Choose a reason for hiding this comment

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


return if ::Net::LDAP::ResultCodesNonError.include?(status_code)

span.record_exception(error_message) unless error_message.empty?
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe record_exception is an explicit helper for exception events. Consider using the Span Status Code description instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@@ -227,4 +231,4 @@
"version-file": "lib/opentelemetry/resource/detector/google_cloud_platform/version.rb"
}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
}
}

OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => host || hosts,
OpenTelemetry::SemanticConventions::Trace::NET_PEER_PORT => port,
OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE => instrumentation_config[:peer_service]
}.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes)
Copy link
Contributor

Choose a reason for hiding this comment

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

why is this amending HTTP Client attributes? How is that relevant to LDAP lookups?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TBH I just took the already existing stale PR that originally was opened to add this instrumentation. That did the job for me, and I thought it might be beneficial for others to have this instrumentation more easily available.
I rushed this a bit and skipped the due diligence (sorry!), so I'm glad you ask.

It doesn't: I removed it.

@encryption = args[:encryption]
end

def instrument(event, payload)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want more specific attribute mappers here for each of these events?

https://github.com/search?q=repo%3Aruby-ldap%2Fruby-net-ldap+%2Finstrument+%22%2F&type=code

I do not particularly like the practice of dumping json strings where we do not know if the contents of the provided payload have sensitive information in them.


tracer.in_span(
event,
attributes: attributes.compact,
Copy link
Contributor

Choose a reason for hiding this comment

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

This allocates and extra hash object.

lets avoid that by checking if the values are present before adding them to the hash.

tracer.in_span(
event,
attributes: attributes.compact,
kind: :client
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think LDAP qualifies as RPC? Would using RPC client semantics be right for this?
Would using ECS style events make more sense for these?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was inclined to say LDAP qualifies as RPC, but my AI friend does not agree with me. Apparently LDAP itself is not RPC, but it is often combined with RPC (e.g. when joining computers to Windows domains), but we're only instrumenting LDAP in this case. Semconv doesn't specify anything for ldap, and other languages don't seem to have ldap instrumentation.

I'm not sure what to do here.

@scbjans scbjans marked this pull request as draft July 9, 2025 14:30
def initialize(args = {})
super

@instrumentation_service = args[:instrumentation_service] || OpenTelemetry::Instrumentation::Net::LDAP::InstrumentationService.new({
Copy link
Contributor

Choose a reason for hiding this comment

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

Another thought I have here, what if we added this otel instrumentation as a decorator to the injected service?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants