oboe 2.7.0.3-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +51 -0
  4. data/Appraisals +10 -0
  5. data/CHANGELOG.md +223 -0
  6. data/Gemfile +49 -0
  7. data/LICENSE +199 -0
  8. data/README.md +380 -0
  9. data/Rakefile +106 -0
  10. data/ext/oboe_metal/extconf.rb +61 -0
  11. data/ext/oboe_metal/noop/noop.c +7 -0
  12. data/ext/oboe_metal/src/bson/bson.h +221 -0
  13. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  14. data/ext/oboe_metal/src/oboe.h +275 -0
  15. data/ext/oboe_metal/src/oboe.hpp +352 -0
  16. data/ext/oboe_metal/src/oboe_wrap.cxx +3886 -0
  17. data/ext/oboe_metal/tests/test.rb +11 -0
  18. data/gemfiles/mongo.gemfile +33 -0
  19. data/gemfiles/moped.gemfile +33 -0
  20. data/get_version.rb +5 -0
  21. data/init.rb +4 -0
  22. data/lib/base.rb +99 -0
  23. data/lib/joboe_metal.rb +185 -0
  24. data/lib/method_profiling.rb +70 -0
  25. data/lib/oboe.rb +50 -0
  26. data/lib/oboe/api.rb +14 -0
  27. data/lib/oboe/api/layerinit.rb +99 -0
  28. data/lib/oboe/api/logging.rb +129 -0
  29. data/lib/oboe/api/memcache.rb +29 -0
  30. data/lib/oboe/api/profiling.rb +50 -0
  31. data/lib/oboe/api/tracing.rb +134 -0
  32. data/lib/oboe/api/util.rb +117 -0
  33. data/lib/oboe/config.rb +140 -0
  34. data/lib/oboe/frameworks/grape.rb +74 -0
  35. data/lib/oboe/frameworks/padrino.rb +66 -0
  36. data/lib/oboe/frameworks/padrino/templates.rb +59 -0
  37. data/lib/oboe/frameworks/rails.rb +139 -0
  38. data/lib/oboe/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
  39. data/lib/oboe/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
  40. data/lib/oboe/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
  41. data/lib/oboe/frameworks/rails/inst/action_controller.rb +123 -0
  42. data/lib/oboe/frameworks/rails/inst/action_view.rb +56 -0
  43. data/lib/oboe/frameworks/rails/inst/action_view_2x.rb +54 -0
  44. data/lib/oboe/frameworks/rails/inst/action_view_30.rb +48 -0
  45. data/lib/oboe/frameworks/rails/inst/active_record.rb +24 -0
  46. data/lib/oboe/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  47. data/lib/oboe/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  48. data/lib/oboe/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
  49. data/lib/oboe/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  50. data/lib/oboe/frameworks/rails/inst/connection_adapters/utils.rb +118 -0
  51. data/lib/oboe/frameworks/sinatra.rb +96 -0
  52. data/lib/oboe/frameworks/sinatra/templates.rb +56 -0
  53. data/lib/oboe/inst/cassandra.rb +281 -0
  54. data/lib/oboe/inst/dalli.rb +75 -0
  55. data/lib/oboe/inst/http.rb +72 -0
  56. data/lib/oboe/inst/memcache.rb +105 -0
  57. data/lib/oboe/inst/memcached.rb +96 -0
  58. data/lib/oboe/inst/mongo.rb +240 -0
  59. data/lib/oboe/inst/moped.rb +474 -0
  60. data/lib/oboe/inst/rack.rb +81 -0
  61. data/lib/oboe/inst/redis.rb +273 -0
  62. data/lib/oboe/inst/resque.rb +193 -0
  63. data/lib/oboe/instrumentation.rb +18 -0
  64. data/lib/oboe/loading.rb +98 -0
  65. data/lib/oboe/logger.rb +41 -0
  66. data/lib/oboe/ruby.rb +11 -0
  67. data/lib/oboe/util.rb +129 -0
  68. data/lib/oboe/version.rb +13 -0
  69. data/lib/oboe/xtrace.rb +52 -0
  70. data/lib/oboe_metal.rb +140 -0
  71. data/lib/rails/generators/oboe/install_generator.rb +76 -0
  72. data/lib/rails/generators/oboe/templates/oboe_initializer.rb +94 -0
  73. data/oboe.gemspec +29 -0
  74. data/release.sh +65 -0
  75. data/test/frameworks/apps/grape_simple.rb +10 -0
  76. data/test/frameworks/apps/padrino_simple.rb +41 -0
  77. data/test/frameworks/apps/sinatra_simple.rb +20 -0
  78. data/test/frameworks/grape_test.rb +27 -0
  79. data/test/frameworks/padrino_test.rb +25 -0
  80. data/test/frameworks/sinatra_test.rb +25 -0
  81. data/test/instrumentation/cassandra_test.rb +381 -0
  82. data/test/instrumentation/dalli_test.rb +164 -0
  83. data/test/instrumentation/http_test.rb +97 -0
  84. data/test/instrumentation/memcache_test.rb +251 -0
  85. data/test/instrumentation/memcached_test.rb +226 -0
  86. data/test/instrumentation/mongo_test.rb +462 -0
  87. data/test/instrumentation/moped_test.rb +473 -0
  88. data/test/instrumentation/rack_test.rb +73 -0
  89. data/test/instrumentation/redis_hashes_test.rb +265 -0
  90. data/test/instrumentation/redis_keys_test.rb +318 -0
  91. data/test/instrumentation/redis_lists_test.rb +310 -0
  92. data/test/instrumentation/redis_misc_test.rb +160 -0
  93. data/test/instrumentation/redis_sets_test.rb +293 -0
  94. data/test/instrumentation/redis_sortedsets_test.rb +325 -0
  95. data/test/instrumentation/redis_strings_test.rb +333 -0
  96. data/test/instrumentation/resque_test.rb +62 -0
  97. data/test/minitest_helper.rb +148 -0
  98. data/test/profiling/method_test.rb +198 -0
  99. data/test/support/config_test.rb +39 -0
  100. data/test/support/liboboe_settings_test.rb +46 -0
  101. data/test/support/xtrace_test.rb +35 -0
  102. metadata +200 -0
@@ -0,0 +1,76 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ source_root File.join(File.dirname(__FILE__), 'templates')
7
+ desc "Copies an oboe initializer files to your application."
8
+
9
+ def copy_initializer
10
+ # Set defaults
11
+ @tracing_mode = 'through'
12
+ @sample_rate = '300000'
13
+ @verbose = 'false'
14
+
15
+ print_header
16
+
17
+ while true do
18
+ print_body
19
+
20
+ user_tracing_mode = ask shell.set_color "* Tracing Mode? [through]:", :yellow
21
+ user_tracing_mode.downcase!
22
+
23
+ break if user_tracing_mode.blank?
24
+ valid = ['always', 'through', 'never'].include?(user_tracing_mode)
25
+
26
+ say shell.set_color "Valid values are 'always', 'through' or 'never'", :red, :bold unless valid
27
+ if valid
28
+ @tracing_mode = user_tracing_mode
29
+ break
30
+ end
31
+ end
32
+
33
+ print_footer
34
+
35
+ template "oboe_initializer.rb", "config/initializers/oboe.rb"
36
+ end
37
+
38
+ private
39
+
40
+ def print_header
41
+ say ""
42
+ say shell.set_color "Welcome to the TraceView Ruby instrumentation setup.", :green, :bold
43
+ say ""
44
+ say "To instrument your Rails application, you can setup your tracing strategy here."
45
+ say ""
46
+ say shell.set_color "Documentation Links", :magenta
47
+ say "-------------------"
48
+ say ""
49
+ say "Details on configuring your sample rate:"
50
+ say "https://support.appneta.com/cloud/configuring-sampling"
51
+ say ""
52
+ say "More information on instrumenting Ruby applications can be found here:"
53
+ say "https://support.appneta.com/cloud/installing-ruby-instrumentation"
54
+ end
55
+
56
+ def print_body
57
+ say ""
58
+ say shell.set_color "Tracing Mode", :magenta
59
+ say "------------"
60
+ say "Tracing Mode determines when traces should be initiated for incoming requests. Valid"
61
+ say "options are #{shell.set_color "always", :yellow}, #{shell.set_color "through", :yellow} (when using an instrumented Apache or Nginx) and #{shell.set_color "never", :yellow}."
62
+ say ""
63
+ say "If you're not using an instrumented Apache or Nginx, set this directive to #{shell.set_color "always", :yellow} in"
64
+ say "order to initiate tracing from Ruby."
65
+ say ""
66
+ end
67
+
68
+ def print_footer
69
+ say ""
70
+ say "You can change configuration values in the future by modifying config/initializers/oboe.rb"
71
+ say ""
72
+ say "Thanks! Creating the TraceView initializer..."
73
+ say ""
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,94 @@
1
+ # AppNeta TraceView Initializer (the oboe gem)
2
+ # http://www.appneta.com/products/traceview/
3
+ #
4
+ # Details on configuring your sample rate:
5
+ # https://support.appneta.com/cloud/configuring-sampling
6
+ #
7
+ # More information on instrumenting Ruby applications can be found here:
8
+ # https://support.appneta.com/cloud/installing-ruby-instrumentation
9
+
10
+ if defined?(Oboe::Config)
11
+ # Tracing Mode determines when traces should be initiated for incoming requests. Valid
12
+ # options are always, through (when using an instrumented Apache or Nginx) and never.
13
+ #
14
+ # If you're not using an instrumented Apache or Nginx, set this directive to always in
15
+ # order to initiate tracing from Ruby.
16
+ Oboe::Config[:tracing_mode] = '<%= @tracing_mode %>'
17
+
18
+ # sample_rate is a value from 0 - 1m indicating the fraction of requests per million to trace
19
+ # Oboe::Config[:sample_rate] = <%= @sample_rate %>
20
+
21
+ # Verbose output of instrumentation initialization
22
+ # Oboe::Config[:verbose] = <%= @verbose %>
23
+
24
+ #
25
+ # Resque Options
26
+ #
27
+ # :link_workers - associates Resque enqueue operations with the jobs they queue by piggybacking
28
+ # an additional argument on the Redis queue that is stripped prior to job
29
+ # processing
30
+ # !!! Note: Make sure both the enqueue side and the Resque workers are instrumented
31
+ # before enabling this or jobs will fail !!!
32
+ # (Default: false)
33
+ # Oboe::Config[:resque][:link_workers] = false
34
+ #
35
+ # Set to true to disable Resque argument logging (Default: false)
36
+ # Oboe::Config[:resque][:log_args] = false
37
+
38
+ # The oboe Ruby client has the ability to sanitize query literals
39
+ # from SQL statements. By default this is disabled. Enable to
40
+ # avoid collecting and reporting query literals to TraceView.
41
+ # Oboe::Config[:sanitize_sql] = false
42
+
43
+ #
44
+ # Enabling/Disabling Instrumentation
45
+ #
46
+ # If you're having trouble with one of the instrumentation libraries, they
47
+ # can be individually disabled here by setting the :enabled
48
+ # value to false:
49
+ #
50
+ # Oboe::Config[:action_controller][:enabled] = true
51
+ # Oboe::Config[:active_record][:enabled] = true
52
+ # Oboe::Config[:action_view][:enabled] = true
53
+ # Oboe::Config[:cassandra][:enabled] = true
54
+ # Oboe::Config[:dalli][:enabled] = true
55
+ # Oboe::Config[:memcache][:enabled] = true
56
+ # Oboe::Config[:memcached][:enabled] = true
57
+ # Oboe::Config[:mongo][:enabled] = true
58
+ # Oboe::Config[:moped][:enabled] = true
59
+ # Oboe::Config[:nethttp][:enabled] = true
60
+ # Oboe::Config[:redis][:enabled] = true
61
+ # Oboe::Config[:resque][:enabled] = true
62
+
63
+ #
64
+ # Enabling/Disabling Backtrace Collection
65
+ #
66
+ # Instrumentation can optionally collect backtraces as they collect
67
+ # performance metrics. Note that this has a negative impact on
68
+ # performance but can be useful when trying to locate the source of
69
+ # a certain call or operation.
70
+ #
71
+ # Oboe::Config[:action_controller][:collect_backtraces] = true
72
+ # Oboe::Config[:active_record][:collect_backtraces] = true
73
+ # Oboe::Config[:action_view][:collect_backtraces] = true
74
+ # Oboe::Config[:cassandra][:collect_backtraces] = true
75
+ # Oboe::Config[:dalli][:collect_backtraces] = false
76
+ # Oboe::Config[:memcache][:collect_backtraces] = false
77
+ # Oboe::Config[:memcached][:collect_backtraces] = false
78
+ # Oboe::Config[:mongo][:collect_backtraces] = true
79
+ # Oboe::Config[:moped][:collect_backtraces] = true
80
+ # Oboe::Config[:nethttp][:collect_backtraces] = true
81
+ # Oboe::Config[:redis][:collect_backtraces] = false
82
+ # Oboe::Config[:resque][:collect_backtraces] = true
83
+ #
84
+
85
+ #
86
+ # Blacklist actions
87
+ #
88
+ # e.g. if your load balancer requests 'index#ok'
89
+ #
90
+ # Oboe::Config[:action_blacklist] = {
91
+ # 'index#ok' => true
92
+ # }
93
+
94
+ end
@@ -0,0 +1,29 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require "oboe/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = %q{oboe}
6
+ s.version = Oboe::Version::STRING
7
+ s.date = Time.now.strftime('%Y-%m-%d')
8
+
9
+ s.license = "AppNeta Open License, Version 1.0"
10
+
11
+ s.authors = ["Peter Giacomo Lombardo", "Spiros Eliopoulos"]
12
+ s.email = %q{traceviewsupport@appneta.com}
13
+ s.homepage = %q{http://www.appneta.com/products/traceview/}
14
+ s.summary = %q{AppNeta TraceView performance instrumentation gem for Ruby}
15
+ s.description = %q{The oboe gem provides TraceView instrumentation for MRI Ruby, JRuby and related frameworks.}
16
+
17
+ s.extra_rdoc_files = ["LICENSE"]
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = Dir.glob("{test}/**/*.rb")
20
+
21
+ s.platform = defined?(JRUBY_VERSION) ? 'java' : Gem::Platform::RUBY
22
+ s.extensions = ['ext/oboe_metal/extconf.rb'] unless defined?(JRUBY_VERSION)
23
+
24
+ s.add_runtime_dependency('json', '>= 0')
25
+ s.add_development_dependency('rake', '>= 0')
26
+
27
+ s.required_ruby_version = '>= 1.8.6'
28
+ end
29
+
@@ -0,0 +1,65 @@
1
+ #!/bin/bash
2
+ #
3
+ # for use only when you're ready to push from prod -> rubygems
4
+ #
5
+
6
+ if [ $# -ne 0 ]
7
+ then
8
+ echo -e "Usage: `basename $0`"
9
+ echo -e "-Summary-"
10
+ echo -e "\t This script will help you build and release a new version of the oboe Ruby gem."
11
+ echo -e "\t It will also create a git tag with the version being released."
12
+ echo -e ""
13
+ echo -e "-Steps-"
14
+ echo -e "\t 1. Update lib/oboe/version.rb with the new version you wish to release."
15
+ echo -e "\t 2. Re-run this script without any arguments."
16
+ echo -e ""
17
+ echo -e "-Notes-"
18
+ echo -e "\t You must have ~/.gem/credentials setup with the Appneta API key for Rubygems."
19
+ echo -e "\t The API key should be titled :rubygems_appneta: in the credentials file."
20
+ echo -e ""
21
+ echo -e "\t Gems with letters in the build number (e.g. pre1 or beta1)will be released "
22
+ echo -e "\t as a prerelease gem on Rubygems."
23
+ echo -e ""
24
+ echo -e "\t See here for an explanation on prelease gems:"
25
+ echo -e "\t http://guides.rubygems.org/patterns/#prerelease-gems"
26
+ exit $E_BADARGS
27
+ fi
28
+
29
+ if [ $(git branch -a | grep ^* | awk '{print $2}') != "prod" ]; then
30
+ echo -e "You can only release gems from prod branch."
31
+ echo -e "Do a 'git checkout prod' and try again."
32
+ exit
33
+ fi
34
+
35
+ #set -e # stop on first non-zero exit code
36
+ #set -x # show commands as they happen
37
+
38
+ # Get gem version from lib/oboe/version.rb
39
+ VERSION=`/usr/bin/env ruby ./get_version.rb`
40
+
41
+ read -p "Are you sure you want to release oboe gem version $VERSION to Rubygems? [y/N]" -n 1 -r
42
+ if [[ $REPLY =~ ^[Yy]$ ]]
43
+ then
44
+ echo -e ""
45
+
46
+ # tag release (if tag already exists, bails out)
47
+ echo -e "Creating git tag rel-$VERSION..."
48
+ if ! git tag rel-$VERSION; then
49
+ echo -e "Couldn't create tag for ${VERSION}: if it already exists, you need to bump the version."
50
+ exit
51
+ fi
52
+
53
+ echo -e "Pushing tags to origin (Github)..."
54
+ git push --tags
55
+
56
+ # Build and publish the gem to Rubygems.org
57
+ echo -e "Building gem..."
58
+ gem build oboe.gemspec
59
+ echo -e "Pushing built gem to Rubygems..."
60
+ gem push -k rubygems_appneta oboe-$VERSION.gem
61
+ else
62
+ echo -e ""
63
+ echo -e "Canceled...nothing done. Have a nice day."
64
+ fi
65
+
@@ -0,0 +1,10 @@
1
+ require 'grape'
2
+
3
+ class GrapeSimple < Grape::API
4
+ set :reload, true
5
+
6
+ get '/json_endpoint' do
7
+ present({ :test => true })
8
+ end
9
+ end
10
+
@@ -0,0 +1,41 @@
1
+ # This test Padrino stack file was taken from the padrino-core gem.
2
+ #
3
+ PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
4
+ # Remove this comment if you want do some like this: ruby PADRINO_ENV=test app.rb
5
+ #
6
+ # require 'rubygems'
7
+ # require 'padrino-core'
8
+ #
9
+
10
+ class SimpleDemo < Padrino::Application
11
+ set :public_folder, File.dirname(__FILE__)
12
+ set :reload, true
13
+ before { true }
14
+ after { true }
15
+ error(404) { "404" }
16
+ end
17
+
18
+ SimpleDemo.controllers do
19
+ get "/" do
20
+ 'The magick number is: 2767356926488785838763860464013972991031534522105386787489885890443740254365!' # Change only the number!!!
21
+ end
22
+
23
+ get "/rand" do
24
+ rand(2 ** 256).to_s
25
+ end
26
+
27
+ get "/render" do
28
+ render :erb, "This is an erb render"
29
+ end
30
+ end
31
+
32
+ ## If you want use this as a standalone app uncomment:
33
+ #
34
+ # Padrino.mount("SimpleDemo").to("/")
35
+ # Padrino.run! unless Padrino.loaded? # If you enable reloader prevent to re-run the app
36
+ #
37
+ # Then run it from your console: ruby -I"lib" test/fixtures/apps/simple.rb
38
+ #
39
+
40
+ Padrino.load!
41
+
@@ -0,0 +1,20 @@
1
+ require 'sinatra'
2
+
3
+ class SinatraSimple < Sinatra::Base
4
+ set :reload, true
5
+
6
+ get "/" do
7
+ 'The magick number is: 2767356926488785838763860464013972991031534522105386787489885890443740254365!' # Change only the number!!!
8
+ end
9
+
10
+ get "/rand" do
11
+ rand(2 ** 256).to_s
12
+ end
13
+
14
+ get "/render" do
15
+ render :erb, "This is an erb render"
16
+ end
17
+ end
18
+
19
+ use SinatraSimple
20
+
@@ -0,0 +1,27 @@
1
+ if RUBY_VERSION >= '1.9.3'
2
+ require 'minitest_helper'
3
+ require File.expand_path(File.dirname(__FILE__) + '/apps/grape_simple')
4
+
5
+ describe Grape do
6
+ before do
7
+ clear_all_traces
8
+ end
9
+
10
+ it "should trace a request to a simple grape stack" do
11
+ @app = GrapeSimple
12
+
13
+ r = get "/json_endpoint"
14
+
15
+ traces = get_all_traces
16
+ traces.count.must_equal 5
17
+
18
+ validate_outer_layers(traces, 'rack')
19
+
20
+ traces[1]['Layer'].must_equal "grape"
21
+ traces[2]['Layer'].must_equal "grape"
22
+ traces[2].has_key?('Controller').must_equal true
23
+ traces[2].has_key?('Action').must_equal true
24
+ traces[3]['Label'].must_equal "info"
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ if RUBY_VERSION >= '1.9.3'
2
+ require "minitest_helper"
3
+ require File.expand_path(File.dirname(__FILE__) + '/apps/padrino_simple')
4
+
5
+ describe Padrino do
6
+ before do
7
+ clear_all_traces
8
+ end
9
+
10
+ it "should trace a request to a simple padrino stack" do
11
+ @app = SimpleDemo
12
+
13
+ r = get "/render"
14
+
15
+ traces = get_all_traces
16
+ traces.count.must_equal 9
17
+
18
+ validate_outer_layers(traces, 'rack')
19
+
20
+ traces[1]['Layer'].must_equal "padrino"
21
+ traces[6]['Controller'].must_equal "SimpleDemo"
22
+ traces[7]['Label'].must_equal "info"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require "minitest_helper"
2
+ require File.expand_path(File.dirname(__FILE__) + '/apps/sinatra_simple')
3
+
4
+ describe Sinatra do
5
+ before do
6
+ clear_all_traces
7
+ end
8
+
9
+ it "should trace a request to a simple sinatra stack" do
10
+ @app = SinatraSimple
11
+
12
+ r = get "/render"
13
+
14
+ traces = get_all_traces
15
+ traces.count.must_equal 9
16
+
17
+ validate_outer_layers(traces, 'rack')
18
+
19
+ traces[1]['Layer'].must_equal "sinatra"
20
+ traces[3]['Label'].must_equal "profile_entry"
21
+ traces[6]['Controller'].must_equal "SinatraSimple"
22
+ traces[7]['Label'].must_equal "info"
23
+ end
24
+ end
25
+
@@ -0,0 +1,381 @@
1
+ require 'minitest_helper'
2
+
3
+ # The cassandra-rb client doesn't support JRuby
4
+ # https://github.com/cassandra-rb/cassandra
5
+ unless defined?(JRUBY_VERSION)
6
+ describe Oboe::Inst::Cassandra do
7
+ before do
8
+ clear_all_traces
9
+
10
+ @client = Cassandra.new("system", "127.0.0.1:9160", { :timeout => 10 })
11
+ @client.disable_node_auto_discovery!
12
+
13
+ @ks_name = "AppNetaCassandraTest"
14
+
15
+ ks_def = CassandraThrift::KsDef.new(:name => @ks_name,
16
+ :strategy_class => "SimpleStrategy",
17
+ :strategy_options => { 'replication_factor' => '2' },
18
+ :cf_defs => [])
19
+
20
+ @client.add_keyspace(ks_def) unless @client.keyspaces.include? @ks_name
21
+ @client.keyspace = @ks_name
22
+
23
+ unless @client.column_families.include? "Users"
24
+ cf_def = CassandraThrift::CfDef.new(:keyspace => @ks_name, :name => "Users")
25
+ @client.add_column_family(cf_def)
26
+ end
27
+
28
+ unless @client.column_families.include? "Statuses"
29
+ cf_def = CassandraThrift::CfDef.new(:keyspace => @ks_name, :name => "Statuses")
30
+ @client.add_column_family(cf_def)
31
+ end
32
+
33
+ # These are standard entry/exit KVs that are passed up with all mongo operations
34
+ @entry_kvs = {
35
+ 'Layer' => 'cassandra',
36
+ 'Label' => 'entry',
37
+ 'RemoteHost' => '127.0.0.1',
38
+ 'RemotePort' => '9160' }
39
+
40
+ @exit_kvs = { 'Layer' => 'cassandra', 'Label' => 'exit' }
41
+ @collect_backtraces = Oboe::Config[:cassandra][:collect_backtraces]
42
+ end
43
+
44
+ after do
45
+ Oboe::Config[:cassandra][:collect_backtraces] = @collect_backtraces
46
+ @client.disconnect!
47
+ end
48
+
49
+ it 'Stock Cassandra should be loaded, defined and ready' do
50
+ defined?(::Cassandra).wont_match nil
51
+ end
52
+
53
+ it 'Cassandra should have oboe methods defined' do
54
+ [ :insert, :remove, :count_columns, :get_columns, :multi_get_columns, :get,
55
+ :multi_get, :get_range_single, :get_range_batch, :get_indexed_slices,
56
+ :create_index, :drop_index, :add_column_family, :drop_column_family,
57
+ :add_keyspace, :drop_keyspace ].each do |m|
58
+ ::Cassandra.method_defined?("#{m}_with_oboe").must_equal true
59
+ end
60
+ # Special 'exists?' case
61
+ ::Cassandra.method_defined?("exists_with_oboe?").must_equal true
62
+ end
63
+
64
+ it 'should trace insert' do
65
+ Oboe::API.start_trace('cassandra_test', '', {}) do
66
+ user = {'screen_name' => 'larry', "blah" => "ok"}
67
+ @client.insert(:Users, '5', user, { :ttl => 600, :consistency => 1})
68
+ end
69
+
70
+ traces = get_all_traces
71
+
72
+ traces.count.must_equal 4
73
+ validate_outer_layers(traces, 'cassandra_test')
74
+
75
+ validate_event_keys(traces[1], @entry_kvs)
76
+ traces[1]['Op'].must_equal "insert"
77
+ traces[1]['Cf'].must_equal "Users"
78
+ traces[1]['Key'].must_equal "\"5\""
79
+ traces[1]['Consistency'].must_equal "1"
80
+ traces[1]['Ttl'].must_equal "600"
81
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
82
+ validate_event_keys(traces[2], @exit_kvs)
83
+ end
84
+
85
+ it 'should trace remove' do
86
+ Oboe::API.start_trace('cassandra_test', '', {}) do
87
+ @client.remove(:Users, '5', 'blah')
88
+ end
89
+
90
+ traces = get_all_traces
91
+
92
+ traces.count.must_equal 4
93
+ validate_outer_layers(traces, 'cassandra_test')
94
+
95
+ validate_event_keys(traces[1], @entry_kvs)
96
+ traces[1]['Op'].must_equal "remove"
97
+ traces[1]['Cf'].must_equal "Users"
98
+ traces[1]['Key'].must_equal "\"5\""
99
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
100
+ validate_event_keys(traces[2], @exit_kvs)
101
+ end
102
+
103
+ it 'should trace count_columns' do
104
+ @client.insert(:Statuses, '12', {'body' => 'v1', 'user' => 'v2'})
105
+
106
+ Oboe::API.start_trace('cassandra_test', '', {}) do
107
+ @client.count_columns(:Statuses, '12', :count => 50)
108
+ end
109
+
110
+ traces = get_all_traces
111
+
112
+ traces.count.must_equal 4
113
+ validate_outer_layers(traces, 'cassandra_test')
114
+
115
+ validate_event_keys(traces[1], @entry_kvs)
116
+ traces[1]['Op'].must_equal "count_columns"
117
+ traces[1]['Cf'].must_equal "Statuses"
118
+ traces[1]['Key'].must_equal "\"12\""
119
+ traces[1]['Count'].must_equal "50"
120
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
121
+ validate_event_keys(traces[2], @exit_kvs)
122
+ end
123
+
124
+ it 'should trace get_columns' do
125
+ Oboe::API.start_trace('cassandra_test', '', {}) do
126
+ @client.get_columns(:Statuses, '12', ['body'])
127
+ end
128
+
129
+ traces = get_all_traces
130
+
131
+ traces.count.must_equal 4
132
+ validate_outer_layers(traces, 'cassandra_test')
133
+
134
+ validate_event_keys(traces[1], @entry_kvs)
135
+ traces[1]['Op'].must_equal "get_columns"
136
+ traces[1]['Cf'].must_equal "Statuses"
137
+ traces[1]['Key'].must_equal "\"12\""
138
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
139
+ validate_event_keys(traces[2], @exit_kvs)
140
+ end
141
+
142
+ it 'should trace multi_get_columns' do
143
+ Oboe::API.start_trace('cassandra_test', '', {}) do
144
+ @client.multi_get_columns(:Users, ['12', '5'], ['body'])
145
+ end
146
+
147
+ traces = get_all_traces
148
+
149
+ traces.count.must_equal 4
150
+ validate_outer_layers(traces, 'cassandra_test')
151
+
152
+ validate_event_keys(traces[1], @entry_kvs)
153
+ traces[1]['Op'].must_equal "multi_get_columns"
154
+ traces[1]['Cf'].must_equal "Users"
155
+ traces[1]['Key'].must_equal "[\"12\", \"5\"]"
156
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
157
+ validate_event_keys(traces[2], @exit_kvs)
158
+ end
159
+
160
+ it 'should trace get' do
161
+ Oboe::API.start_trace('cassandra_test', '', {}) do
162
+ @client.get(:Statuses, '12', :reversed => true)
163
+ end
164
+
165
+ traces = get_all_traces
166
+
167
+ traces.count.must_equal 4
168
+ validate_outer_layers(traces, 'cassandra_test')
169
+
170
+ validate_event_keys(traces[1], @entry_kvs)
171
+ traces[1]['Op'].must_equal "get"
172
+ traces[1]['Cf'].must_equal "Statuses"
173
+ traces[1]['Key'].must_equal "\"12\""
174
+ traces[1]['Reversed'].must_equal "true"
175
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
176
+ validate_event_keys(traces[2], @exit_kvs)
177
+ end
178
+
179
+ it 'should trace exists?' do
180
+ Oboe::API.start_trace('cassandra_test', '', {}) do
181
+ @client.exists?(:Statuses, '12')
182
+ @client.exists?(:Statuses, '12', 'body')
183
+ end
184
+
185
+ traces = get_all_traces
186
+
187
+ traces.count.must_equal 6
188
+ validate_outer_layers(traces, 'cassandra_test')
189
+
190
+ validate_event_keys(traces[1], @entry_kvs)
191
+ traces[1]['Op'].must_equal "exists?"
192
+ traces[1]['Cf'].must_equal "Statuses"
193
+ traces[1]['Key'].must_equal "\"12\""
194
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
195
+ validate_event_keys(traces[2], @exit_kvs)
196
+
197
+ traces[3]['Op'].must_equal "exists?"
198
+ traces[3]['Cf'].must_equal "Statuses"
199
+ traces[3]['Key'].must_equal "\"12\""
200
+ traces[3].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
201
+ end
202
+
203
+ it 'should trace get_range_keys' do
204
+ Oboe::API.start_trace('cassandra_test', '', {}) do
205
+ @client.get_range_keys(:Statuses, :key_count => 4)
206
+ end
207
+
208
+ traces = get_all_traces
209
+
210
+ traces.count.must_equal 4
211
+ validate_outer_layers(traces, 'cassandra_test')
212
+
213
+ validate_event_keys(traces[1], @entry_kvs)
214
+ traces[1]['Op'].must_equal "get_range_batch"
215
+ traces[1]['Cf'].must_equal "Statuses"
216
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
217
+ validate_event_keys(traces[2], @exit_kvs)
218
+ end
219
+
220
+ it 'should trace create_index' do
221
+ Oboe::API.start_trace('cassandra_test', '', {}) do
222
+ @client.create_index(@ks_name, 'Statuses', 'column_name', 'LongType')
223
+ end
224
+
225
+ traces = get_all_traces
226
+
227
+ traces.count.must_equal 4
228
+ validate_outer_layers(traces, 'cassandra_test')
229
+
230
+ validate_event_keys(traces[1], @entry_kvs)
231
+ traces[1]['Op'].must_equal "create_index"
232
+ traces[1]['Cf'].must_equal "Statuses"
233
+ traces[1]['Keyspace'].must_equal @ks_name
234
+ traces[1]['Column_name'].must_equal "column_name"
235
+ traces[1]['Validation_class'].must_equal "LongType"
236
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
237
+ validate_event_keys(traces[2], @exit_kvs)
238
+
239
+ # Clean up
240
+ @client.drop_index(@ks_name, 'Statuses', 'column_name')
241
+ end
242
+
243
+ it 'should trace drop_index' do
244
+ # Prep
245
+ @client.create_index(@ks_name, 'Statuses', 'column_name', 'LongType')
246
+
247
+ Oboe::API.start_trace('cassandra_test', '', {}) do
248
+ @client.drop_index(@ks_name, 'Statuses', 'column_name')
249
+ end
250
+
251
+ traces = get_all_traces
252
+
253
+ traces.count.must_equal 4
254
+ validate_outer_layers(traces, 'cassandra_test')
255
+
256
+ validate_event_keys(traces[1], @entry_kvs)
257
+ traces[1]['Op'].must_equal "drop_index"
258
+ traces[1]['Cf'].must_equal "Statuses"
259
+ traces[1]['Keyspace'].must_equal @ks_name
260
+ traces[1]['Column_name'].must_equal "column_name"
261
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
262
+ validate_event_keys(traces[2], @exit_kvs)
263
+ end
264
+
265
+ it 'should trace get_indexed_slices' do
266
+ @client.create_index(@ks_name, 'Statuses', 'x', 'LongType')
267
+ Oboe::API.start_trace('cassandra_test', '', {}) do
268
+ expressions = [
269
+ { :column_name => 'x',
270
+ :value => [0,20].pack("NN"),
271
+ :comparison => "=="},
272
+ { :column_name => 'non_indexed',
273
+ :value => [5].pack("N*"),
274
+ :comparison => ">"} ]
275
+ @client.get_indexed_slices(:Statuses, expressions).length
276
+ end
277
+
278
+ traces = get_all_traces
279
+
280
+ traces.count.must_equal 4
281
+ validate_outer_layers(traces, 'cassandra_test')
282
+
283
+ validate_event_keys(traces[1], @entry_kvs)
284
+ traces[1]['Op'].must_equal "get_indexed_slices"
285
+ traces[1]['Cf'].must_equal "Statuses"
286
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
287
+ validate_event_keys(traces[2], @exit_kvs)
288
+ end
289
+
290
+ it 'should trace add and remove of column family' do
291
+ cf_name = (0...10).map{ ('a'..'z').to_a[rand(26)] }.join
292
+ cf_def = CassandraThrift::CfDef.new(:keyspace => @ks_name, :name => cf_name)
293
+
294
+ Oboe::API.start_trace('cassandra_test', '', {}) do
295
+ @client.add_column_family(cf_def)
296
+ @client.drop_column_family(cf_name)
297
+ end
298
+
299
+ traces = get_all_traces
300
+
301
+ traces.count.must_equal 6
302
+ validate_outer_layers(traces, 'cassandra_test')
303
+
304
+ validate_event_keys(traces[1], @entry_kvs)
305
+ traces[1]['Op'].must_equal "add_column_family"
306
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
307
+ validate_event_keys(traces[2], @exit_kvs)
308
+
309
+ traces[3]['Op'].must_equal "drop_column_family"
310
+ traces[3]['Cf'].must_equal cf_name
311
+ traces[3].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
312
+ end
313
+
314
+ it 'should trace adding a keyspace' do
315
+ ks_name = (0...10).map{ ('a'..'z').to_a[rand(26)] }.join
316
+ column_families = [{:name =>"a"}, {:name => "b", :type => :super}]
317
+ ks_def = CassandraThrift::KsDef.new(:name => ks_name,
318
+ :strategy_class => "org.apache.cassandra.locator.SimpleStrategy",
319
+ :strategy_options => { 'replication_factor' => '2' },
320
+ :cf_defs => [])
321
+
322
+ Oboe::API.start_trace('cassandra_test', '', {}) do
323
+ @client.add_keyspace(ks_def)
324
+ @client.keyspace = ks_name
325
+ end
326
+
327
+ traces = get_all_traces
328
+
329
+ traces.count.must_equal 4
330
+ validate_outer_layers(traces, 'cassandra_test')
331
+
332
+ validate_event_keys(traces[1], @entry_kvs)
333
+ traces[1]['Op'].must_equal "add_keyspace"
334
+ traces[1]['Name'].must_equal ks_name
335
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
336
+ validate_event_keys(traces[2], @exit_kvs)
337
+ end
338
+
339
+ it 'should trace the removal of a keyspace' do
340
+ Oboe::API.start_trace('cassandra_test', '', {}) do
341
+ @client.drop_keyspace(@ks_name)
342
+ end
343
+
344
+ traces = get_all_traces
345
+
346
+ traces.count.must_equal 4
347
+ validate_outer_layers(traces, 'cassandra_test')
348
+
349
+ validate_event_keys(traces[1], @entry_kvs)
350
+ traces[1]['Op'].must_equal "drop_keyspace"
351
+ traces[1]['Name'].must_equal @ks_name
352
+ traces[1].has_key?('Backtrace').must_equal Oboe::Config[:cassandra][:collect_backtraces]
353
+ validate_event_keys(traces[2], @exit_kvs)
354
+ end
355
+
356
+ it "should obey :collect_backtraces setting when true" do
357
+ Oboe::Config[:cassandra][:collect_backtraces] = true
358
+
359
+ Oboe::API.start_trace('cassandra_test', '', {}) do
360
+ user = {'screen_name' => 'larry', "blah" => "ok"}
361
+ @client.insert(:Users, '5', user, { :ttl => 600, :consistency => 1})
362
+ end
363
+
364
+ traces = get_all_traces
365
+ layer_has_key(traces, 'cassandra', 'Backtrace')
366
+ end
367
+
368
+ it "should obey :collect_backtraces setting when false" do
369
+ Oboe::Config[:cassandra][:collect_backtraces] = false
370
+
371
+ Oboe::API.start_trace('cassandra_test', '', {}) do
372
+ user = {'screen_name' => 'larry', "blah" => "ok"}
373
+ @client.insert(:Users, '5', user, { :ttl => 600, :consistency => 1})
374
+ end
375
+
376
+ traces = get_all_traces
377
+ layer_doesnt_have_key(traces, 'cassandra', 'Backtrace')
378
+ end
379
+
380
+ end
381
+ end