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,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
+