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,18 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module Inst
6
+ def self.load_instrumentation
7
+ # Load the general instrumentation
8
+ pattern = File.join(File.dirname(__FILE__), 'inst', '*.rb')
9
+ Dir.glob(pattern) do |f|
10
+ begin
11
+ require f
12
+ rescue => e
13
+ Oboe.logger.error "[oboe/loading] Error loading instrumentation file '#{f}' : #{e}"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,98 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'digest/sha1'
5
+
6
+ module Oboe
7
+ module Util
8
+ ##
9
+ # This module is used solely for RUM ID calculation
10
+ #
11
+ module Base64URL
12
+ module_function
13
+
14
+ def encode(bin)
15
+ c = [bin].pack('m0').gsub(/\=+\Z/, '').tr('+/', '-_').rstrip
16
+ m = c.size % 4
17
+ c += '=' * (4 - m) if m != 0
18
+ c
19
+ end
20
+
21
+ def decode(bin)
22
+ m = bin.size % 4
23
+ bin += '=' * (4 - m) if m != 0
24
+ bin.tr('-_', '+/').unpack('m0').first
25
+ end
26
+ end
27
+ end
28
+
29
+ ##
30
+ # This module houses all of the loading functionality for the oboe gem.
31
+ #
32
+ # Note that this does not necessarily _have_ to include initialization routines
33
+ # (although it can).
34
+ #
35
+ # Actual initialization is often separated out as it can be dependent on on the state
36
+ # of the stack boot process. e.g. code requiring that initializers, frameworks or
37
+ # instrumented libraries are already loaded...
38
+ #
39
+ module Loading
40
+ ##
41
+ # Load the TraceView access key (either from system configuration file
42
+ # or environment variable) and calculate internal RUM ID
43
+ #
44
+ def self.load_access_key
45
+ begin
46
+ if ENV.has_key?('TRACEVIEW_CUUID')
47
+ # Preferably get access key from environment (e.g. Heroku)
48
+ Oboe::Config[:access_key] = ENV['TRACEVIEW_CUUID']
49
+ Oboe::Config[:rum_id] = Oboe::Util::Base64URL.encode(Digest::SHA1.digest("RUM" + Oboe::Config[:access_key]))
50
+ else
51
+ # ..else read from system-wide configuration file
52
+ if Oboe::Config.access_key.empty?
53
+ config_file = '/etc/tracelytics.conf'
54
+ return unless File.exists?(config_file)
55
+
56
+ File.open(config_file).each do |line|
57
+ if line =~ /^tracelyzer.access_key=/ or line =~ /^access_key/
58
+ bits = line.split(/=/)
59
+ Oboe::Config[:access_key] = bits[1].strip
60
+ Oboe::Config[:rum_id] = Oboe::Util::Base64URL.encode(Digest::SHA1.digest("RUM" + Oboe::Config[:access_key]))
61
+ break
62
+ end
63
+ end
64
+ end
65
+ end
66
+ rescue StandardError => e
67
+ Oboe.logger.error "Trouble obtaining access_key and rum_id: #{e.inspect}"
68
+ end
69
+ end
70
+
71
+ ##
72
+ # Load the oboe tracing API
73
+ #
74
+ def self.require_api
75
+ pattern = File.join(File.dirname(__FILE__), 'api', '*.rb')
76
+ Dir.glob(pattern) do |f|
77
+ require f
78
+ end
79
+ require 'oboe/api'
80
+
81
+ begin
82
+ Oboe::API.extend_with_tracing
83
+ rescue LoadError => e
84
+ Oboe.logger.fatal "[oboe/error] Couldn't load oboe api."
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ Oboe::Loading.require_api
91
+
92
+ # Auto-start the Reporter unless we running Unicorn on Heroku
93
+ # In that case, we start the reporters after fork
94
+ unless Oboe.heroku? and Oboe.forking_webserver?
95
+ Oboe.logger.debug "[oboe/debug] starting Reporter from oboe gem"
96
+ Oboe::Reporter.start
97
+ end
98
+
@@ -0,0 +1,41 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'logger'
5
+
6
+ module Oboe
7
+ class << self
8
+ attr_accessor :logger
9
+ end
10
+
11
+ class Logger
12
+ # Fatal message
13
+ def fatal(string, exception = nil)
14
+ Oboe.logger.fatal(string) if Oboe.logger
15
+ end
16
+
17
+ # Error message
18
+ def error(msg, exception = nil)
19
+ Oboe.logger.error(string) if Oboe.logger
20
+ end
21
+
22
+ # Warn message
23
+ def warn(msg, exception = nil)
24
+ Oboe.logger.warn(string) if Oboe.logger
25
+ end
26
+
27
+ # Info message
28
+ def info(msg, exception = nil)
29
+ Oboe.logger.info(string) if Oboe.logger
30
+ end
31
+
32
+ # Debug message
33
+ def debug(msg, exception = nil)
34
+ Oboe.logger.debug(string) if Oboe.logger
35
+ end
36
+
37
+ end
38
+ end
39
+
40
+ Oboe.logger = Logger.new(STDERR)
41
+
@@ -0,0 +1,11 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module Ruby
6
+ def self.initialize
7
+ Oboe::Loading.load_access_key
8
+ Oboe::Inst.load_instrumentation
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,129 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module Util
6
+ class << self
7
+ def contextual_name(cls)
8
+ # Attempt to infer a contextual name if not indicated
9
+ #
10
+ # For example:
11
+ # ::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.to_s.split(/::/).last
12
+ # => "AbstractMysqlAdapter"
13
+ #
14
+ begin
15
+ cls.to_s.split(/::/).last
16
+ rescue
17
+ end
18
+ end
19
+
20
+ ##
21
+ # method_alias
22
+ #
23
+ # Centralized utility method to alias a method on an arbitrary
24
+ # class or module.
25
+ #
26
+ def method_alias(cls, method, name=nil)
27
+ name ||= contextual_name(cls)
28
+
29
+ if cls.method_defined? method.to_sym or cls.private_method_defined? method.to_sym
30
+
31
+ # Strip '!' or '?' from method if present
32
+ safe_method_name = method.to_s.chop if method.to_s =~ /\?$|\!$/
33
+ safe_method_name ||= method
34
+
35
+ without_oboe = "#{safe_method_name}_without_oboe"
36
+ with_oboe = "#{safe_method_name}_with_oboe"
37
+
38
+ # Only alias if we haven't done so already
39
+ unless cls.method_defined? without_oboe.to_sym or
40
+ cls.private_method_defined? without_oboe.to_sym
41
+
42
+ cls.class_eval do
43
+ alias_method without_oboe, "#{method}"
44
+ alias_method "#{method}", with_oboe
45
+ end
46
+ end
47
+ else Oboe.logger.warn "[oboe/loading] Couldn't properly instrument #{name}. Partial traces may occur."
48
+ end
49
+ end
50
+
51
+ ##
52
+ # class_method_alias
53
+ #
54
+ # Centralized utility method to alias a class method on an arbitrary
55
+ # class or module
56
+ #
57
+ def class_method_alias(cls, method, name=nil)
58
+ name ||= contextual_name(cls)
59
+
60
+ if cls.singleton_methods.include? method.to_sym
61
+
62
+ # Strip '!' or '?' from method if present
63
+ safe_method_name = method.to_s.chop if method.to_s =~ /\?$|\!$/
64
+ safe_method_name ||= method
65
+
66
+ without_oboe = "#{safe_method_name}_without_oboe"
67
+ with_oboe = "#{safe_method_name}_with_oboe"
68
+
69
+ # Only alias if we haven't done so already
70
+ unless cls.singleton_methods.include? without_oboe.to_sym
71
+ cls.singleton_class.send(:alias_method, without_oboe, "#{method}")
72
+ cls.singleton_class.send(:alias_method, "#{method}", with_oboe)
73
+ end
74
+ else Oboe.logger.warn "[oboe/loading] Couldn't properly instrument #{name}. Partial traces may occur."
75
+ end
76
+ end
77
+
78
+ ##
79
+ # send_extend
80
+ #
81
+ # Centralized utility method to send an extend call for an
82
+ # arbitrary class
83
+ def send_extend(target_cls, cls)
84
+ if defined?(target_cls)
85
+ target_cls.send(:extend, cls)
86
+ end
87
+ end
88
+
89
+ ##
90
+ # send_include
91
+ #
92
+ # Centralized utility method to send a include call for an
93
+ # arbitrary class
94
+ def send_include(target_cls, cls)
95
+ if defined?(target_cls)
96
+ target_cls.send(:include, cls)
97
+ end
98
+ end
99
+
100
+ ##
101
+ # static_asset?
102
+ #
103
+ # Given a path, this method determines whether it is a static asset or not (based
104
+ # solely on filename)
105
+ #
106
+ def static_asset?(path)
107
+ return (path =~ /\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|ttf|woff|svg|less)$/i)
108
+ end
109
+
110
+ ##
111
+ # prettify
112
+ #
113
+ # Even to my surprise, 'prettify' is a real word:
114
+ # transitive v. To make pretty or prettier, especially in a superficial or insubstantial way.
115
+ # from The American Heritage® Dictionary of the English Language, 4th Edition
116
+ #
117
+ # This method makes things 'purty' for reporting.
118
+ def prettify(x)
119
+ if (x.to_s =~ /^#</) == 0
120
+ x.class.to_s
121
+ else
122
+ x.to_s
123
+ end
124
+ end
125
+
126
+ end
127
+ end
128
+ end
129
+
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module Version
6
+ MAJOR = 2
7
+ MINOR = 7
8
+ PATCH = 0
9
+ BUILD = 3
10
+
11
+ STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
12
+ end
13
+ end
@@ -0,0 +1,52 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module XTrace
6
+ class << self
7
+
8
+ ##
9
+ # Oboe::XTrace.valid?
10
+ #
11
+ # Perform basic validation on a potential X-Trace ID
12
+ #
13
+ def valid?(xtrace)
14
+ begin
15
+ # Shouldn't be nil
16
+ return false unless xtrace
17
+
18
+ # The X-Trace ID shouldn't be an initialized empty ID
19
+ return false if (xtrace =~ /^1b0000000/i) == 0
20
+
21
+ # Valid X-Trace IDs have a length of 58 bytes and start with '1b'
22
+ return false unless xtrace.length == 58 and (xtrace =~ /^1b/i) == 0
23
+
24
+ true
25
+ rescue StandardError => e
26
+ Oboe.logger.debug e.message
27
+ Oboe.logger.debug e.backtrace
28
+ false
29
+ end
30
+ end
31
+
32
+ ##
33
+ # Oboe::XTrace.task_id
34
+ #
35
+ # Extract and return the task_id portion of an X-Trace ID
36
+ #
37
+ def task_id(xtrace)
38
+ begin
39
+ return nil unless Oboe::XTrace.valid?(xtrace)
40
+
41
+ xtrace[2..41]
42
+ rescue StandardError => e
43
+ Oboe.logger.debug e.message
44
+ Oboe.logger.debug e.backtrace
45
+ return nil
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+
@@ -0,0 +1,140 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'base'
5
+
6
+ module Oboe
7
+ extend OboeBase
8
+ include Oboe_metal
9
+
10
+ class Reporter
11
+ ##
12
+ # Initialize the Oboe Context, reporter and report the initialization
13
+ #
14
+ def self.start
15
+ return unless Oboe.loaded
16
+
17
+ begin
18
+ Oboe_metal::Context.init()
19
+
20
+ if ENV.has_key?("OBOE_GEM_TEST")
21
+ Oboe.reporter = Oboe::FileReporter.new("/tmp/trace_output.bson")
22
+ else
23
+ Oboe.reporter = Oboe::UdpReporter.new(Oboe::Config[:reporter_host], Oboe::Config[:reporter_port])
24
+ end
25
+
26
+ # Only report __Init from here if we are not instrumenting a framework.
27
+ # Otherwise, frameworks will handle reporting __Init after full initialization
28
+ unless defined?(::Rails) or defined?(::Sinatra) or defined?(::Padrino) or defined?(::Grape)
29
+ Oboe::API.report_init
30
+ end
31
+
32
+ rescue Exception => e
33
+ $stderr.puts e.message
34
+ raise
35
+ end
36
+ end
37
+
38
+ def self.sendReport(evt)
39
+ Oboe.reporter.sendReport(evt)
40
+ end
41
+
42
+ ##
43
+ # clear_all_traces
44
+ #
45
+ # Truncates the trace output file to zero
46
+ #
47
+ def self.clear_all_traces
48
+ File.truncate($trace_file, 0)
49
+ end
50
+
51
+ ##
52
+ # get_all_traces
53
+ #
54
+ # Retrieves all traces written to the trace file
55
+ #
56
+ def self.get_all_traces
57
+ io = File.open($trace_file, "r")
58
+ contents = io.readlines(nil)
59
+
60
+ return contents if contents.empty?
61
+
62
+ s = StringIO.new(contents[0])
63
+
64
+ traces = []
65
+
66
+ until s.eof?
67
+ if ::BSON.respond_to? :read_bson_document
68
+ traces << BSON.read_bson_document(s)
69
+ else
70
+ traces << BSON::Document.from_bson(s)
71
+ end
72
+ end
73
+
74
+ traces
75
+ end
76
+ end
77
+
78
+ class Event
79
+ def self.metadataString(evt)
80
+ evt.metadataString()
81
+ end
82
+ end
83
+
84
+ class << self
85
+ def sample?(opts = {})
86
+ begin
87
+ return false unless Oboe.always?
88
+
89
+ # Assure defaults since SWIG enforces Strings
90
+ layer = opts[:layer] ? opts[:layer].strip : ''
91
+ xtrace = opts[:xtrace] ? opts[:xtrace].strip : ''
92
+ tv_meta = opts['X-TV-Meta'] ? opts['X-TV-Meta'].strip : ''
93
+
94
+ rv = Oboe::Context.sampleRequest(layer, xtrace, tv_meta)
95
+
96
+ # For older liboboe that returns true/false, just return that.
97
+ return rv if [TrueClass, FalseClass].include?(rv.class) or (rv == 0)
98
+
99
+ # liboboe version > 1.3.1 returning a bit masked integer with SampleRate and
100
+ # source embedded
101
+ Oboe.sample_rate = (rv & SAMPLE_RATE_MASK)
102
+ Oboe.sample_source = (rv & SAMPLE_SOURCE_MASK) >> 24
103
+ rescue StandardError => e
104
+ Oboe.logger.debug "[oboe/error] sample? error: #{e.inspect}"
105
+ false
106
+ end
107
+ end
108
+
109
+ def set_tracing_mode(mode)
110
+ return unless Oboe.loaded
111
+
112
+ value = mode.to_sym
113
+
114
+ case value
115
+ when :never
116
+ Oboe::Context.setTracingMode(OBOE_TRACE_NEVER)
117
+
118
+ when :always
119
+ Oboe::Context.setTracingMode(OBOE_TRACE_ALWAYS)
120
+
121
+ when :through
122
+ Oboe::Context.setTracingMode(OBOE_TRACE_THROUGH)
123
+
124
+ else
125
+ Oboe.logger.fatal "[oboe/error] Invalid tracing mode set: #{mode}"
126
+ Oboe::Context.setTracingMode(OBOE_TRACE_THROUGH)
127
+ end
128
+ end
129
+
130
+ def set_sample_rate(rate)
131
+ if Oboe.loaded
132
+ # Update liboboe with the new SampleRate value
133
+ Oboe::Context.setDefaultSampleRate(rate.to_i)
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ Oboe.loaded = true
140
+