Skip to content

Commit

Permalink
Merge pull request #553 from DataDog/0.16-dev
Browse files Browse the repository at this point in the history
0.16.0 to stable
  • Loading branch information
delner authored Sep 20, 2018
2 parents 22f9943 + 3718e64 commit edd3d55
Show file tree
Hide file tree
Showing 47 changed files with 2,741 additions and 47 deletions.
16 changes: 14 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@

## [Unreleased (beta)]

## [0.16.0] - 2018-09-18

Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.16.0

Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.15.0...v0.16.0

### Added

- OpenTracing support (#517)
- `middleware` option for disabling Rails trace middleware. (#552)

## [0.15.0] - 2018-09-12

Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.15.0
Expand Down Expand Up @@ -500,8 +511,9 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1

Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1

[Unreleased (stable)]: https://github.com/DataDog/dd-trace-rb/compare/v0.15.0...master
[Unreleased (beta)]: https://github.com/DataDog/dd-trace-rb/compare/v0.15.0...0.16-dev
[Unreleased (stable)]: https://github.com/DataDog/dd-trace-rb/compare/v0.16.0...master
[Unreleased (beta)]: https://github.com/DataDog/dd-trace-rb/compare/v0.16.0...0.17-dev
[0.15.0]: https://github.com/DataDog/dd-trace-rb/compare/v0.15.0...v0.16.0
[0.15.0]: https://github.com/DataDog/dd-trace-rb/compare/v0.14.2...v0.15.0
[0.14.2]: https://github.com/DataDog/dd-trace-rb/compare/v0.14.1...v0.14.2
[0.14.1]: https://github.com/DataDog/dd-trace-rb/compare/v0.14.0...v0.14.1
Expand Down
10 changes: 9 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ namespace :spec do

RSpec::Core::RakeTask.new(:main) do |t|
t.pattern = 'spec/**/*_spec.rb'
t.exclude_pattern = 'spec/**/{contrib,benchmark,redis}/**/*_spec.rb'
t.exclude_pattern = 'spec/**/{contrib,benchmark,redis,opentracer}/**/*_spec.rb'
end

RSpec::Core::RakeTask.new(:opentracer) do |t|
t.pattern = 'spec/ddtrace/opentracer/**/*_spec.rb'
end

RSpec::Core::RakeTask.new(:rails) do |t|
Expand Down Expand Up @@ -311,6 +315,7 @@ task :ci do
sh 'bundle exec rake test:main'
sh 'bundle exec rake spec:main'
sh 'bundle exec rake spec:contrib'
sh 'bundle exec rake spec:opentracer'

if RUBY_PLATFORM != 'java'
# Contrib minitests
Expand Down Expand Up @@ -366,6 +371,7 @@ task :ci do
sh 'bundle exec rake test:main'
sh 'bundle exec rake spec:main'
sh 'bundle exec rake spec:contrib'
sh 'bundle exec rake spec:opentracer'

if RUBY_PLATFORM != 'java'
# Contrib minitests
Expand Down Expand Up @@ -432,6 +438,7 @@ task :ci do
sh 'bundle exec rake test:main'
sh 'bundle exec rake spec:main'
sh 'bundle exec rake spec:contrib'
sh 'bundle exec rake spec:opentracer'

if RUBY_PLATFORM != 'java'
# Contrib minitests
Expand Down Expand Up @@ -497,6 +504,7 @@ task :ci do
sh 'bundle exec rake test:main'
sh 'bundle exec rake spec:main'
sh 'bundle exec rake spec:contrib'
sh 'bundle exec rake spec:opentracer'

if RUBY_PLATFORM != 'java'
# Contrib minitests
Expand Down
2 changes: 2 additions & 0 deletions ddtrace.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Gem::Specification.new do |spec|
spec.require_paths = ['lib']

spec.add_dependency 'msgpack'
# TODO: Move this to Appraisals?
spec.add_dependency 'opentracing', '>= 0.4.1'

spec.add_development_dependency 'rake', '>= 10.5'
spec.add_development_dependency 'rubocop', '= 0.49.1' if RUBY_VERSION >= '2.1.0'
Expand Down
76 changes: 72 additions & 4 deletions docs/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ For descriptions of terminology used in APM, take a look at the [official docume
- [Installation](#installation)
- [Quickstart for Rails applications](#quickstart-for-rails-applications)
- [Quickstart for Ruby applications](#quickstart-for-ruby-applications)
- [Quickstart for OpenTracing](#quickstart-for-opentracing)
- [Manual instrumentation](#manual-instrumentation)
- [Integration instrumentation](#integration-instrumentation)
- [Active Record](#active-record)
Expand Down Expand Up @@ -59,6 +60,7 @@ For descriptions of terminology used in APM, take a look at the [official docume
- [Processing pipeline](#processing-pipeline)
- [Filtering](#filtering)
- [Processing](#processing)
- [OpenTracing](#opentracing)

## Compatibility

Expand All @@ -75,10 +77,6 @@ For descriptions of terminology used in APM, take a look at the [official docume
| | | 2.4 | Full |
| JRuby | http://jruby.org/ | 9.1.5 | Experimental |

*Full* support indicates all tracer features are available.

*Experimental* indicates most features should be available, but unverified.

**Supported web servers**:

| Type | Documentation | Version | Support type |
Expand All @@ -87,6 +85,16 @@ For descriptions of terminology used in APM, take a look at the [official docume
| Unicorn | https://bogomips.org/unicorn/ | 4.8+ / 5.1+ | Full |
| Passenger | https://www.phusionpassenger.com/ | 5.0+ | Full |

**Supported tracing frameworks**:

| Type | Documentation | Version | Support type |
| ----------- | ----------------------------------------------- | --------------------- | ------------ |
| OpenTracing | https://github.com/opentracing/opentracing-ruby | 0.4.1+ (w/ Ruby 2.1+) | Experimental |

*Full* support indicates all tracer features are available.

*Experimental* indicates most features should be available, but unverified.

## Installation

The following steps will help you quickly start tracing your Ruby application.
Expand Down Expand Up @@ -136,6 +144,36 @@ The Ruby APM tracer sends trace data through the Datadog Agent.
1. Activate integration instrumentation (see [Integration instrumentation](#integration-instrumentation))
2. Add manual instrumentation around your code (see [Manual instrumentation](#manual-instrumentation))

### Quickstart for OpenTracing

1. Install the gem with `gem install ddtrace`
2. To your OpenTracing configuration file, add the following:

```ruby
require 'opentracing'
require 'ddtrace'
require 'ddtrace/opentracer'
# Activate the Datadog tracer for OpenTracing
OpenTracing.global_tracer = Datadog::OpenTracer::Tracer.new
```

3. (Optional) Add a configuration block to your Ruby application to configure Datadog with:

```ruby
Datadog.configure do |c|
# Configure the Datadog tracer here.
# Activate integrations, change tracer settings, etc...
# By default without additional configuration,
# no additional integrations will be traced, only
# what you have instrumented with OpenTracing.
end
```

4. (Optional) Add or activate additional instrumentation by doing either of the following:
1. Activate Datadog integration instrumentation (see [Integration instrumentation](#integration-instrumentation))
2. Add Datadog manual instrumentation around your code (see [Manual instrumentation](#manual-instrumentation))

### Final steps for installation

After setting up, your services will appear on the [APM services page](https://app.datadoghq.com/apm/services) within a few minutes. Learn more about [using the APM UI][visualization docs].
Expand Down Expand Up @@ -869,6 +907,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
| ``database_service`` | Database service name used when tracing database activity | ``<app_name>-<adapter_name>`` |
| ``exception_controller`` | Class or Module which identifies a custom exception controller class. Tracer provides improved error behavior when it can identify custom exception controllers. By default, without this option, it 'guesses' what a custom exception controller looks like. Providing this option aids this identification. | ``nil`` |
| ``distributed_tracing`` | Enables [distributed tracing](#distributed-tracing) so that this service trace is connected with a trace of another service if tracing headers are received | `false` |
| ``middleware`` | Add the trace middleware to the Rails application. Set to `false` if you don't want the middleware to load. | `true` |
| ``middleware_names`` | Enables any short-circuited middleware requests to display the middleware name as resource for the trace. | `false` |
| ``template_base_path`` | Used when the template name is parsed. If you don't store your templates in the ``views/`` folder, you may need to change this value | ``views/`` |
| ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
Expand Down Expand Up @@ -1510,3 +1549,32 @@ Datadog::Pipeline.before_flush(
Datadog::Pipeline::SpanProcessor.new { |span| span.resource.gsub!(/password=.*/, '') }
)
```
### OpenTracing
For setting up Datadog with OpenTracing, see out [Quickstart for OpenTracing](#quickstart-for-opentracing) section for details.
**Configuring Datadog tracer settings**
The underlying Datadog tracer can be configured by passing options (which match `Datadog::Tracer`) when configuring the global tracer:
```ruby
# Where `options` is a Hash of options provided to Datadog::Tracer
OpenTracing.global_tracer = Datadog::OpenTracer::Tracer.new(options)
```
It can also be configured by using `Datadog.configure` described in the [Tracer settings](#tracer-settings) section.
**Activating and configuring integrations**
By default, configuring OpenTracing with Datadog will not automatically activate any additional instrumentation provided by Datadog. You will only receive spans and traces from OpenTracing instrumentation you have in your application.
However, additional instrumentation provided by Datadog can be activated alongside OpenTracing using `Datadog.configure`, which can be used to further enhance your tracing. To activate this, see [Integration instrumentation](#integration-instrumentation) for more details.
**Supported serialization formats**
| Type | Supported? | Additional information |
| ------------------------------ | ---------- | ---------------------- |
| `OpenTracing::FORMAT_TEXT_MAP` | Yes | |
| `OpenTracing::FORMAT_RACK` | Yes | Because of the loss of resolution in the Rack format, please note that baggage items with names containing either upper case characters or `-` will be converted to lower case and `_` in a round-trip respectively. We recommend avoiding these characters, or accommodating accordingly on the receiving end. |
| `OpenTracing::FORMAT_BINARY` | No | |
3 changes: 2 additions & 1 deletion lib/ddtrace/contrib/rack/patcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def patch
@patched = true
end

if !@middleware_patched && get_option(:middleware_names)
if (!instance_variable_defined?(:@middleware_patched) || !@middleware_patched) \
&& get_option(:middleware_names)
if get_option(:application)
enable_middleware_names
@middleware_patched = true
Expand Down
42 changes: 39 additions & 3 deletions lib/ddtrace/contrib/rails/patcher.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
require 'ddtrace/contrib/rails/utils'
require 'ddtrace/contrib/rails/framework'
require 'ddtrace/contrib/rails/middlewares'
require 'ddtrace/contrib/rack/middlewares'

module Datadog
module Contrib
Expand All @@ -17,6 +20,7 @@ module Patcher
Datadog.configuration[:active_record][:service_name] = value
end
end
option :middleware, default: true
option :middleware_names, default: false
option :distributed_tracing, default: false
option :template_base_path, default: 'views/'
Expand All @@ -28,7 +32,41 @@ module Patcher
class << self
def patch
return @patched if patched? || !compatible?
require_relative 'framework'

# Add a callback hook to add the trace middleware before the application initializes.
# Otherwise the middleware stack will be frozen.
do_once(:rails_before_initialize_hook) do
::ActiveSupport.on_load(:before_initialize) do
# Sometimes we don't want to activate middleware e.g. OpenTracing, etc.
if Datadog.configuration[:rails][:middleware]
# Add trace middleware
config.middleware.insert_before(0, Datadog::Contrib::Rack::TraceMiddleware)

# Insert right after Rails exception handling middleware, because if it's before,
# it catches and swallows the error. If it's too far after, custom middleware can find itself
# between, and raise exceptions that don't end up getting tagged on the request properly.
# e.g lost stack trace.
config.middleware.insert_after(
ActionDispatch::ShowExceptions,
Datadog::Contrib::Rails::ExceptionMiddleware
)
end
end
end

# Add a callback hook to finish configuring the tracer after the application is initialized.
# We need to wait for some things, like application name, middleware stack, etc.
do_once(:rails_after_initialize_hook) do
::ActiveSupport.on_load(:after_initialize) do
Datadog::Contrib::Rails::Framework.setup

# Add instrumentation to Rails components
Datadog::Contrib::Rails::ActionController.instrument
Datadog::Contrib::Rails::ActionView.instrument
Datadog::Contrib::Rails::ActiveSupport.instrument
end
end

@patched = true
rescue => e
Datadog::Tracer.log.error("Unable to apply Rails integration: #{e}")
Expand All @@ -49,5 +87,3 @@ def compatible?
end
end
end

require 'ddtrace/contrib/rails/railtie' if Datadog.registry[:rails].compatible?
13 changes: 8 additions & 5 deletions lib/ddtrace/contrib/rails/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
module Datadog
# Railtie class initializes
class Railtie < Rails::Railtie
config.app_middleware.insert_before(0, Datadog::Contrib::Rack::TraceMiddleware)
# Insert right after Rails exception handling middleware, because if it's before,
# it catches and swallows the error. If it's too far after, custom middleware can find itself
# between, and raise exceptions that don't end up getting tagged on the request properly (e.g lost stack trace.)
config.app_middleware.insert_after(ActionDispatch::ShowExceptions, Datadog::Contrib::Rails::ExceptionMiddleware)
# Add the trace middleware to the application stack
initializer 'datadog.add_middleware' do |app|
app.middleware.insert_before(0, Datadog::Contrib::Rack::TraceMiddleware)
# Insert right after Rails exception handling middleware, because if it's before,
# it catches and swallows the error. If it's too far after, custom middleware can find itself
# between, and raise exceptions that don't end up getting tagged on the request properly (e.g lost stack trace.)
app.middleware.insert_after(ActionDispatch::ShowExceptions, Datadog::Contrib::Rails::ExceptionMiddleware)
end

config.after_initialize do
Datadog::Contrib::Rails::Framework.setup
Expand Down
40 changes: 40 additions & 0 deletions lib/ddtrace/opentracer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module Datadog
# Namespace for ddtrace OpenTracing implementation
module OpenTracer
module_function

def supported?
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.1')
end

def load_opentracer
require 'opentracing'
require 'opentracing/carrier'
require 'ddtrace'
require 'ddtrace/opentracer/carrier'
require 'ddtrace/opentracer/tracer'
require 'ddtrace/opentracer/span'
require 'ddtrace/opentracer/span_context'
require 'ddtrace/opentracer/span_context_factory'
require 'ddtrace/opentracer/scope'
require 'ddtrace/opentracer/scope_manager'
require 'ddtrace/opentracer/thread_local_scope'
require 'ddtrace/opentracer/thread_local_scope_manager'
require 'ddtrace/opentracer/distributed_headers'
require 'ddtrace/opentracer/propagator'
require 'ddtrace/opentracer/text_map_propagator'
require 'ddtrace/opentracer/binary_propagator'
require 'ddtrace/opentracer/rack_propagator'
require 'ddtrace/opentracer/global_tracer'

# Modify the OpenTracing module functions
OpenTracing.module_eval do
class << self
prepend Datadog::OpenTracer::GlobalTracer
end
end
end

load_opentracer if supported?
end
end
24 changes: 24 additions & 0 deletions lib/ddtrace/opentracer/binary_propagator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module Datadog
module OpenTracer
# OpenTracing propagator for Datadog::OpenTracer::Tracer
module BinaryPropagator
extend Propagator

# Inject a SpanContext into the given carrier
#
# @param span_context [SpanContext]
# @param carrier [Carrier] A carrier object of Binary type
def self.inject(span_context, carrier)
nil
end

# Extract a SpanContext in Binary format from the given carrier.
#
# @param carrier [Carrier] A carrier object of Binary type
# @return [SpanContext, nil] the extracted SpanContext or nil if none could be found
def self.extract(carrier)
SpanContext::NOOP_INSTANCE
end
end
end
end
6 changes: 6 additions & 0 deletions lib/ddtrace/opentracer/carrier.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Datadog
module OpenTracer
class Carrier < ::OpenTracing::Carrier
end
end
end
Loading

0 comments on commit edd3d55

Please sign in to comment.