traceview 3.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +58 -0
- data/Appraisals +10 -0
- data/CHANGELOG.md +490 -0
- data/CONFIG.md +16 -0
- data/Gemfile +95 -0
- data/LICENSE +199 -0
- data/README.md +380 -0
- data/Rakefile +109 -0
- data/examples/DNT.md +35 -0
- data/examples/carrying_context.rb +225 -0
- data/examples/instrumenting_metal_controller.rb +8 -0
- data/examples/puma_on_heroku_config.rb +17 -0
- data/examples/tracing_async_threads.rb +125 -0
- data/examples/tracing_background_jobs.rb +52 -0
- data/examples/tracing_forked_processes.rb +100 -0
- data/examples/unicorn_on_heroku_config.rb +28 -0
- data/ext/oboe_metal/extconf.rb +61 -0
- data/ext/oboe_metal/noop/noop.c +7 -0
- data/ext/oboe_metal/src/bson/bson.h +221 -0
- data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
- data/ext/oboe_metal/src/oboe.h +275 -0
- data/ext/oboe_metal/src/oboe.hpp +352 -0
- data/ext/oboe_metal/src/oboe_wrap.cxx +3886 -0
- data/ext/oboe_metal/tests/test.rb +11 -0
- data/gemfiles/mongo.gemfile +33 -0
- data/gemfiles/moped.gemfile +33 -0
- data/get_version.rb +5 -0
- data/init.rb +4 -0
- data/lib/joboe_metal.rb +206 -0
- data/lib/oboe.rb +7 -0
- data/lib/oboe/README +2 -0
- data/lib/oboe/backward_compatibility.rb +59 -0
- data/lib/oboe/inst/rack.rb +11 -0
- data/lib/oboe_metal.rb +151 -0
- data/lib/rails/generators/traceview/install_generator.rb +76 -0
- data/lib/rails/generators/traceview/templates/traceview_initializer.rb +159 -0
- data/lib/traceview.rb +62 -0
- data/lib/traceview/api.rb +18 -0
- data/lib/traceview/api/layerinit.rb +51 -0
- data/lib/traceview/api/logging.rb +209 -0
- data/lib/traceview/api/memcache.rb +31 -0
- data/lib/traceview/api/profiling.rb +50 -0
- data/lib/traceview/api/tracing.rb +135 -0
- data/lib/traceview/api/util.rb +121 -0
- data/lib/traceview/base.rb +225 -0
- data/lib/traceview/config.rb +238 -0
- data/lib/traceview/frameworks/grape.rb +97 -0
- data/lib/traceview/frameworks/padrino.rb +64 -0
- data/lib/traceview/frameworks/padrino/templates.rb +58 -0
- data/lib/traceview/frameworks/rails.rb +145 -0
- data/lib/traceview/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
- data/lib/traceview/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
- data/lib/traceview/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
- data/lib/traceview/frameworks/rails/inst/action_controller.rb +216 -0
- data/lib/traceview/frameworks/rails/inst/action_view.rb +56 -0
- data/lib/traceview/frameworks/rails/inst/action_view_2x.rb +54 -0
- data/lib/traceview/frameworks/rails/inst/action_view_30.rb +48 -0
- data/lib/traceview/frameworks/rails/inst/active_record.rb +24 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/utils.rb +117 -0
- data/lib/traceview/frameworks/sinatra.rb +95 -0
- data/lib/traceview/frameworks/sinatra/templates.rb +56 -0
- data/lib/traceview/inst/cassandra.rb +279 -0
- data/lib/traceview/inst/dalli.rb +86 -0
- data/lib/traceview/inst/em-http-request.rb +99 -0
- data/lib/traceview/inst/excon.rb +111 -0
- data/lib/traceview/inst/faraday.rb +73 -0
- data/lib/traceview/inst/http.rb +87 -0
- data/lib/traceview/inst/httpclient.rb +173 -0
- data/lib/traceview/inst/memcache.rb +102 -0
- data/lib/traceview/inst/memcached.rb +94 -0
- data/lib/traceview/inst/mongo.rb +238 -0
- data/lib/traceview/inst/moped.rb +474 -0
- data/lib/traceview/inst/rack.rb +122 -0
- data/lib/traceview/inst/redis.rb +271 -0
- data/lib/traceview/inst/resque.rb +192 -0
- data/lib/traceview/inst/rest-client.rb +38 -0
- data/lib/traceview/inst/sequel.rb +162 -0
- data/lib/traceview/inst/typhoeus.rb +102 -0
- data/lib/traceview/instrumentation.rb +21 -0
- data/lib/traceview/loading.rb +94 -0
- data/lib/traceview/logger.rb +41 -0
- data/lib/traceview/method_profiling.rb +84 -0
- data/lib/traceview/ruby.rb +36 -0
- data/lib/traceview/support.rb +113 -0
- data/lib/traceview/thread_local.rb +26 -0
- data/lib/traceview/util.rb +250 -0
- data/lib/traceview/version.rb +16 -0
- data/lib/traceview/xtrace.rb +90 -0
- data/test/frameworks/apps/grape_nested.rb +30 -0
- data/test/frameworks/apps/grape_simple.rb +24 -0
- data/test/frameworks/apps/padrino_simple.rb +45 -0
- data/test/frameworks/apps/sinatra_simple.rb +24 -0
- data/test/frameworks/grape_test.rb +142 -0
- data/test/frameworks/padrino_test.rb +30 -0
- data/test/frameworks/sinatra_test.rb +30 -0
- data/test/instrumentation/cassandra_test.rb +380 -0
- data/test/instrumentation/dalli_test.rb +171 -0
- data/test/instrumentation/em_http_request_test.rb +86 -0
- data/test/instrumentation/excon_test.rb +207 -0
- data/test/instrumentation/faraday_test.rb +235 -0
- data/test/instrumentation/http_test.rb +140 -0
- data/test/instrumentation/httpclient_test.rb +296 -0
- data/test/instrumentation/memcache_test.rb +251 -0
- data/test/instrumentation/memcached_test.rb +226 -0
- data/test/instrumentation/mongo_test.rb +462 -0
- data/test/instrumentation/moped_test.rb +496 -0
- data/test/instrumentation/rack_test.rb +116 -0
- data/test/instrumentation/redis_hashes_test.rb +265 -0
- data/test/instrumentation/redis_keys_test.rb +318 -0
- data/test/instrumentation/redis_lists_test.rb +310 -0
- data/test/instrumentation/redis_misc_test.rb +160 -0
- data/test/instrumentation/redis_sets_test.rb +293 -0
- data/test/instrumentation/redis_sortedsets_test.rb +325 -0
- data/test/instrumentation/redis_strings_test.rb +333 -0
- data/test/instrumentation/resque_test.rb +62 -0
- data/test/instrumentation/rest-client_test.rb +294 -0
- data/test/instrumentation/sequel_mysql2_test.rb +326 -0
- data/test/instrumentation/sequel_mysql_test.rb +326 -0
- data/test/instrumentation/sequel_pg_test.rb +330 -0
- data/test/instrumentation/typhoeus_test.rb +285 -0
- data/test/minitest_helper.rb +187 -0
- data/test/profiling/method_test.rb +198 -0
- data/test/servers/rackapp_8101.rb +22 -0
- data/test/support/backcompat_test.rb +269 -0
- data/test/support/config_test.rb +128 -0
- data/test/support/dnt_test.rb +73 -0
- data/test/support/liboboe_settings_test.rb +104 -0
- data/test/support/xtrace_test.rb +35 -0
- data/traceview.gemspec +29 -0
- metadata +250 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module TraceView
|
|
5
|
+
##
|
|
6
|
+
# The current version of the gem. Used mainly by
|
|
7
|
+
# traceview.gemspec during gem build process
|
|
8
|
+
module Version
|
|
9
|
+
MAJOR = 3
|
|
10
|
+
MINOR = 0
|
|
11
|
+
PATCH = 0
|
|
12
|
+
BUILD = nil
|
|
13
|
+
|
|
14
|
+
STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module TraceView
|
|
5
|
+
##
|
|
6
|
+
# Methods to act on, manipulate or investigate an X-Trace
|
|
7
|
+
# value
|
|
8
|
+
module XTrace
|
|
9
|
+
class << self
|
|
10
|
+
##
|
|
11
|
+
# TraceView::XTrace.valid?
|
|
12
|
+
#
|
|
13
|
+
# Perform basic validation on a potential X-Trace ID
|
|
14
|
+
#
|
|
15
|
+
def valid?(xtrace)
|
|
16
|
+
# Shouldn't be nil
|
|
17
|
+
return false unless xtrace
|
|
18
|
+
|
|
19
|
+
# The X-Trace ID shouldn't be an initialized empty ID
|
|
20
|
+
return false if (xtrace =~ /^1b0000000/i) == 0
|
|
21
|
+
|
|
22
|
+
# Valid X-Trace IDs have a length of 58 bytes and start with '1b'
|
|
23
|
+
return false unless xtrace.length == 58 && (xtrace =~ /^1b/i) == 0
|
|
24
|
+
|
|
25
|
+
true
|
|
26
|
+
rescue StandardError => e
|
|
27
|
+
TraceView.logger.debug e.message
|
|
28
|
+
TraceView.logger.debug e.backtrace
|
|
29
|
+
false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# TraceView::XTrace.task_id
|
|
34
|
+
#
|
|
35
|
+
# Extract and return the task_id portion of an X-Trace ID
|
|
36
|
+
#
|
|
37
|
+
def task_id(xtrace)
|
|
38
|
+
return nil unless TraceView::XTrace.valid?(xtrace)
|
|
39
|
+
|
|
40
|
+
xtrace[2..41]
|
|
41
|
+
rescue StandardError => e
|
|
42
|
+
TraceView.logger.debug e.message
|
|
43
|
+
TraceView.logger.debug e.backtrace
|
|
44
|
+
return nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# TraceView::XTrace.edge_id
|
|
49
|
+
#
|
|
50
|
+
# Extract and return the edge_id portion of an X-Trace ID
|
|
51
|
+
#
|
|
52
|
+
def edge_id(xtrace)
|
|
53
|
+
return nil unless TraceView::XTrace.valid?(xtrace)
|
|
54
|
+
|
|
55
|
+
xtrace[42..57]
|
|
56
|
+
rescue StandardError => e
|
|
57
|
+
TraceView.logger.debug e.message
|
|
58
|
+
TraceView.logger.debug e.backtrace
|
|
59
|
+
return nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
##
|
|
63
|
+
# continue_service_context
|
|
64
|
+
#
|
|
65
|
+
# In the case of service calls such as external HTTP requests, we
|
|
66
|
+
# pass along X-Trace headers so that request context can be maintained
|
|
67
|
+
# across servers and applications.
|
|
68
|
+
#
|
|
69
|
+
# Remote requests can return a X-Trace header in which case we want
|
|
70
|
+
# to pickup on and continue the context in most cases.
|
|
71
|
+
#
|
|
72
|
+
# @start is the context just before the outgoing request
|
|
73
|
+
#
|
|
74
|
+
# @finish is the context returned to us (as an HTTP response header
|
|
75
|
+
# if that be the case)
|
|
76
|
+
#
|
|
77
|
+
def continue_service_context(start, finish)
|
|
78
|
+
if TraceView::XTrace.valid?(finish) && TraceView.tracing?
|
|
79
|
+
|
|
80
|
+
# Assure that we received back a valid X-Trace with the same task_id
|
|
81
|
+
if TraceView::XTrace.task_id(start) == TraceView::XTrace.task_id(finish)
|
|
82
|
+
TraceView::Context.fromString(finish)
|
|
83
|
+
else
|
|
84
|
+
TraceView.logger.debug "Mismatched returned X-Trace ID: #{finish}"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'grape'
|
|
2
|
+
|
|
3
|
+
class Wrapper < Grape::API
|
|
4
|
+
class GrapeSimple < Grape::API
|
|
5
|
+
rescue_from :all do |e|
|
|
6
|
+
error_response({ message: "rescued from #{e.class.name}" })
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
get '/json_endpoint' do
|
|
10
|
+
present({ :test => true })
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
get "/break" do
|
|
14
|
+
raise Exception.new("This should have http status code 500!")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
get "/error" do
|
|
18
|
+
error!("This is a error with 'error'!")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
get "/breakstring" do
|
|
22
|
+
raise "This should have http status code 500!"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class GrapeNested < Grape::API
|
|
28
|
+
mount Wrapper::GrapeSimple
|
|
29
|
+
end
|
|
30
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'grape'
|
|
2
|
+
|
|
3
|
+
class GrapeSimple < Grape::API
|
|
4
|
+
rescue_from :all do |e|
|
|
5
|
+
error_response({ message: "rescued from #{e.class.name}" })
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
get '/json_endpoint' do
|
|
9
|
+
present({ :test => true })
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
get "/break" do
|
|
13
|
+
raise Exception.new("This should have http status code 500!")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
get "/error" do
|
|
17
|
+
error!("This is a error with 'error'!")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
get "/breakstring" do
|
|
21
|
+
raise "This should have http status code 500!"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
|
|
31
|
+
get "/break" do
|
|
32
|
+
raise "This is a controller exception!"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
## If you want use this as a standalone app uncomment:
|
|
37
|
+
#
|
|
38
|
+
# Padrino.mount("SimpleDemo").to("/")
|
|
39
|
+
# Padrino.run! unless Padrino.loaded? # If you enable reloader prevent to re-run the app
|
|
40
|
+
#
|
|
41
|
+
# Then run it from your console: ruby -I"lib" test/fixtures/apps/simple.rb
|
|
42
|
+
#
|
|
43
|
+
|
|
44
|
+
Padrino.load!
|
|
45
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
|
|
18
|
+
get "/break" do
|
|
19
|
+
raise "This is a controller exception!"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
use SinatraSimple
|
|
24
|
+
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
if RUBY_VERSION >= '1.9.3'
|
|
2
|
+
require 'minitest_helper'
|
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/apps/grape_simple')
|
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/apps/grape_nested')
|
|
5
|
+
|
|
6
|
+
describe Grape do
|
|
7
|
+
before do
|
|
8
|
+
clear_all_traces
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should trace a request to a simple grape stack" do
|
|
12
|
+
@app = GrapeSimple
|
|
13
|
+
|
|
14
|
+
r = get "/json_endpoint"
|
|
15
|
+
|
|
16
|
+
r.status.must_equal 200
|
|
17
|
+
r.headers.key?('X-Trace').must_equal true
|
|
18
|
+
|
|
19
|
+
traces = get_all_traces
|
|
20
|
+
traces.count.must_equal 5
|
|
21
|
+
|
|
22
|
+
validate_outer_layers(traces, 'rack')
|
|
23
|
+
|
|
24
|
+
traces[2]['Layer'].must_equal "grape"
|
|
25
|
+
traces[3]['Layer'].must_equal "grape"
|
|
26
|
+
traces[3].has_key?('Controller').must_equal true
|
|
27
|
+
traces[3].has_key?('Action').must_equal true
|
|
28
|
+
traces[4]['Label'].must_equal "exit"
|
|
29
|
+
|
|
30
|
+
# Validate the existence of the response header
|
|
31
|
+
r.headers.key?('X-Trace').must_equal true
|
|
32
|
+
r.headers['X-Trace'].must_equal traces[4]['X-Trace']
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should trace a request to a nested grape stack" do
|
|
36
|
+
@app = GrapeNested
|
|
37
|
+
|
|
38
|
+
r = get "/json_endpoint"
|
|
39
|
+
|
|
40
|
+
r.status.must_equal 200
|
|
41
|
+
r.headers.key?('X-Trace').must_equal true
|
|
42
|
+
|
|
43
|
+
traces = get_all_traces
|
|
44
|
+
traces.count.must_equal 5
|
|
45
|
+
|
|
46
|
+
validate_outer_layers(traces, 'rack')
|
|
47
|
+
|
|
48
|
+
traces[2]['Layer'].must_equal "grape"
|
|
49
|
+
traces[3]['Layer'].must_equal "grape"
|
|
50
|
+
traces[3].has_key?('Controller').must_equal true
|
|
51
|
+
traces[3].has_key?('Action').must_equal true
|
|
52
|
+
traces[4]['Label'].must_equal "exit"
|
|
53
|
+
|
|
54
|
+
# Validate the existence of the response header
|
|
55
|
+
r.headers.key?('X-Trace').must_equal true
|
|
56
|
+
r.headers['X-Trace'].must_equal traces[4]['X-Trace']
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should trace a an error in a nested grape stack" do
|
|
60
|
+
@app = GrapeNested
|
|
61
|
+
|
|
62
|
+
r = get "/error"
|
|
63
|
+
|
|
64
|
+
r.status.must_equal 500
|
|
65
|
+
r.headers.key?('X-Trace').must_equal true
|
|
66
|
+
|
|
67
|
+
traces = get_all_traces
|
|
68
|
+
traces.count.must_equal 6
|
|
69
|
+
|
|
70
|
+
validate_outer_layers(traces, 'rack')
|
|
71
|
+
|
|
72
|
+
traces[2]['Layer'].must_equal "grape"
|
|
73
|
+
traces[2]['Label'].must_equal "entry"
|
|
74
|
+
traces[3]['Layer'].must_equal "grape"
|
|
75
|
+
traces[3]['Label'].must_equal "exit"
|
|
76
|
+
traces[3].has_key?('Controller').must_equal true
|
|
77
|
+
traces[3].has_key?('Action').must_equal true
|
|
78
|
+
traces[4]['Label'].must_equal "error"
|
|
79
|
+
traces[4]['ErrorClass'].must_equal "GrapeError"
|
|
80
|
+
traces[4]['ErrorMsg'].must_equal "This is a error with 'error'!"
|
|
81
|
+
traces[4].has_key?('Backtrace').must_equal true
|
|
82
|
+
traces[5]['Layer'].must_equal "rack"
|
|
83
|
+
traces[5]['Label'].must_equal "exit"
|
|
84
|
+
|
|
85
|
+
# Validate the existence of the response header
|
|
86
|
+
r.headers.key?('X-Trace').must_equal true
|
|
87
|
+
r.headers['X-Trace'].must_equal traces[5]['X-Trace']
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
it "should trace a request with an exception" do
|
|
92
|
+
@app = GrapeSimple
|
|
93
|
+
|
|
94
|
+
begin
|
|
95
|
+
r = get "/break"
|
|
96
|
+
rescue Exception => e
|
|
97
|
+
# Do not handle/raise this error so
|
|
98
|
+
# we can continue to test
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
traces = get_all_traces
|
|
102
|
+
traces.count.must_equal 6
|
|
103
|
+
|
|
104
|
+
validate_outer_layers(traces, 'rack')
|
|
105
|
+
|
|
106
|
+
traces[2]['Layer'].must_equal "grape"
|
|
107
|
+
traces[3]['Layer'].must_equal "grape"
|
|
108
|
+
traces[3].has_key?('Controller').must_equal true
|
|
109
|
+
traces[3].has_key?('Action').must_equal true
|
|
110
|
+
traces[4]['Label'].must_equal "error"
|
|
111
|
+
traces[4]['ErrorClass'].must_equal "Exception"
|
|
112
|
+
traces[4]['ErrorMsg'].must_equal "This should have http status code 500!"
|
|
113
|
+
traces[5]['Label'].must_equal "exit"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "should trace a request with an error" do
|
|
117
|
+
@app = GrapeSimple
|
|
118
|
+
|
|
119
|
+
r = get "/error"
|
|
120
|
+
|
|
121
|
+
traces = get_all_traces
|
|
122
|
+
traces.count.must_equal 6
|
|
123
|
+
|
|
124
|
+
r.status.must_equal 500
|
|
125
|
+
r.headers.key?('X-Trace').must_equal true
|
|
126
|
+
|
|
127
|
+
validate_outer_layers(traces, 'rack')
|
|
128
|
+
|
|
129
|
+
traces[0]['Layer'].must_equal "rack"
|
|
130
|
+
traces[2]['Layer'].must_equal "grape"
|
|
131
|
+
traces[3]['Layer'].must_equal "grape"
|
|
132
|
+
traces[3].has_key?('Controller').must_equal true
|
|
133
|
+
traces[3].has_key?('Action').must_equal true
|
|
134
|
+
traces[4]['Label'].must_equal "error"
|
|
135
|
+
traces[4]['ErrorClass'].must_equal "GrapeError"
|
|
136
|
+
traces[4]['ErrorMsg'].must_equal "This is a error with 'error'!"
|
|
137
|
+
traces[5]['Layer'].must_equal "rack"
|
|
138
|
+
traces[5]['Label'].must_equal "exit"
|
|
139
|
+
traces[5]['Status'].must_equal 500
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
|
|
17
|
+
traces.count.must_equal 9
|
|
18
|
+
valid_edges?(traces).must_equal true
|
|
19
|
+
validate_outer_layers(traces, 'rack')
|
|
20
|
+
|
|
21
|
+
traces[2]['Layer'].must_equal "padrino"
|
|
22
|
+
traces[7]['Controller'].must_equal "SimpleDemo"
|
|
23
|
+
traces[8]['Label'].must_equal "exit"
|
|
24
|
+
|
|
25
|
+
# Validate the existence of the response header
|
|
26
|
+
r.headers.key?('X-Trace').must_equal true
|
|
27
|
+
r.headers['X-Trace'].must_equal traces[8]['X-Trace']
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
|
|
16
|
+
traces.count.must_equal 9
|
|
17
|
+
valid_edges?(traces).must_equal true
|
|
18
|
+
validate_outer_layers(traces, 'rack')
|
|
19
|
+
|
|
20
|
+
traces[2]['Layer'].must_equal "sinatra"
|
|
21
|
+
traces[4]['Label'].must_equal "profile_entry"
|
|
22
|
+
traces[7]['Controller'].must_equal "SinatraSimple"
|
|
23
|
+
traces[8]['Label'].must_equal "exit"
|
|
24
|
+
|
|
25
|
+
# Validate the existence of the response header
|
|
26
|
+
r.headers.key?('X-Trace').must_equal true
|
|
27
|
+
r.headers['X-Trace'].must_equal traces[8]['X-Trace']
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
@@ -0,0 +1,380 @@
|
|
|
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 "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 = TraceView::Config[:cassandra][:collect_backtraces]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
after do
|
|
45
|
+
TraceView::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 traceview 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_traceview").must_equal true
|
|
59
|
+
end
|
|
60
|
+
# Special 'exists?' case
|
|
61
|
+
::Cassandra.method_defined?("exists_with_traceview?").must_equal true
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'should trace insert' do
|
|
65
|
+
TraceView::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 TraceView::Config[:cassandra][:collect_backtraces]
|
|
82
|
+
validate_event_keys(traces[2], @exit_kvs)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'should trace remove' do
|
|
86
|
+
TraceView::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 TraceView::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
|
+
TraceView::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 TraceView::Config[:cassandra][:collect_backtraces]
|
|
121
|
+
validate_event_keys(traces[2], @exit_kvs)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'should trace get_columns' do
|
|
125
|
+
TraceView::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 TraceView::Config[:cassandra][:collect_backtraces]
|
|
139
|
+
validate_event_keys(traces[2], @exit_kvs)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it 'should trace multi_get_columns' do
|
|
143
|
+
TraceView::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 TraceView::Config[:cassandra][:collect_backtraces]
|
|
157
|
+
validate_event_keys(traces[2], @exit_kvs)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it 'should trace get' do
|
|
161
|
+
TraceView::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 TraceView::Config[:cassandra][:collect_backtraces]
|
|
176
|
+
validate_event_keys(traces[2], @exit_kvs)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it 'should trace exists?' do
|
|
180
|
+
TraceView::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 TraceView::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 TraceView::Config[:cassandra][:collect_backtraces]
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it 'should trace get_range_keys' do
|
|
204
|
+
TraceView::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 TraceView::Config[:cassandra][:collect_backtraces]
|
|
217
|
+
validate_event_keys(traces[2], @exit_kvs)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
it 'should trace create_index' do
|
|
221
|
+
TraceView::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 TraceView::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
|
+
TraceView::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 TraceView::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
|
+
TraceView::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 TraceView::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
|
+
TraceView::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 TraceView::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 TraceView::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
|
+
ks_def = CassandraThrift::KsDef.new(:name => ks_name,
|
|
317
|
+
:strategy_class => "org.apache.cassandra.locator.SimpleStrategy",
|
|
318
|
+
:strategy_options => { 'replication_factor' => '2' },
|
|
319
|
+
:cf_defs => [])
|
|
320
|
+
|
|
321
|
+
TraceView::API.start_trace('cassandra_test', '', {}) do
|
|
322
|
+
@client.add_keyspace(ks_def)
|
|
323
|
+
@client.keyspace = ks_name
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
traces = get_all_traces
|
|
327
|
+
|
|
328
|
+
traces.count.must_equal 4
|
|
329
|
+
validate_outer_layers(traces, 'cassandra_test')
|
|
330
|
+
|
|
331
|
+
validate_event_keys(traces[1], @entry_kvs)
|
|
332
|
+
traces[1]['Op'].must_equal "add_keyspace"
|
|
333
|
+
traces[1]['Name'].must_equal ks_name
|
|
334
|
+
traces[1].has_key?('Backtrace').must_equal TraceView::Config[:cassandra][:collect_backtraces]
|
|
335
|
+
validate_event_keys(traces[2], @exit_kvs)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
it 'should trace the removal of a keyspace' do
|
|
339
|
+
TraceView::API.start_trace('cassandra_test', '', {}) do
|
|
340
|
+
@client.drop_keyspace(@ks_name)
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
traces = get_all_traces
|
|
344
|
+
|
|
345
|
+
traces.count.must_equal 4
|
|
346
|
+
validate_outer_layers(traces, 'cassandra_test')
|
|
347
|
+
|
|
348
|
+
validate_event_keys(traces[1], @entry_kvs)
|
|
349
|
+
traces[1]['Op'].must_equal "drop_keyspace"
|
|
350
|
+
traces[1]['Name'].must_equal @ks_name
|
|
351
|
+
traces[1].has_key?('Backtrace').must_equal TraceView::Config[:cassandra][:collect_backtraces]
|
|
352
|
+
validate_event_keys(traces[2], @exit_kvs)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
it "should obey :collect_backtraces setting when true" do
|
|
356
|
+
TraceView::Config[:cassandra][:collect_backtraces] = true
|
|
357
|
+
|
|
358
|
+
TraceView::API.start_trace('cassandra_test', '', {}) do
|
|
359
|
+
user = {'screen_name' => 'larry', "blah" => "ok"}
|
|
360
|
+
@client.insert(:Users, '5', user, { :ttl => 600, :consistency => 1})
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
traces = get_all_traces
|
|
364
|
+
layer_has_key(traces, 'cassandra', 'Backtrace')
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
it "should obey :collect_backtraces setting when false" do
|
|
368
|
+
TraceView::Config[:cassandra][:collect_backtraces] = false
|
|
369
|
+
|
|
370
|
+
TraceView::API.start_trace('cassandra_test', '', {}) do
|
|
371
|
+
user = {'screen_name' => 'larry', "blah" => "ok"}
|
|
372
|
+
@client.insert(:Users, '5', user, { :ttl => 600, :consistency => 1})
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
traces = get_all_traces
|
|
376
|
+
layer_doesnt_have_key(traces, 'cassandra', 'Backtrace')
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
end
|
|
380
|
+
end
|