Skip to content

Commit edd3d55

Browse files
authored
Merge pull request #553 from DataDog/0.16-dev
0.16.0 to stable
2 parents 22f9943 + 3718e64 commit edd3d55

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2741
-47
lines changed

CHANGELOG.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@
44

55
## [Unreleased (beta)]
66

7+
## [0.16.0] - 2018-09-18
8+
9+
Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.16.0
10+
11+
Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.15.0...v0.16.0
12+
13+
### Added
14+
15+
- OpenTracing support (#517)
16+
- `middleware` option for disabling Rails trace middleware. (#552)
17+
718
## [0.15.0] - 2018-09-12
819

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

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

503-
[Unreleased (stable)]: https://github.com/DataDog/dd-trace-rb/compare/v0.15.0...master
504-
[Unreleased (beta)]: https://github.com/DataDog/dd-trace-rb/compare/v0.15.0...0.16-dev
514+
[Unreleased (stable)]: https://github.com/DataDog/dd-trace-rb/compare/v0.16.0...master
515+
[Unreleased (beta)]: https://github.com/DataDog/dd-trace-rb/compare/v0.16.0...0.17-dev
516+
[0.15.0]: https://github.com/DataDog/dd-trace-rb/compare/v0.15.0...v0.16.0
505517
[0.15.0]: https://github.com/DataDog/dd-trace-rb/compare/v0.14.2...v0.15.0
506518
[0.14.2]: https://github.com/DataDog/dd-trace-rb/compare/v0.14.1...v0.14.2
507519
[0.14.1]: https://github.com/DataDog/dd-trace-rb/compare/v0.14.0...v0.14.1

Rakefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ namespace :spec do
1515

1616
RSpec::Core::RakeTask.new(:main) do |t|
1717
t.pattern = 'spec/**/*_spec.rb'
18-
t.exclude_pattern = 'spec/**/{contrib,benchmark,redis}/**/*_spec.rb'
18+
t.exclude_pattern = 'spec/**/{contrib,benchmark,redis,opentracer}/**/*_spec.rb'
19+
end
20+
21+
RSpec::Core::RakeTask.new(:opentracer) do |t|
22+
t.pattern = 'spec/ddtrace/opentracer/**/*_spec.rb'
1923
end
2024

2125
RSpec::Core::RakeTask.new(:rails) do |t|
@@ -311,6 +315,7 @@ task :ci do
311315
sh 'bundle exec rake test:main'
312316
sh 'bundle exec rake spec:main'
313317
sh 'bundle exec rake spec:contrib'
318+
sh 'bundle exec rake spec:opentracer'
314319

315320
if RUBY_PLATFORM != 'java'
316321
# Contrib minitests
@@ -366,6 +371,7 @@ task :ci do
366371
sh 'bundle exec rake test:main'
367372
sh 'bundle exec rake spec:main'
368373
sh 'bundle exec rake spec:contrib'
374+
sh 'bundle exec rake spec:opentracer'
369375

370376
if RUBY_PLATFORM != 'java'
371377
# Contrib minitests
@@ -432,6 +438,7 @@ task :ci do
432438
sh 'bundle exec rake test:main'
433439
sh 'bundle exec rake spec:main'
434440
sh 'bundle exec rake spec:contrib'
441+
sh 'bundle exec rake spec:opentracer'
435442

436443
if RUBY_PLATFORM != 'java'
437444
# Contrib minitests
@@ -497,6 +504,7 @@ task :ci do
497504
sh 'bundle exec rake test:main'
498505
sh 'bundle exec rake spec:main'
499506
sh 'bundle exec rake spec:contrib'
507+
sh 'bundle exec rake spec:opentracer'
500508

501509
if RUBY_PLATFORM != 'java'
502510
# Contrib minitests

ddtrace.gemspec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ Gem::Specification.new do |spec|
3333
spec.require_paths = ['lib']
3434

3535
spec.add_dependency 'msgpack'
36+
# TODO: Move this to Appraisals?
37+
spec.add_dependency 'opentracing', '>= 0.4.1'
3638

3739
spec.add_development_dependency 'rake', '>= 10.5'
3840
spec.add_development_dependency 'rubocop', '= 0.49.1' if RUBY_VERSION >= '2.1.0'

docs/GettingStarted.md

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ For descriptions of terminology used in APM, take a look at the [official docume
2121
- [Installation](#installation)
2222
- [Quickstart for Rails applications](#quickstart-for-rails-applications)
2323
- [Quickstart for Ruby applications](#quickstart-for-ruby-applications)
24+
- [Quickstart for OpenTracing](#quickstart-for-opentracing)
2425
- [Manual instrumentation](#manual-instrumentation)
2526
- [Integration instrumentation](#integration-instrumentation)
2627
- [Active Record](#active-record)
@@ -59,6 +60,7 @@ For descriptions of terminology used in APM, take a look at the [official docume
5960
- [Processing pipeline](#processing-pipeline)
6061
- [Filtering](#filtering)
6162
- [Processing](#processing)
63+
- [OpenTracing](#opentracing)
6264

6365
## Compatibility
6466

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

78-
*Full* support indicates all tracer features are available.
79-
80-
*Experimental* indicates most features should be available, but unverified.
81-
8280
**Supported web servers**:
8381

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

88+
**Supported tracing frameworks**:
89+
90+
| Type | Documentation | Version | Support type |
91+
| ----------- | ----------------------------------------------- | --------------------- | ------------ |
92+
| OpenTracing | https://github.com/opentracing/opentracing-ruby | 0.4.1+ (w/ Ruby 2.1+) | Experimental |
93+
94+
*Full* support indicates all tracer features are available.
95+
96+
*Experimental* indicates most features should be available, but unverified.
97+
9098
## Installation
9199

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

147+
### Quickstart for OpenTracing
148+
149+
1. Install the gem with `gem install ddtrace`
150+
2. To your OpenTracing configuration file, add the following:
151+
152+
```ruby
153+
require 'opentracing'
154+
require 'ddtrace'
155+
require 'ddtrace/opentracer'
156+
157+
# Activate the Datadog tracer for OpenTracing
158+
OpenTracing.global_tracer = Datadog::OpenTracer::Tracer.new
159+
```
160+
161+
3. (Optional) Add a configuration block to your Ruby application to configure Datadog with:
162+
163+
```ruby
164+
Datadog.configure do |c|
165+
# Configure the Datadog tracer here.
166+
# Activate integrations, change tracer settings, etc...
167+
# By default without additional configuration,
168+
# no additional integrations will be traced, only
169+
# what you have instrumented with OpenTracing.
170+
end
171+
```
172+
173+
4. (Optional) Add or activate additional instrumentation by doing either of the following:
174+
1. Activate Datadog integration instrumentation (see [Integration instrumentation](#integration-instrumentation))
175+
2. Add Datadog manual instrumentation around your code (see [Manual instrumentation](#manual-instrumentation))
176+
139177
### Final steps for installation
140178

141179
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].
@@ -869,6 +907,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
869907
| ``database_service`` | Database service name used when tracing database activity | ``<app_name>-<adapter_name>`` |
870908
| ``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`` |
871909
| ``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` |
910+
| ``middleware`` | Add the trace middleware to the Rails application. Set to `false` if you don't want the middleware to load. | `true` |
872911
| ``middleware_names`` | Enables any short-circuited middleware requests to display the middleware name as resource for the trace. | `false` |
873912
| ``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/`` |
874913
| ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
@@ -1510,3 +1549,32 @@ Datadog::Pipeline.before_flush(
15101549
Datadog::Pipeline::SpanProcessor.new { |span| span.resource.gsub!(/password=.*/, '') }
15111550
)
15121551
```
1552+
1553+
### OpenTracing
1554+
1555+
For setting up Datadog with OpenTracing, see out [Quickstart for OpenTracing](#quickstart-for-opentracing) section for details.
1556+
1557+
**Configuring Datadog tracer settings**
1558+
1559+
The underlying Datadog tracer can be configured by passing options (which match `Datadog::Tracer`) when configuring the global tracer:
1560+
1561+
```ruby
1562+
# Where `options` is a Hash of options provided to Datadog::Tracer
1563+
OpenTracing.global_tracer = Datadog::OpenTracer::Tracer.new(options)
1564+
```
1565+
1566+
It can also be configured by using `Datadog.configure` described in the [Tracer settings](#tracer-settings) section.
1567+
1568+
**Activating and configuring integrations**
1569+
1570+
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.
1571+
1572+
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.
1573+
1574+
**Supported serialization formats**
1575+
1576+
| Type | Supported? | Additional information |
1577+
| ------------------------------ | ---------- | ---------------------- |
1578+
| `OpenTracing::FORMAT_TEXT_MAP` | Yes | |
1579+
| `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. |
1580+
| `OpenTracing::FORMAT_BINARY` | No | |

lib/ddtrace/contrib/rack/patcher.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ def patch
3939
@patched = true
4040
end
4141

42-
if !@middleware_patched && get_option(:middleware_names)
42+
if (!instance_variable_defined?(:@middleware_patched) || !@middleware_patched) \
43+
&& get_option(:middleware_names)
4344
if get_option(:application)
4445
enable_middleware_names
4546
@middleware_patched = true

lib/ddtrace/contrib/rails/patcher.rb

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
require 'ddtrace/contrib/rails/utils'
2+
require 'ddtrace/contrib/rails/framework'
3+
require 'ddtrace/contrib/rails/middlewares'
4+
require 'ddtrace/contrib/rack/middlewares'
25

36
module Datadog
47
module Contrib
@@ -17,6 +20,7 @@ module Patcher
1720
Datadog.configuration[:active_record][:service_name] = value
1821
end
1922
end
23+
option :middleware, default: true
2024
option :middleware_names, default: false
2125
option :distributed_tracing, default: false
2226
option :template_base_path, default: 'views/'
@@ -28,7 +32,41 @@ module Patcher
2832
class << self
2933
def patch
3034
return @patched if patched? || !compatible?
31-
require_relative 'framework'
35+
36+
# Add a callback hook to add the trace middleware before the application initializes.
37+
# Otherwise the middleware stack will be frozen.
38+
do_once(:rails_before_initialize_hook) do
39+
::ActiveSupport.on_load(:before_initialize) do
40+
# Sometimes we don't want to activate middleware e.g. OpenTracing, etc.
41+
if Datadog.configuration[:rails][:middleware]
42+
# Add trace middleware
43+
config.middleware.insert_before(0, Datadog::Contrib::Rack::TraceMiddleware)
44+
45+
# Insert right after Rails exception handling middleware, because if it's before,
46+
# it catches and swallows the error. If it's too far after, custom middleware can find itself
47+
# between, and raise exceptions that don't end up getting tagged on the request properly.
48+
# e.g lost stack trace.
49+
config.middleware.insert_after(
50+
ActionDispatch::ShowExceptions,
51+
Datadog::Contrib::Rails::ExceptionMiddleware
52+
)
53+
end
54+
end
55+
end
56+
57+
# Add a callback hook to finish configuring the tracer after the application is initialized.
58+
# We need to wait for some things, like application name, middleware stack, etc.
59+
do_once(:rails_after_initialize_hook) do
60+
::ActiveSupport.on_load(:after_initialize) do
61+
Datadog::Contrib::Rails::Framework.setup
62+
63+
# Add instrumentation to Rails components
64+
Datadog::Contrib::Rails::ActionController.instrument
65+
Datadog::Contrib::Rails::ActionView.instrument
66+
Datadog::Contrib::Rails::ActiveSupport.instrument
67+
end
68+
end
69+
3270
@patched = true
3371
rescue => e
3472
Datadog::Tracer.log.error("Unable to apply Rails integration: #{e}")
@@ -49,5 +87,3 @@ def compatible?
4987
end
5088
end
5189
end
52-
53-
require 'ddtrace/contrib/rails/railtie' if Datadog.registry[:rails].compatible?

lib/ddtrace/contrib/rails/railtie.rb

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
module Datadog
66
# Railtie class initializes
77
class Railtie < Rails::Railtie
8-
config.app_middleware.insert_before(0, Datadog::Contrib::Rack::TraceMiddleware)
9-
# Insert right after Rails exception handling middleware, because if it's before,
10-
# it catches and swallows the error. If it's too far after, custom middleware can find itself
11-
# between, and raise exceptions that don't end up getting tagged on the request properly (e.g lost stack trace.)
12-
config.app_middleware.insert_after(ActionDispatch::ShowExceptions, Datadog::Contrib::Rails::ExceptionMiddleware)
8+
# Add the trace middleware to the application stack
9+
initializer 'datadog.add_middleware' do |app|
10+
app.middleware.insert_before(0, Datadog::Contrib::Rack::TraceMiddleware)
11+
# Insert right after Rails exception handling middleware, because if it's before,
12+
# it catches and swallows the error. If it's too far after, custom middleware can find itself
13+
# between, and raise exceptions that don't end up getting tagged on the request properly (e.g lost stack trace.)
14+
app.middleware.insert_after(ActionDispatch::ShowExceptions, Datadog::Contrib::Rails::ExceptionMiddleware)
15+
end
1316

1417
config.after_initialize do
1518
Datadog::Contrib::Rails::Framework.setup

lib/ddtrace/opentracer.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
module Datadog
2+
# Namespace for ddtrace OpenTracing implementation
3+
module OpenTracer
4+
module_function
5+
6+
def supported?
7+
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.1')
8+
end
9+
10+
def load_opentracer
11+
require 'opentracing'
12+
require 'opentracing/carrier'
13+
require 'ddtrace'
14+
require 'ddtrace/opentracer/carrier'
15+
require 'ddtrace/opentracer/tracer'
16+
require 'ddtrace/opentracer/span'
17+
require 'ddtrace/opentracer/span_context'
18+
require 'ddtrace/opentracer/span_context_factory'
19+
require 'ddtrace/opentracer/scope'
20+
require 'ddtrace/opentracer/scope_manager'
21+
require 'ddtrace/opentracer/thread_local_scope'
22+
require 'ddtrace/opentracer/thread_local_scope_manager'
23+
require 'ddtrace/opentracer/distributed_headers'
24+
require 'ddtrace/opentracer/propagator'
25+
require 'ddtrace/opentracer/text_map_propagator'
26+
require 'ddtrace/opentracer/binary_propagator'
27+
require 'ddtrace/opentracer/rack_propagator'
28+
require 'ddtrace/opentracer/global_tracer'
29+
30+
# Modify the OpenTracing module functions
31+
OpenTracing.module_eval do
32+
class << self
33+
prepend Datadog::OpenTracer::GlobalTracer
34+
end
35+
end
36+
end
37+
38+
load_opentracer if supported?
39+
end
40+
end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module Datadog
2+
module OpenTracer
3+
# OpenTracing propagator for Datadog::OpenTracer::Tracer
4+
module BinaryPropagator
5+
extend Propagator
6+
7+
# Inject a SpanContext into the given carrier
8+
#
9+
# @param span_context [SpanContext]
10+
# @param carrier [Carrier] A carrier object of Binary type
11+
def self.inject(span_context, carrier)
12+
nil
13+
end
14+
15+
# Extract a SpanContext in Binary format from the given carrier.
16+
#
17+
# @param carrier [Carrier] A carrier object of Binary type
18+
# @return [SpanContext, nil] the extracted SpanContext or nil if none could be found
19+
def self.extract(carrier)
20+
SpanContext::NOOP_INSTANCE
21+
end
22+
end
23+
end
24+
end

lib/ddtrace/opentracer/carrier.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module Datadog
2+
module OpenTracer
3+
class Carrier < ::OpenTracing::Carrier
4+
end
5+
end
6+
end

0 commit comments

Comments
 (0)