Skip to content

Commit

Permalink
zipkin-tracer gem
Browse files Browse the repository at this point in the history
Add tracing to a Rack application

- In config.ru: `use ZipkinTracer::RackHandler`
- Configurable in Rails configs

Author: franklinhu
Pull Request: #13
URL: #13
  • Loading branch information
Franklin Hu committed Jun 12, 2012
1 parent de8b7fc commit b4f2198
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 40 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,17 @@ The UI is a standard Rails 3 app.
bundle exec rails server.
```

#### zipkin-tracer gem
The `zipkin-tracer` gem adds tracing to a Rails application through the use of a Rack Handler.
In `config.ru`:

```
use ZipkinTracer::RackHandler
run <YOUR_APPLICATION>
```

If the application's static assets are served through Rails, those requests will be traced.

## Running a Hadoop job
It's possible to setup Scribe to log into Hadoop. If you do this you can generate various reports from the data
that is not easy to do on the fly in Zipkin itself.
Expand Down
19 changes: 19 additions & 0 deletions zipkin-gems/zipkin-tracer/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2012 Twitter Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'rubygems'

desc 'Build the gem'
task :build do
system "gem build zipkin-tracer.gemspec"
end
79 changes: 79 additions & 0 deletions zipkin-gems/zipkin-tracer/lib/zipkin-tracer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Copyright 2012 Twitter Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'finagle-thrift'
require 'finagle-thrift/trace'
require 'scribe'

require 'zipkin-tracer/careless_scribe'

module ZipkinTracer extend self

class RackHandler
def initialize(app)
@app = app
@lock = Mutex.new

config = app.config.zipkin_tracer
@service_name = config[:service_name]
@service_port = config[:service_port]

scribe =
if config[:scribe_server] then
Scribe.new(config[:scribe_server])
else
Scribe.new()
end

scribe_max_buffer =
if config[:scribe_max_buffer] then
config[:scribe_max_buffer]
else
10
end

@sample_rate =
if config[:sample_rate] then
config[:sample_rate]
else
0.1
end

::Trace.tracer = ::Trace::ZipkinTracer.new(CarelessScribe.new(scribe), scribe_max_buffer)
end

def call(env)
id = ::Trace::TraceId.new(::Trace.generate_id, nil, ::Trace.generate_id, true)
::Trace.default_endpoint = ::Trace.default_endpoint.with_service_name(@service_name).with_port(@service_port)
::Trace.sample_rate=(@sample_rate)
tracing_filter(id, env) { @app.call(env) }
end

private
def tracing_filter(trace_id, env)
@lock.synchronize do
::Trace.push(trace_id)
::Trace.set_rpc_name(env["REQUEST_METHOD"]) # get/post and all that jazz
::Trace.record(::Trace::BinaryAnnotation.new("http.uri", env["PATH_INFO"], "STRING", ::Trace.default_endpoint))
::Trace.record(::Trace::Annotation.new(::Trace::Annotation::SERVER_RECV, ::Trace.default_endpoint))
end
yield if block_given?
ensure
@lock.synchronize do
::Trace.record(::Trace::Annotation.new(::Trace::Annotation::SERVER_SEND, ::Trace.default_endpoint))
::Trace.pop
end
end
end

end
File renamed without changes.
17 changes: 17 additions & 0 deletions zipkin-gems/zipkin-tracer/lib/zipkin-tracer/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2012 Twitter Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module ZipkinTracer
VERSION = "0.0.1"
end

36 changes: 36 additions & 0 deletions zipkin-gems/zipkin-tracer/zipkin-tracer.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- encoding: utf-8 -*-
# Copyright 2012 Twitter Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
lib = File.expand_path('../lib/', __FILE__)
$:.unshift lib unless $:.include?(lib)

require 'zipkin-tracer/version'

Gem::Specification.new do |s|
s.name = "zipkin-tracer"
s.version = ZipkinTracer::VERSION
s.authors = ["Franklin Hu"]
s.email = ["[email protected]"]
s.homepage = "https://github.com/twitter/zipkin"
s.summary = "Ruby tracing via Zipkin"
s.description = "Adds tracing instrumentation for ruby applications"

s.required_rubygems_version = ">= 1.3.5"

s.files = Dir.glob("{bin,lib}/**/*")
s.require_path = 'lib'

s.add_dependency "finagle-thrift", "~> 1.2.0"
s.add_dependency "scribe", "~> 0.2.4"
end
1 change: 1 addition & 0 deletions zipkin-web/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ gem 'thrift_client', "0.6.3"
gem 'zookeeper', "1.2.4"
gem 'finagle-thrift', '1.2.0'
gem 'scribe', '0.2.4'
gem 'zipkin-tracer', '0.0.1'

4 changes: 4 additions & 0 deletions zipkin-web/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ GEM
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.33)
zipkin-tracer (0.0.1)
finagle-thrift (~> 1.2.0)
scribe (~> 0.2.4)
zookeeper (1.2.4)
backports (~> 2.5.1)
logging (~> 1.7.2)
Expand All @@ -101,4 +104,5 @@ DEPENDENCIES
scribe (= 0.2.4)
thrift (= 0.6.0)
thrift_client (= 0.6.3)
zipkin-tracer (= 0.0.1)
zookeeper (= 1.2.4)
8 changes: 4 additions & 4 deletions zipkin-web/config.ru
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Copyright 2012 Twitter Inc.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand All @@ -15,5 +15,5 @@
# This file is used by Rack-based servers to start the application.

require ::File.expand_path('../config/environment', __FILE__)
use ZipkinRackHandler
use ZipkinTracer::RackHandler
run Zipkin::Application
45 changes: 9 additions & 36 deletions zipkin-web/config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
require "action_mailer/railtie"
require "active_resource/railtie"
require "rails/test_unit/railtie"
require 'lib/careless_scribe'
require 'sprockets/railtie'

# If you have a Gemfile, require the gems listed there, including any gems
Expand Down Expand Up @@ -88,43 +87,17 @@ class Application < Rails::Application
# :skip_zookeeper => true
#}

end
end
config.zipkin_tracer = {
# Scribe settings that can be overwritten
#:scribe_server => "HOST:PORT",
#:scribe_max_buff => 10

class ZipkinRackHandler
def initialize(app)
@app = app
@lock = Mutex.new
Trace.tracer = Trace::ZipkinTracer.new(CarelessScribe.new(Scribe.new()), 10)
end
# Required settings
:service_name => "ZipkinUI",
:service_port => 80,

def call(env)
# TODO HERE BE HACK. Chad made me do it!
# this is due to our setup where statics are served through the ruby app, but we don't want to trace that.
rp = env["REQUEST_PATH"]
if !rp.blank? && (rp.starts_with?("/stylesheets") || rp.starts_with?("/javascripts") || rp.starts_with?("/images"))
return @app.call(env)
end

id = Trace::TraceId.new(Trace.generate_id, nil, Trace.generate_id, true)
Trace.default_endpoint = Trace.default_endpoint.with_service_name("zipkinui").with_port(0) #TODO any way to get the port?
Trace.sample_rate=(1)
tracing_filter(id, env) { @app.call(env) }
end
:sample_rate => 1
}

private
def tracing_filter(trace_id, env)
@lock.synchronize do
Trace.push(trace_id)
Trace.set_rpc_name(env["REQUEST_METHOD"]) # get/post and all that jazz
Trace.record(Trace::BinaryAnnotation.new("http.uri", env["PATH_INFO"], "STRING", Trace.default_endpoint))
Trace.record(Trace::Annotation.new(Trace::Annotation::SERVER_RECV, Trace.default_endpoint))
end
yield if block_given?
ensure
@lock.synchronize do
Trace.record(Trace::Annotation.new(Trace::Annotation::SERVER_SEND, Trace.default_endpoint))
Trace.pop
end
end
end

0 comments on commit b4f2198

Please sign in to comment.