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

Add Rack instrumentation #166

Merged
merged 75 commits into from
Mar 5, 2020
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
508b8df
rack: Add Gemfile, gemspec, version
duonoid Jan 6, 2020
367c78c
Add Rakefile
duonoid Jan 6, 2020
6f5c5e1
tests: Add test_helper
duonoid Jan 6, 2020
3ed377c
Add example: trace_demonstration
duonoid Jan 6, 2020
acb435c
Add QueueTime
duonoid Jan 13, 2020
384e331
Add TracerMiddleware
duonoid Dec 18, 2019
6a6fd0a
Add Adapters::Rack::Adapter
duonoid Jan 6, 2020
16e8d32
Add Adapters::Rack
duonoid Jan 6, 2020
4da0f61
Update to 2020 copyright
duonoid Jan 21, 2020
b62e0fa
Initialize 'now' later
duonoid Jan 21, 2020
59b5791
Merge branch 'master' into rack-instrumentation--67
duonoid Jan 22, 2020
5e2be00
Adapt to Instrumentation Auto Installer interface
duonoid Jan 22, 2020
423397a
Fix example to use updated Instrumentation Auto Installer
duonoid Jan 22, 2020
0be8aff
Handle errors by setting span.status, leave a TODO and rescue clause
duonoid Jan 23, 2020
14b1198
Allow config[:quantization]
duonoid Jan 23, 2020
9f0e2d8
Remove optional parent context extraction
duonoid Jan 23, 2020
fb1bf71
Resolve 'http.base_url' TODO
duonoid Jan 23, 2020
ea061d3
Resolve 'resource name' TODO
duonoid Jan 23, 2020
242b403
Resolve 'http.route' TODO
duonoid Jan 23, 2020
c3b9319
Note: missing 'span.set_error()' for now
duonoid Jan 23, 2020
b110cf1
Resolve FrontendSpan TODOs
duonoid Jan 23, 2020
4cdca21
Optimize allowed_request_headers
duonoid Jan 24, 2020
ba86941
Optimize allowed_response_headers()
duonoid Jan 24, 2020
e328a7c
Optimize return of EMPTY_HASH frozen constant
duonoid Jan 24, 2020
6544839
Refactor to avoid using dup._call(env)
duonoid Jan 24, 2020
5604391
Merge branch 'master' into rack-instrumentation--67
duonoid Jan 25, 2020
efad4af
Merge branch 'master' into rack-instrumentation--67
duonoid Jan 28, 2020
22b69cd
Add Appraisals, integrate into circleci
duonoid Jan 28, 2020
44ddb04
Integrate rubocop, fix violations, add adapters to top-level rake task
duonoid Jan 28, 2020
197ade6
Update example to use new config
duonoid Jan 28, 2020
87e74b8
Rewrite examples
duonoid Jan 31, 2020
de91025
Automatically patch Rack::Builder
duonoid Feb 1, 2020
e9c021b
Port ddtrace Quantization::HTTP
duonoid Feb 3, 2020
99f44e8
Integrate Util::Quantization
duonoid Feb 3, 2020
33fe594
Revert "Automatically patch Rack::Builder"
duonoid Feb 4, 2020
1ce1bf5
Add missing files needed for Bundler.require
duonoid Feb 5, 2020
8a34ab2
Update Rakefile
duonoid Feb 5, 2020
6344642
Avoid patching config[:application] during installation
duonoid Feb 5, 2020
de81be2
Refine/optimize allowed_request_headers
duonoid Feb 5, 2020
5479ad0
Refine/optimize allowed_response_headers
duonoid Feb 5, 2020
edb95f9
Avoid circular require
duonoid Feb 6, 2020
1399250
Use SDK.configure to streamline test_helper.rb setup
duonoid Feb 6, 2020
78acca7
Revert "Integrate Util::Quantization"
duonoid Feb 6, 2020
a69f94e
Revert "Port ddtrace Quantization::HTTP"
duonoid Feb 6, 2020
70aa352
Fix example/trace_demonstration2.rb to integrate explicitly, with 'use'
duonoid Feb 11, 2020
457e695
Update example/trace_demonstration2.rb documentation
duonoid Feb 11, 2020
f78c90e
Optimize allowed_response_headers to avoid using Hash#detect
duonoid Feb 11, 2020
c1a3a6e
Simplify allowed_{rack,request}_header_names to inline config
duonoid Feb 11, 2020
7d5fc8b
Optimize to return EMPTY_HASH if allowed_{response,rack_request}_head…
duonoid Feb 11, 2020
b447d74
Merge branch 'master' into rack-instrumentation--67
duonoid Feb 11, 2020
dcb150f
Adjust to context prop changes
duonoid Feb 11, 2020
845aaa6
Remove unused variables
duonoid Feb 11, 2020
f565ad3
Use kind: :server for both frontend and request span
duonoid Feb 11, 2020
7b08085
Make request_span parented by frontend_span
duonoid Feb 12, 2020
8e0e1b4
Implement using helpers to that in_span doesn't have to record and re…
duonoid Feb 12, 2020
dabdf02
Cleanup some URL wrapper methods
duonoid Feb 13, 2020
1317d35
Optimize: return without assigning local variable
duonoid Feb 13, 2020
caeb3bd
Just use http.{scheme,host,target} (remove url, base_url)
duonoid Feb 13, 2020
3659ead
Inline Rack::Request#fullpath
duonoid Feb 13, 2020
af52bd7
Merge remote-tracking branch 'upstream/master' into rack-instrumentat…
duonoid Feb 18, 2020
2c68392
Fix .circleci/config.yml after conflict
duonoid Feb 18, 2020
c1a1c2d
Merge remote-tracking branch 'upstream/master' into rack-instrumentat…
duonoid Feb 19, 2020
fb3a242
Adjust error handling according to #184
duonoid Feb 19, 2020
e763e21
Rewrite to utilize in_span
duonoid Feb 22, 2020
e5d15c6
Reduce comments that were more useful in development/review
duonoid Feb 22, 2020
313f576
Merge branch 'master' into rack-instrumentation--67
duonoid Feb 24, 2020
12b6b58
Update http.host to use HTTP_HOST or 'unknown'
duonoid Feb 25, 2020
bb3b9c2
Update request_start_time to be number, not timestamp
duonoid Feb 25, 2020
bcf940f
Remove request_span comment
duonoid Feb 25, 2020
cc14c64
Remove 'service' attribute when creating frontend span
duonoid Feb 25, 2020
16079fa
Merge branch 'master' into rack-instrumentation--67
duonoid Feb 25, 2020
80b2c2d
Change frontend_span to 'http_server.proxy', make request_span :internal
duonoid Feb 28, 2020
85bf829
Merge branch 'master' into rack-instrumentation--67
duonoid Feb 28, 2020
37c9f55
Merge remote-tracking branch 'upstream/master' into rack-instrumentat…
duonoid Feb 28, 2020
d3443e3
Merge remote-tracking branch 'upstream/master' into rack-instrumentat…
duonoid Feb 28, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions adapters/rack/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

# Copyright 2019 OpenTelemetry Authors
duonoid marked this conversation as resolved.
Show resolved Hide resolved
#
# SPDX-License-Identifier: Apache-2.0

source 'https://rubygems.org'

gemspec

gem 'opentelemetry-api', path: '../../api'

group :test do
gem 'opentelemetry-sdk', path: '../../sdk'
end
14 changes: 14 additions & 0 deletions adapters/rack/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

# Copyright 2019 OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require 'bundler/gem_tasks'
require 'rake/testtask'

Rake::TestTask.new :test do |t|
t.libs << 'test'
t.libs << 'lib'
t.test_files = FileList['test/**/*_test.rb']
end
8 changes: 8 additions & 0 deletions adapters/rack/example/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'rack'
gem 'rack-test'
gem 'opentelemetry-api', path: '../../../api'
gem 'opentelemetry-sdk', path: '../../../sdk'
38 changes: 38 additions & 0 deletions adapters/rack/example/trace_demonstration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'rubygems'
require 'bundler/setup'

require 'opentelemetry/sdk'

require 'rack'
require_relative '../lib/opentelemetry/adapters/rack'

# Set preferred tracer implementation:
SDK = OpenTelemetry::SDK

# global initialization:
factory = OpenTelemetry.tracer_factory = SDK::Trace::TracerFactory.new
factory.add_span_processor(
SDK::Trace::Export::SimpleSpanProcessor.new(
SDK::Trace::Export::ConsoleSpanExporter.new
)
)

# setup fake rack application:
builder = Rack::Builder.new do
# can't use TracerMiddleware constant before calling Adapters::Rack.install:
#use OpenTelemetry::Adapters::Rack::Middlewares::TracerMiddleware
end
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['All responses are OK']] }
builder.run app

# demonstrate rack configuration options:
config = {}
config[:retain_middleware_names] = true
config[:application] = builder
config[:record_frontend_span] = true
OpenTelemetry::Adapters::Rack.install(config)

# integrate/activate tracing middleware:
builder.use OpenTelemetry::Adapters::Rack::Middlewares::TracerMiddleware

puts Rack::MockRequest.new(builder).get('/')
30 changes: 30 additions & 0 deletions adapters/rack/lib/opentelemetry/adapters/rack.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

# Copyright 2020 OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

module OpenTelemetry
module Adapters
module Rack
module_function

def install(config = {})
require_relative 'rack/adapter'
Rack::Adapter.install(config)
end

# Convenience method to access the nested module name
def name
Module.nesting[0].to_s
end

# Convenience method to access the adapter version
def version
VERSION
end
end
end
end

require_relative './rack/version'
77 changes: 77 additions & 0 deletions adapters/rack/lib/opentelemetry/adapters/rack/adapter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# frozen_string_literal: true

# Copyright 2020 OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

module OpenTelemetry
module Adapters
module Rack
class Adapter
class << self
attr_reader :config,
:propagator

def install(config = {})
@config = config
@propagator = OpenTelemetry.tracer_factory.http_text_format

new.install
end

def tracer
@tracer ||= OpenTelemetry::tracer_factory.tracer(
Rack.name,
Rack.version
)
end

attr_accessor :installed
alias_method :installed?, :installed
end

def install
return :already_installed if self.class.installed?

require_relative 'middlewares/tracer_middleware'

retain_middleware_names if config[:retain_middleware_names]

self.class.installed = true
end

private

MissingApplicationError = Class.new(StandardError)

def config
self.class.config
end

# intercept all middleware-compatible calls, retain class name
def retain_middleware_names
next_middleware = config[:application]
raise MissingApplicationError unless next_middleware

while next_middleware
if next_middleware.respond_to?(:call)
next_middleware.singleton_class.class_eval do
alias_method :__call, :call

def call(env)
env['RESPONSE_MIDDLEWARE'] = self.class.to_s
__call(env)
end
end
end

next_middleware = next_middleware.instance_variable_defined?('@app') &&
next_middleware.instance_variable_get('@app')
end
end
end
end
end
end

require_relative '../rack'
Loading