oboe 2.7.0.3-java

Sign up to get free protection for your applications and to get access to all the features.
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