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,11 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'oboe'
5
+
6
+ r = Oboe::UdpReporter.new('127.0.0.1')
7
+ Oboe::Context.init()
8
+ e = Oboe::Context.createEvent()
9
+ e.addInfo("TestKey", "TestValue")
10
+ r.sendReport(e)
11
+
@@ -0,0 +1,33 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "dalli"
6
+ gem "memcache-client"
7
+ gem "memcached", "1.7.2"
8
+ gem "cassandra"
9
+ gem "mongo"
10
+ gem "bson"
11
+ gem "moped", "~> 1.5"
12
+ gem "resque"
13
+ gem "redis"
14
+ gem "sinatra"
15
+ gem "padrino", "0.12.0"
16
+ gem "grape"
17
+
18
+ group :development, :test do
19
+ gem "minitest"
20
+ gem "minitest-reporters"
21
+ gem "rack-test"
22
+ gem "appraisal"
23
+ end
24
+
25
+ group :development do
26
+ gem "ruby-debug", :platform => :mri_18
27
+ gem "debugger", :platform => :mri_19
28
+ gem "byebug", :platforms => [:mri_20, :mri_21]
29
+ gem "perftools.rb", :platforms => [:mri_20, :mri_21], :require => "perftools"
30
+ gem "pry"
31
+ end
32
+
33
+ gemspec :name => "oboe", :path => "../"
@@ -0,0 +1,33 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "dalli"
6
+ gem "memcache-client"
7
+ gem "memcached", "1.7.2"
8
+ gem "cassandra"
9
+ gem "mongo"
10
+ gem "bson"
11
+ gem "moped", "~> 1.5"
12
+ gem "resque"
13
+ gem "redis"
14
+ gem "sinatra"
15
+ gem "padrino", "0.12.0"
16
+ gem "grape"
17
+
18
+ group :development, :test do
19
+ gem "minitest"
20
+ gem "minitest-reporters"
21
+ gem "rack-test"
22
+ gem "appraisal"
23
+ end
24
+
25
+ group :development do
26
+ gem "ruby-debug", :platform => :mri_18
27
+ gem "debugger", :platform => :mri_19
28
+ gem "byebug", :platforms => [:mri_20, :mri_21]
29
+ gem "perftools.rb", :platforms => [:mri_20, :mri_21], :require => "perftools"
30
+ gem "pry"
31
+ end
32
+
33
+ gemspec :name => "oboe", :path => "../"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/lib/oboe/version.rb'
4
+
5
+ puts Oboe::Version::STRING
data/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'oboe'
@@ -0,0 +1,99 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ # Constants from liboboe
5
+ OBOE_TRACE_NEVER = 0
6
+ OBOE_TRACE_ALWAYS = 1
7
+ OBOE_TRACE_THROUGH = 2
8
+
9
+ OBOE_SAMPLE_RATE_SOURCE_FILE = 1
10
+ OBOE_SAMPLE_RATE_SOURCE_DEFAULT = 2
11
+ OBOE_SAMPLE_RATE_SOURCE_OBOE = 3
12
+ OBOE_SAMPLE_RATE_SOURCE_LAST_OBOE = 4
13
+ OBOE_SAMPLE_RATE_SOURCE_DEFAULT_MISCONFIGURED = 5
14
+ OBOE_SAMPLE_RATE_SOURCE_OBOE_DEFAULT = 6
15
+
16
+ # Masks for bitwise ops
17
+ ZERO_MASK = 0b0000000000000000000000000000
18
+
19
+ SAMPLE_RATE_MASK = 0b0000111111111111111111111111
20
+ SAMPLE_SOURCE_MASK = 0b1111000000000000000000000000
21
+
22
+ ZERO_SAMPLE_RATE_MASK = 0b1111000000000000000000000000
23
+ ZERO_SAMPLE_SOURCE_MASK = 0b0000111111111111111111111111
24
+
25
+ module OboeBase
26
+ attr_accessor :reporter
27
+ attr_accessor :loaded
28
+ attr_accessor :sample_source
29
+ attr_accessor :sample_rate
30
+ attr_accessor :layer_op
31
+
32
+ def self.included(cls)
33
+ self.loaded = true
34
+ end
35
+
36
+ def tracing_layer_op?(operation)
37
+ if operation.is_a?(Array)
38
+ return operation.include?(@layer_op)
39
+ else
40
+ return @layer_op == operation
41
+ end
42
+ end
43
+
44
+ def always?
45
+ Oboe::Config[:tracing_mode].to_s == "always"
46
+ end
47
+
48
+ def never?
49
+ Oboe::Config[:tracing_mode].to_s == "never"
50
+ end
51
+
52
+ def passthrough?
53
+ ["always", "through"].include?(Oboe::Config[:tracing_mode])
54
+ end
55
+
56
+ def through?
57
+ Oboe::Config[:tracing_mode] == "through"
58
+ end
59
+
60
+ def tracing?
61
+ return false unless Oboe.loaded
62
+
63
+ Oboe::Context.isValid and not Oboe.never?
64
+ end
65
+
66
+ def log(layer, label, options = {})
67
+ # WARN: Oboe.log will be deprecated in a future release. Please use Oboe::API.log instead.
68
+ Oboe::API.log(layer, label, options)
69
+ end
70
+
71
+ def heroku?
72
+ false
73
+ end
74
+
75
+ def forking_webserver?
76
+ (defined?(::Unicorn) and ($0 =~ /unicorn/i)) ? true : false
77
+ end
78
+
79
+ ##
80
+ # These methods should be implemented by the descendants
81
+ # (Oboe_metal, Oboe_metal (JRuby), Heroku_metal)
82
+ #
83
+ def sample?(opts = {})
84
+ raise "sample? should be implemented by metal layer."
85
+ end
86
+
87
+ def log(layer, label, options = {})
88
+ raise "log should be implemented by metal layer."
89
+ end
90
+
91
+ def set_tracing_mode(mode)
92
+ raise "set_tracing_mode should be implemented by metal layer."
93
+ end
94
+
95
+ def set_sample_rate(rate)
96
+ raise "set_sample_rate should be implemented by metal layer."
97
+ end
98
+ end
99
+
@@ -0,0 +1,185 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'base'
5
+
6
+ module Oboe_metal
7
+ include_package 'com.tracelytics.joboe'
8
+ java_import 'com.tracelytics.joboe.LayerUtil'
9
+ java_import 'com.tracelytics.joboe.SettingsReader'
10
+ java_import 'com.tracelytics.joboe.Context'
11
+ java_import 'com.tracelytics.joboe.Event'
12
+ java_import 'com.tracelytics.agent.Agent'
13
+
14
+ class Context
15
+ class << self
16
+ def toString
17
+ md = getMetadata.toHexString
18
+ end
19
+
20
+ def fromString(xtrace)
21
+ Context.setMetadata(xtrace)
22
+ end
23
+
24
+ def clear
25
+ clearMetadata
26
+ end
27
+
28
+ def get
29
+ getMetadata
30
+ end
31
+ end
32
+ end
33
+
34
+ class Event
35
+ def self.metadataString(evt)
36
+ evt.getMetadata.toHexString
37
+ end
38
+ end
39
+
40
+ def UdpReporter
41
+ Java::ComTracelyticsJoboe
42
+ end
43
+
44
+ module Metadata
45
+ Java::ComTracelyticsJoboeMetaData
46
+ end
47
+
48
+ module Reporter
49
+ ##
50
+ # Initialize the Oboe Context, reporter and report the initialization
51
+ #
52
+ def self.start
53
+ begin
54
+ return unless Oboe.loaded
55
+
56
+ if ENV.has_key?("OBOE_GEM_TEST")
57
+ Oboe.reporter = Java::ComTracelyticsJoboe::TestReporter.new
58
+ else
59
+ Oboe.reporter = Java::ComTracelyticsJoboe::ReporterFactory.getInstance().buildUdpReporter()
60
+ end
61
+
62
+
63
+ # Import the tracing mode and sample rate settings
64
+ # from the Java agent (user configured in
65
+ # /usr/local/tracelytics/javaagent.json when under JRuby)
66
+ cfg = LayerUtil.getLocalSampleRate(nil, nil)
67
+
68
+ if cfg.hasSampleStartFlag
69
+ Oboe::Config.tracing_mode = 'always'
70
+ elsif cfg.hasSampleThroughFlag
71
+ Oboe::Config.tracing_mode = 'through'
72
+ else
73
+ Oboe::Config.tracing_mode = 'never'
74
+ end
75
+
76
+ Oboe.sample_rate = cfg.sampleRate
77
+ Oboe::Config.sample_rate = cfg.sampleRate
78
+ Oboe::Config.sample_source = cfg.sampleRateSource.a
79
+
80
+ # Only report __Init from here if we are not instrumenting a framework.
81
+ # Otherwise, frameworks will handle reporting __Init after full initialization
82
+ unless defined?(::Rails) or defined?(::Sinatra) or defined?(::Padrino) or defined?(::Grape)
83
+ Oboe::API.report_init
84
+ end
85
+
86
+ rescue Exception => e
87
+ $stderr.puts e.message
88
+ raise
89
+ end
90
+ end
91
+
92
+ ##
93
+ # clear_all_traces
94
+ #
95
+ # Truncates the trace output file to zero
96
+ #
97
+ def self.clear_all_traces
98
+ Oboe.reporter.reset if Oboe.loaded
99
+ end
100
+
101
+ ##
102
+ # get_all_traces
103
+ #
104
+ # Retrieves all traces written to the trace file
105
+ #
106
+ def self.get_all_traces
107
+ return [] unless Oboe.loaded
108
+
109
+ # Joboe TestReporter returns a Java::ComTracelyticsExtEbson::DefaultDocument
110
+ # document for traces which doesn't correctly support things like has_key? which
111
+ # raises an unhandled exception on non-existent key (duh). Here we convert
112
+ # the Java::ComTracelyticsExtEbson::DefaultDocument doc to a pure array of Ruby
113
+ # hashes
114
+ traces = []
115
+ Oboe.reporter.getSentEventsAsBsonDocument.to_a.each do |e|
116
+ t = {}
117
+ e.each_pair { |k,v|
118
+ t[k] = v
119
+ }
120
+ traces << t
121
+ end
122
+ traces
123
+ end
124
+
125
+ def self.sendReport(evt)
126
+ evt.report(Oboe.reporter)
127
+ end
128
+ end
129
+ end
130
+
131
+ module Oboe
132
+ extend OboeBase
133
+ include Oboe_metal
134
+
135
+ class << self
136
+ def sample?(opts = {})
137
+ begin
138
+ return false unless Oboe.always? and Oboe.loaded
139
+
140
+ return true if ENV['OBOE_GEM_TEST'] == "test"
141
+
142
+ # Validation to make Joboe happy. Assure that we have the KVs and that they
143
+ # are not empty strings.
144
+ opts[:layer] = nil if opts[:layer].is_a?(String) and opts[:layer].empty?
145
+ opts[:xtrace] = nil if opts[:xtrace].is_a?(String) and opts[:xtrace].empty?
146
+ opts['X-TV-Meta'] = nil if opts['X-TV-Meta'].is_a?(String) and opts['X-TV-Meta'].empty?
147
+
148
+ opts[:layer] ||= nil
149
+ opts[:xtrace] ||= nil
150
+ opts['X-TV-Meta'] ||= nil
151
+
152
+ sr_cfg = Java::ComTracelyticsJoboe::LayerUtil.shouldTraceRequest( opts[:layer],
153
+ { 'X-Trace' => opts[:xtrace], 'X-TV-Meta' => opts['X-TV-Meta'] } )
154
+
155
+ # Store the returned SampleRateConfig into Oboe::Config
156
+ if sr_cfg
157
+ Oboe.sample_rate = sr_cfg.sampleRate
158
+ Oboe.sample_source = sr_cfg.sampleRateSource.a
159
+ end
160
+
161
+ sr_cfg
162
+ rescue => e
163
+ Oboe.logger.debug "[oboe/debug] #{e.message}"
164
+ false
165
+ end
166
+ end
167
+
168
+ def set_tracing_mode(mode)
169
+ Oboe.logger.warn "When using JRuby set the tracing mode in /usr/local/tracelytics/javaagent.json instead"
170
+ end
171
+
172
+ def set_sample_rate(rate)
173
+ # N/A
174
+ end
175
+ end
176
+ end
177
+
178
+ # Assure that the Joboe Java Agent was loaded via premain
179
+ status = Java::ComTracelyticsAgent::Agent.getStatus
180
+ if status == Java::ComTracelyticsAgent::Agent::AgentStatus::UNINITIALIZED
181
+ Oboe.loaded = false
182
+ else
183
+ Oboe.loaded = true
184
+ end
185
+
@@ -0,0 +1,70 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module OboeMethodProfiling
5
+ def self.included klass
6
+ klass.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def profile_method(method_name, profile_name, store_args=false, store_return=false, profile=false)
11
+ begin
12
+ # this only gets file and line where profiling is turned on, presumably
13
+ # right after the function definition. ruby 1.9 and 2.0 has nice introspection (Method.source_location)
14
+ # but its appears no such luck for ruby 1.8
15
+ version = RbConfig::CONFIG['ruby_version']
16
+ file = ''
17
+ line = ''
18
+ if version and (version.match(/^1.9/) or version.match(/^2.0/))
19
+ info = self.instance_method(method_name).source_location
20
+ if !info.nil?
21
+ file = info[0].to_s
22
+ line = info[1].to_s
23
+ end
24
+ else
25
+ info = Kernel.caller[0].split(':')
26
+ file = info.first.to_s
27
+ line = info.last.to_s
28
+ end
29
+
30
+ # Safety: Make sure there are no quotes or double quotes to break the class_eval
31
+ file = file.gsub /[\'\"]/, ''
32
+ line = line.gsub /[\'\"]/, ''
33
+
34
+ # profiling via ruby-prof, is it possible to get return value of profiled code?
35
+ code = "def _oboe_profiled_#{method_name}(*args, &block)
36
+ entry_kvs = {}
37
+ entry_kvs['Language'] = 'ruby'
38
+ entry_kvs['ProfileName'] = '#{Oboe::Util.prettify(profile_name)}'
39
+ entry_kvs['FunctionName'] = '#{Oboe::Util.prettify(method_name)}'
40
+ entry_kvs['File'] = '#{file}'
41
+ entry_kvs['LineNumber'] = '#{line}'
42
+ entry_kvs['Args'] = Oboe::API.pps(*args) if #{store_args}
43
+ entry_kvs.merge!(::Oboe::API.get_class_name(self))
44
+
45
+ Oboe::API.log(nil, 'profile_entry', entry_kvs)
46
+
47
+ ret = _oboe_orig_#{method_name}(*args, &block)
48
+
49
+ exit_kvs = {}
50
+ exit_kvs['Language'] = 'ruby'
51
+ exit_kvs['ProfileName'] = '#{Oboe::Util.prettify(profile_name)}'
52
+ exit_kvs['ReturnValue'] = Oboe::API.pps(ret) if #{store_return}
53
+
54
+ Oboe::API.log(nil, 'profile_exit', exit_kvs)
55
+ ret
56
+ end"
57
+ rescue Exception => e
58
+ Oboe.logger.warn "[oboe/warn] profile_method: #{e.inspect}"
59
+ end
60
+
61
+ begin
62
+ class_eval code, __FILE__, __LINE__
63
+ alias_method "_oboe_orig_#{method_name}", method_name
64
+ alias_method method_name, "_oboe_profiled_#{method_name}"
65
+ rescue Exception => e
66
+ Oboe.logger.warn "[oboe/warn] Fatal error profiling method (#{method_name}): #{e.inspect}" if Oboe::Config[:verbose]
67
+ end
68
+ end
69
+ end
70
+ end