Aid developers who wish to port existing datadog (dd-trace-rb) instrumentation to opentelemetry.
- There should be a subclass of
OpenTelemetry::Instrumentation::Base
that implements its DSL:- Implement
install
block, where all of the integration work happens - Implement
present
block - Optionally, implement
compatible
- See
OpenTelemetry::Instrumentation::Base
API documentation for more details
- Implement
- Add Gemfile, opentelemetry-instrumentation-#{name}.gemspec
- Add runnable (docker) example (using its own Gemfile)
$ docker-compose run ex-instrumentation-myinstrumentation bundle install
$ docker-compose run ex-instrumentation-myinstrumentation
bash-5.0$ ruby trace_demonstration.rb
- Rakefile
tests/test_helper.rb
- Integrate rubocop (see open-telemetry/opentelemetry-ruby#172 (review))
instrumentation/faraday
andinstrumentation/sinatra
were the earliest, simplest implementations
- It's ok to use
require_relative
for files that are internal to the project - Don't load integration implementation (require file) until
install
('patch')-time - Most times, only want to run installation (via
#install
) once, but need to consider being able toreset
somehow for, e.g., testing
Tracer
:name
and:version
should come from instrumentation/base, not from the instrumented library
- Wrap instrumented-library operations in
span
(viatracer.in_span
(block), ortracer.start_span
(returnsSpan
))Span.finish
should be called if usingtracer.start_span
- Span
:with_parent
defaults tocurrent_span
- Prefer "low-cardinality" names (see open-telemetry/opentelemetry-specification#416)
Span
attribute keys should be strings, not symbolsSpan
attribute values should be strings, not symbols- Prefer to populate span attributes via method arguments (e.g.,
tracer.in_span(attributes: ...
) instead ofspan.set_attribute
- Some
Span
attribute naming is based on semantic conventions, for example HTTP semantic conventions- When opening a PR, it would be useful to note which attributes come from which semantic conventions, and which ones could not be found
Span
:kind
defaults to:internal
(other available options include:client
or:server
)
- Gemfile should include "opentelemetry-instrumentation-#{instrumentation_name}"
Watch for "low hanging fruit" performance improvements including:
- reduce object allocations - move to a constant, or cache values that would be generated repeatedly
- look for "easy wins" vs. "complete redesigns"
- Add tests via minitest (not rspec)
- Test against multiple versions of instrumented library via
appraisal
- GOTCHA: appraisal-2.2.0 + bundler-2.1.x (at least 2.1.4)
- Configure
.circleci/config.yml
- Try to preserve all applicable tests from dd-trace-rb
- Skip tests datadog-specific configurations
- Skip tests for things that are not being ported
- For client-only libraries, just
inject
- For server-side libraries,
extract
remote span context from request headers, then start a new span using parent context (e.g.,tracer.in_span(with_parent_context: ...
) - Use the plain
http_text_format
rather thanrack_http_text_format
- Allow instrumentation to function when underlying dependency (e.g.,
faraday
gem) isn't present- Don't create a hard-dependency on instrumented libraries
opentelemetry-sdk
is only needed for tests
span.set_tag
=>span.set_attribute
Datadog::Logger.log.debug
=>OpenTelemetry.logger.debug
span.resource
=> ?? possiblyspan.attributes[:url]
, etc., possibly ignoredspan.service
=>span.name
span.span_type
=>span.attributes[:component]
options[:tracer]
=>OpenTelemetry.tracer_factory.tracer
(then, e.g.,Instrumentation.tracer
)
- Pin ('patch info') -- probably deprecated in dd-trace-rb
- Configuration option for
:distributed_tracing
(should always be enabled) - Deprecation paths
- Passing spans/information around ENV
Span#set_error
Contrib::Analytics
- Quantization
- set a tag (attribute) value only once (check if set already)?