Skip to content
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

Opentracing bridge #108

Closed
wants to merge 45 commits into from
Closed

Conversation

rdooley
Copy link
Contributor

@rdooley rdooley commented Sep 25, 2019

I believe this is ready for review again (and probably could do with me squashing work)

.travis.yml Outdated Show resolved Hide resolved
@fbogsany
Copy link
Contributor

I'd remove the "shim" suffix everywhere.

@fbogsany
Copy link
Contributor

Also, the suggested terminology here is "bridges"

@rdooley
Copy link
Contributor Author

rdooley commented Sep 26, 2019

@fbogsany so something like opentracingbridge/lib/opentelemetry/opentracingbridge/span.rb ?

@rdooley rdooley changed the title WIP: Opentracing shim WIP: Opentracing bridge Sep 26, 2019
@fbogsany
Copy link
Contributor

Either of the following:

opentelemetry-ruby/opencensus/lib/opentelemetry/opencensus/span.rb
opentelemetry-ruby/opencensus/opentelemetry-opencensus.gemspec
opentelemetry-ruby/opentracing/lib/opentelemetry/opentracing/span.rb
opentelemetry-ruby/opentracing/lib/opentelemetry-opentracing.gemspec

or

opentelemetry-ruby/bridges/opentracing/lib/opentelemetry/bridge/opentracing/span.rb
opentelemetry-ruby/bridges/opentracing/opentelemetry-bridge-opentracing.gemspec
...

I kinda like the second. I'm a little 🤷‍♂ about pluralizing the top-level directory, but leaning toward the plural. So:

api
sdk
bridges
exporters
adapters

at the top-level.

@rdooley
Copy link
Contributor Author

rdooley commented Sep 26, 2019

The plural makes sense to me, on it

.travis.yml Outdated Show resolved Hide resolved
@@ -48,6 +48,12 @@ commands:
- run:
name: CI (Jaeger)
command: "cd exporters/jaeger && bundle exec rake"
- run:
name: Bundle (OpenTracing Bridge)
command: "cd bridges/opentracing && gem install --no-document bundler && bundle install --jobs=3 --retry=3"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Very weird jruby thing where if you bundle OTrace bridge before CI jaeger (or vise versa) whichever you bundled before the other one, fails its CI step with e.g.

File does not exist: thrift

@rdooley rdooley requested a review from fbogsany February 6, 2020 15:36
@rdooley rdooley requested a review from fbogsany February 12, 2020 15:36
@rdooley rdooley requested a review from mwear February 24, 2020 15:58
@mwear
Copy link
Member

mwear commented Feb 27, 2020

👋 @rdooley I definitely owe you a review, which I'll try to get in tomorrow. Thanks for your patience 🙏!

Copy link
Member

@mwear mwear left a comment

Choose a reason for hiding this comment

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

I went through this and spotted a few things that are definitely issues. I took things a step further and tried this out on a small test app and it does not work. Mainly due to the fact that child_of can be an OpenTelemetry::Context. There are definitely more issues beyond those I mentioned. I'm going to paste in the sample app I tested with as I think it could be useful to help validate your work as you go.

The test app is a simple rack app. You can drop it in a config.ru file and run it with rackup. You can spin up two instances say, on ports 3000 and 3001 and it will make a request to the next instance. It has instrumentation for Rack and Faraday, so you should be able to get a distributed tracing linking up between both of them.

Gemfile

adjust paths for your local checkout of otel:

source 'https://rubygems.org'

gem 'rack'
gem 'faraday'
gem 'rack-tracer'
gem 'faraday-tracer'
gem 'opentelemetry-bridge-opentracing', path: '../../opentelemetry-ruby/bridges/opentracing'
gem 'opentelemetry-api', path: '../../opentelemetry-ruby/api'
gem 'opentelemetry-sdk', path: '../../opentelemetry-ruby/sdk'

app

drop this in a config.ru

require 'bundler'
Bundler.require

require 'opentelemetry/bridge/opentracing'

OpenTelemetry::SDK.configure
OpenTracing.global_tracer = OpenTelemetry::Bridge::OpenTracing::Tracer.new(OpenTelemetry.tracer_factory.tracer('default'))

class App
  class << self
    def call(env)
      call_next(env)
      [200, {}, ["Hello world!"]]
    end

    def call_next(env)
      puts "request: #{next_url(env)}"
      resp = http_conn.get(next_url(env))
      resp.body
    rescue => e
      puts e.inspect
    end

    def next_url(env)
      host = env['SERVER_NAME']
      port = env['SERVER_PORT'].to_i + 1
      "http://#{host}:#{port}"
    end

    def http_conn
      @http_conn ||= Faraday.new do |f|
        f.use Faraday::Tracer
        f.request :url_encoded
        f.adapter Faraday.default_adapter
      end
    end
  end
end

use Rack::Tracer

run App
  • Note: your branch is out a date a bit with master. The tracer_factory is now a tracer_provider. Keep that in mind if you rebase.

Let me know if this helps get you moving in the right direction and reach out if you have any questions.

ignore_active_scope: false,
finish_on_close: true,
&block)
child_of = child_of.span unless child_of.instance_of? OpenTelemetry::Trace::Span
Copy link
Member

Choose a reason for hiding this comment

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

You need to be able to handle the case where child_of is an OpenTelemetry::Context. If child of is a Context you'll want to pass that as with_parent_context.

tags: nil,
ignore_active_scope: false,
&block)
child_of = child_of.span unless child_of.instance_of? OpenTelemetry::Trace::Span
Copy link
Member

Choose a reason for hiding this comment

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

The same applies here.

context = context.set_value(OpenTelemetry::Trace::Propagation::ContextKeys.current_span_key, span)
case format
when ::OpenTracing::FORMAT_TEXT_MAP
OpenTelemetry::Trace::Propagation.http_trace_context_injector.inject(context, carrier) do |c, k, v|
Copy link
Member

Choose a reason for hiding this comment

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

If we want to interop with the OpenTelemetry Tracer, both inject and extract should use the global propagators, i.e. OpenTelemetry.propagation.inject and OpenTelemetry.propagation.extract.

links: references,
start_timestamp: start_time)
wrapped = Span.new(span, dist_context: span.context)
scope = Scope.new(ScopeManager.instance, wrapped, finish_on_close)
Copy link
Member

Choose a reason for hiding this comment

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

Scope activation / deactivation (closing) needs to correspond with an OpenTelemetry::Context containing the active span being attached and detached. Attach makes that the current context, whereas detach restores the previous context. Manual Context#attach and Context#detach are somewhat dangerous, as each call to attach and detach need to match, however, I think the scope concept from OT should make this work out.

@mwear mwear mentioned this pull request Feb 29, 2020
rdooley added 2 commits March 10, 2020 12:41
* intermediate check in
* fix some rubocop stuff
* add logic/test surrounding starting a span using an Otelem context as
  parent
* take a stab at the inject/extract using OTelem globals
Base automatically changed from master to main January 28, 2021 22:57
@fbogsany
Copy link
Contributor

This is out of date and the spec has tightened up around OT compatibility for Otel. Closing this in favour of a new implementation.

@fbogsany fbogsany closed this Mar 16, 2021
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.

4 participants