README.md in oboe-2.5.0.7 vs README.md in oboe-2.6.0.2
- old
+ new
@@ -15,40 +15,48 @@
# Installation
The oboe gem is [available on Rubygems](https://rubygems.org/gems/oboe) and can be installed with:
- gem install oboe
+```bash
+gem install oboe
+```
or added to your bundle Gemfile and running `bundle install`:
- gem 'oboe'
+```ruby
+gem 'oboe'
+```
# Running
## Rails
No special steps are needed to instrument Ruby on Rails. Once part of the bundle, the oboe gem will automatically detect Rails and instrument on stack initialization.
-_Note: You will still need to decide on your `tracing_mode` depending on whether you are running with an instrumented Apache or nginx in front of your Rails stack. See below for more details._
+*Note: You will still need to decide on your `tracing_mode` depending on whether you are running with an instrumented Apache or nginx in front of your Rails stack. See below for more details.*
### The Install Generator
The oboe gem provides a Rails generator used to seed an oboe initializer where you can configure and control `tracing_mode`, `sample_rate` and [other options](https://support.tv.appneta.com/support/solutions/articles/86392-configuring-the-ruby-instrumentation).
To run the install generator run:
- bundle exec rails generate oboe:install
+```bash
+bundle exec rails generate oboe:install
+```
After the prompts, this will create an initializer: `config/initializers/oboe.rb`.
-## Sinatra/Padrino
+## Sinatra
-You can instrument your Sinatra or Padrino application by adding the following code to your `config.ru` Rackup file (Padrino example).
+You can instrument your Sinatra application by adding the following code to your `config.ru` Rackup file:
+```ruby
+ # If you're not using Bundler.require. Make sure this is done
+ # after the Sinatra require directive.
require 'oboe'
- require 'oboe/inst/rack'
# When traces should be initiated for incoming requests. Valid options are
# "always", "through" (when the request is initiated with a tracing header
# from upstream) and "never". You must set this directive to "always" in
# order to initiate tracing.
@@ -56,37 +64,62 @@
# You can remove the following line in production to allow for
# auto sampling or managing the sample rate through the TraceView portal.
# Oboe::Config[:sample_rate] = 1000000
- # You may want to replace the Oboe.logger with your own
- Oboe.logger = Padrino.logger
-
- Oboe::Ruby.initialize
- Padrino.use Oboe::Rack
+ # You may want to replace the Oboe.logger with whichever logger you are using
+ # Oboe.logger = Sinatra.logger
+```
-_In a future release, much of this will be automated._
+Note: If you're on Heroku, you don't need to set `tracing_mode` or `sample_rate` - they will be automatically configured.
+Make sure that the oboe gem is loaded _after_ Sinatra either by listing `gem 'oboe'` after Sinatra in your Gemfile or calling the `require 'oboe'` directive after Sinatra is loaded.
+
+With this, the oboe gem will automatically detect Sinatra on boot and instrument key components.
+
+## Padrino
+
+As long as the oboe gem is in your `Gemfile` (inserted after the `gem 'padrino'` directive) and you are calling `Bundler.require`, the oboe gem will automatically instrument Padrino applications.
+
+If you need to set `Oboe::Config` values on stack boot, you can do so by adding the following
+to your `config/boot.rb` file:
+
+ Padrino.before_load do
+ # When traces should be initiated for incoming requests. Valid options are
+ # "always", "through" (when the request is initiated with a tracing header
+ # from upstream) and "never". You must set this directive to "always" in
+ # order to initiate tracing.
+ Oboe::Config[:tracing_mode] = 'always'
+
+ # You can remove the following line in production to allow for
+ # auto sampling or managing the sample rate through the TraceView portal.
+ Oboe::Config[:sample_rate] = 1e6
+ end
+
+Note: If you're on Heroku, you don't need to set `tracing_mode` or `sample_rate` - they will be automatically configured.
+
## Custom Ruby Scripts & Applications
The oboe gem has the ability to instrument any arbitrary Ruby application or script as long as the gem is initialized with the manual methods:
- require 'rubygems'
- require 'bundler'
-
- Bundler.require
-
- require 'oboe'
+```ruby
+require 'rubygems'
+require 'bundler'
- # Tracing mode can be 'never', 'through' (to follow upstream) or 'always'
- Oboe::Config[:tracing_mode] = 'always'
+Bundler.require
- # Number of requests to trace out of each million
- Oboe::Config[:sample_rate] = 1000000
+require 'oboe'
- Oboe::Ruby.initialize
+# Tracing mode can be 'never', 'through' (to follow upstream) or 'always'
+Oboe::Config[:tracing_mode] = 'always'
+# Number of requests to trace out of each million
+Oboe::Config[:sample_rate] = 1000000
+
+Oboe::Ruby.initialize
+```
+
From here, you can use the Tracing API to instrument areas of code using `Oboe::API.start_trace` (see below). If you prefer to instead dive directly into code, take a look at [this example](https://gist.github.com/pglombardo/8550713) of an instrumented Ruby script.
## Other
You can send deploy notifications to TraceView and have the events show up on your dashboard. See: [Capistrano Deploy Notifications with tlog](https://support.tv.appneta.com/support/solutions/articles/86389-capistrano-deploy-notifications-with-tlog).
@@ -95,24 +128,26 @@
## The Tracing API
You can instrument any arbitrary block of code using `Oboe::API.trace`:
- # layer_name will show up in the TraceView app dashboard
- layer_name = 'subsystemX'
+```ruby
+# layer_name will show up in the TraceView app dashboard
+layer_name = 'subsystemX'
- # report_kvs are a set of information Key/Value pairs that are sent to
- # TraceView dashboard along with the performance metrics. These KV
- # pairs are used to report request, environment and/or client specific
- # information.
+# report_kvs are a set of information Key/Value pairs that are sent to
+# TraceView dashboard along with the performance metrics. These KV
+# pairs are used to report request, environment and/or client specific
+# information.
- report_kvs = {}
- report_kvs[:mykey] = @client.id
+report_kvs = {}
+report_kvs[:mykey] = @client.id
- Oboe::API.trace(layer_name, report_kvs) do
- # the block of code to be traced
- end
+Oboe::API.trace(layer_name, report_kvs) do
+ # the block of code to be traced
+end
+```
`Oboe::API.trace` is used within the context of a request. It will follow the upstream state of the request being traced. i.e. the block of code will only be traced when the parent request is being traced.
This tracing state of a request can also be queried by using `Oboe.tracing?`.
@@ -124,24 +159,26 @@
By using class level declarations, it's possible to automatically have certain methods on that class instrumented and reported to your TraceView dashboard automatically.
The pattern for Method Profiling is as follows:
- # 'profile_name' is similar to a layer name.
- # It identifies this custom trace in your dashboard.
- #
- class Engine
- include OboeMethodProfiling
+```ruby
+# 'profile_name' is similar to a layer name.
+# It identifies this custom trace in your dashboard.
+#
+class Engine
+ include OboeMethodProfiling
- def processor()
- # body of method
- end
-
- # call syntax: profile_method <method>, <profile_name>
- profile_method :processor, 'processor'
+ def processor()
+ # body of method
end
+ # call syntax: profile_method <method>, <profile_name>
+ profile_method :processor, 'processor'
+end
+```
+
This example demonstrates method profiling of instance methods. Class methods are profiled slightly differently. See the TraceView [documentation portal](https://support.tv.appneta.com/support/solutions/articles/86395-ruby-instrumentation-public-api) for full details.
# Support
If you find a bug or would like to request an enhancement, feel free to file an issue. For all other support requests, see our [support portal](https://support.tv.appneta.com/) or on IRC @ #appneta on [Freenode](http://freenode.net/).
@@ -177,11 +214,13 @@
## Building the Gem
The oboe gem is built with the standard `gem build` command passing in the gemspec:
- gem build oboe.gemspec
+```bash
+gem build oboe.gemspec
+```
## Writing Custom Instrumentation
Custom instrumentation for a library, database or other service can be authored fairly easily. Generally, instrumentation of a library is done by wrapping select operations of that library and timing their execution using the Oboe Tracing API which then reports the metrics to the users' TraceView dashboard.
@@ -189,54 +228,58 @@
The Dalli gem nicely routes all memcache operations through a single `perform` operation. Wrapping this method allows us to capture all Dalli operations called by an application.
First, we define a module (Oboe::Inst::Dalli) and our own custom `perform_with_oboe` method that we will use as a wrapper around Dalli's `perform` method. We also declare an `included` method which automatically gets called when this module is included by another. See ['included' Ruby reference documentation](http://apidock.com/ruby/Module/included).
- module Oboe
- module Inst
- module Dalli
- include Oboe::API::Memcache
+```ruby
+module Oboe
+ module Inst
+ module Dalli
+ include Oboe::API::Memcache
- def self.included(cls)
- cls.class_eval do
- if ::Dalli::Client.private_method_defined? :perform
- alias perform_without_oboe perform
- alias perform perform_with_oboe
- end
- end
+ def self.included(cls)
+ cls.class_eval do
+ if ::Dalli::Client.private_method_defined? :perform
+ alias perform_without_oboe perform
+ alias perform perform_with_oboe
end
-
- def perform_with_oboe(*all_args, &blk)
- op, key, *args = *all_args
+ end
+ end
- if Oboe.tracing?
- opts = {}
- opts[:KVOp] = op
- opts[:KVKey] = key
+ def perform_with_oboe(*all_args, &blk)
+ op, key, *args = *all_args
- Oboe::API.trace('memcache', opts || {}) do
- result = perform_without_oboe(*all_args, &blk)
- if op == :get and key.class == String
- Oboe::API.log('memcache', 'info', { :KVHit => memcache_hit?(result) })
- end
- result
- end
- else
- perform_without_oboe(*all_args, &blk)
+ if Oboe.tracing?
+ opts = {}
+ opts[:KVOp] = op
+ opts[:KVKey] = key
+
+ Oboe::API.trace('memcache', opts || {}) do
+ result = perform_without_oboe(*all_args, &blk)
+ if op == :get and key.class == String
+ Oboe::API.log('memcache', 'info', { :KVHit => memcache_hit?(result) })
end
+ result
end
+ else
+ perform_without_oboe(*all_args, &blk)
end
end
end
+ end
+end
+```
Second, we tail onto the end of the instrumentation file a simple `::Dalli::Client.module_eval` call to tell the Dalli module to include our newly defined instrumentation module. Doing this will invoke our previously defined `included` method.
- if defined?(Dalli) and Oboe::Config[:dalli][:enabled]
- ::Dalli::Client.module_eval do
- include Oboe::Inst::Dalli
- end
- end
+```ruby
+if defined?(Dalli) and Oboe::Config[:dalli][:enabled]
+ ::Dalli::Client.module_eval do
+ include Oboe::Inst::Dalli
+ end
+end
+```
Third, in our wrapper method, we capture the arguments passed in, collect the operation and key information into a local hash and then invoke the `Oboe::API.trace` method to time the execution of the original operation.
The `Oboe::API.trace` method calls Dalli's native operation and reports the timing metrics and your custom `report_kvs` up to TraceView servers to be shown on the user's dashboard.
@@ -246,13 +289,13 @@
* You can point your Gemfile directly at your cloned oboe source by using `gem 'oboe', :path => '/path/to/oboe-ruby'`
* If instrumenting a library, database or service, place your new instrumentation file into the `lib/oboe/inst/` directory. From there, the oboe gem will detect it and automatically load the instrumentation file.
-* If instrumentating a new framework, place your instrumentation file in `lib/oboe/frameworks`. Refer to the Rails instrumentation for on ideas on how to load the oboe gem correctly in your framework.
+* If instrumenting a new framework, place your instrumentation file in `lib/oboe/frameworks`. Refer to the Rails instrumentation for on ideas on how to load the oboe gem correctly in your framework.
-* Review other existing instrumention similar to the one you wish to author. `lib/oboe/inst/` is a great place to start.
+* Review other existing instrumentation similar to the one you wish to author. `lib/oboe/inst/` is a great place to start.
* Depending on the configured `:sample_rate`, not all requests will be traced. Use `Oboe.tracing?` to determine of this is a request that is being traced.
* Performance is paramount. Make sure that your wrapped methods don't slow down users applications.
@@ -260,25 +303,29 @@
## Compiling the C extension
The oboe gem utilizes a C extension to interface with the system `liboboe.so` library. This system library is installed with the TraceView host packages (tracelyzer, liboboe0, liboboe-dev) and is used to report [host](http://www.appneta.com/blog/app-host-metrics/) and performance metrics from multiple sources (Ruby, Apache, Python etc.) back to TraceView servers.
-C extensions are usually built on `gem install` but when working out of a local git repository, it's required that you manually build this C extension for the gem to function.
+C extensions are usually built on `gem install` but when working out of a local git repository, it's required that you manually build this C extension for the gem to function.
To make this simpler, we've included a few rake tasks to automate this process:
- rake compile # Build the gem's c extension
- rake distclean # Remove all built files and extensions
- rake recompile # Rebuild the gem's c extension
+```bash
+rake compile # Build the gem's c extension
+rake distclean # Remove all built files and extensions
+rake recompile # Rebuild the gem's c extension
+```
Note: Make sure you have the development package `liboboe0-dev` installed before attempting to compile the C extension.
- >$ dpkg -l | grep liboboe
- ii liboboe-dev 1.1.1-precise1 Tracelytics common library -- development files
- ii liboboe0 1.1.1-precise1 Tracelytics common library
+```bash
+>$ dpkg -l | grep liboboe
+ii liboboe-dev 1.1.1-precise1 Tracelytics common library -- development files
+ii liboboe0 1.1.1-precise1 Tracelytics common library
+```
-See [Installing Base Packages on Debian and Ubuntu](https://support.tv.appneta.com/support/solutions/articles/86359-installing-base-packages-on-debian-and-ubuntu) in the Knowledge Base for details. Our hacker extraodinaire [Rob Salmond](https://github.com/rsalmond) from the support team has even gotten these packages to [run on Gentoo](http://www.appneta.com/blog/unsupported-doesnt-work/)!
+See [Installing Base Packages on Debian and Ubuntu](https://support.tv.appneta.com/support/solutions/articles/86359-installing-base-packages-on-debian-and-ubuntu) in the Knowledge Base for details. Our hacker extraordinaire [Rob Salmond](https://github.com/rsalmond) from the support team has even gotten these packages to [run on Gentoo](http://www.appneta.com/blog/unsupported-doesnt-work/)!
To see the code related to the C extension, take a look at `ext/oboe_metal/extconf.rb` for details.
You can read more about Ruby gems with C extensions in the [Rubygems Guides](http://guides.rubygems.org/gems-with-extensions/).
@@ -286,23 +333,27 @@
The tests bundled with the gem are implemented using [Minitest](https://github.com/seattlerb/minitest). The tests are currently used to validate the sanity of the traces generated and basic gem functionality.
After a bundle install, the tests can be run as:
- bundle exec rake test
+```bash
+bundle exec rake test
+```
This will run a full end-to-end test suite that covers all supported libraries and databases. Note that this requires all of the supported software (Cassandra, Memcache, Mongo etc.) to be installed, configured and available.
-Since this is overly burdonsome for casual users, you can run just the tests that you're interested in.
+Since this is overly burdensome for casual users, you can run just the tests that you're interested in.
To run just the tests for the dalli gem trace validation:
- bundle exec rake test TEST=test/instrumentation/dalli_test.rb
+```bash
+bundle exec rake test TEST=test/instrumentation/dalli_test.rb
+```
-We humbly request that any submitted instrumention is delivered with corresponding test coverage.
+We humbly request that any submitted instrumentation is delivered with corresponding test coverage.
# License
-Copyright (c) 2013 Appneta
+Copyright (c) 2014 Appneta
Released under the [AppNeta Open License](http://www.appneta.com/appneta-license), Version 1.0