oboe 1.3.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.
- data/LICENSE +4 -0
- data/ext/oboe_metal/extconf.rb +20 -0
- data/ext/oboe_metal/noop/noop.c +7 -0
- data/ext/oboe_metal/src/oboe.hpp +256 -0
- data/ext/oboe_metal/src/oboe_wrap.cxx +3599 -0
- data/init.rb +4 -0
- data/install.rb +1 -0
- data/lib/oboe.rb +13 -0
- data/lib/oboe/api.rb +20 -0
- data/lib/oboe/api/layerinit.rb +37 -0
- data/lib/oboe/api/logging.rb +145 -0
- data/lib/oboe/api/memcache.rb +29 -0
- data/lib/oboe/api/tracing.rb +146 -0
- data/lib/oboe/api/util.rb +37 -0
- data/lib/oboe/config.rb +39 -0
- data/lib/oboe/frameworks/rails/inst/action_controller.rb +86 -0
- data/lib/oboe/frameworks/rails/inst/active_record.rb +291 -0
- data/lib/oboe/frameworks/rails/inst/dalli.rb +45 -0
- data/lib/oboe/frameworks/rails/inst/http.rb +40 -0
- data/lib/oboe/frameworks/rails/inst/memcache.rb +40 -0
- data/lib/oboe/frameworks/rails/inst/memcached.rb +32 -0
- data/lib/oboe/frameworks/rails/inst/rack.rb +29 -0
- data/lib/oboe/frameworks/rails/rails.rb +55 -0
- data/lib/oboe/loading.rb +40 -0
- data/lib/oboe/version.rb +10 -0
- data/lib/oboe_fu.rb +4 -0
- data/lib/oboe_metal.rb +151 -0
- metadata +91 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright (c) 2012 by Tracelytics, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
if defined?(::MemCache)
|
5
|
+
class ::MemCache
|
6
|
+
include Oboe::API::Memcache
|
7
|
+
|
8
|
+
MEMCACHE_OPS.reject { |m| not method_defined?(m) }.each do |m|
|
9
|
+
opts = { :KVOp => m }
|
10
|
+
define_method("#{m}_with_oboe") do |*args|
|
11
|
+
Oboe::API.trace('memcache', opts) do
|
12
|
+
send("#{m}_without_oboe", *args)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class_eval "alias #{m}_without_oboe #{m}"
|
17
|
+
class_eval "alias #{m} #{m}_with_oboe"
|
18
|
+
end
|
19
|
+
|
20
|
+
define_method(:request_setup_with_oboe) do |*args|
|
21
|
+
server, cache_key = request_setup_without_oboe(*args)
|
22
|
+
Oboe::API.log('memcache', 'info', { :KVKey => cache_key, :RemoteHost => server.host })
|
23
|
+
return [server, cache_key]
|
24
|
+
end
|
25
|
+
|
26
|
+
alias request_setup_without_oboe request_setup
|
27
|
+
alias request_setup request_setup_with_oboe
|
28
|
+
|
29
|
+
|
30
|
+
define_method(:cache_get_with_oboe) do |server, cache_key|
|
31
|
+
result = cache_get_without_oboe(server, cache_key)
|
32
|
+
Oboe::API.log('memcache', 'info', { :KVHit => memcache_hit?(result) })
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
alias cache_get_without_oboe cache_get
|
37
|
+
alias cache_get cache_get_with_oboe
|
38
|
+
end
|
39
|
+
puts "[oboe/loading] Instrumenting memcache" if Oboe::Config[:verbose]
|
40
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright (c) 2012 by Tracelytics, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
|
5
|
+
if defined?(Memcached)
|
6
|
+
class Memcached
|
7
|
+
include Oboe::API::Memcache
|
8
|
+
|
9
|
+
MEMCACHE_OPS.reject { |m| not method_defined?(m) }.each do |m|
|
10
|
+
define_method("#{m}_with_oboe") do |*args|
|
11
|
+
opts = { :KVOp => m }
|
12
|
+
if args.length and args[0].class != Array
|
13
|
+
opts[:KVKey] = args[0].to_s
|
14
|
+
rhost = remote_host(args[0].to_s)
|
15
|
+
opts[:RemoteHost] = rhost if rhost
|
16
|
+
end
|
17
|
+
|
18
|
+
Oboe::API.trace('memcache', opts) do
|
19
|
+
result = send("#{m}_without_oboe", *args)
|
20
|
+
if m == :get and args.length and args[0].class == String
|
21
|
+
Oboe::API.log('memcache', 'info', { :KVHit => memcache_hit?(result) })
|
22
|
+
end
|
23
|
+
result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class_eval "alias #{m}_without_oboe #{m}"
|
28
|
+
class_eval "alias #{m} #{m}_with_oboe"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
puts "[oboe/loading] Instrumenting memcached" if Oboe::Config[:verbose]
|
32
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Copyright (c) 2012 by Tracelytics, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
module Oboe
|
5
|
+
class Middleware
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
header = env['HTTP_X_TRACE']
|
12
|
+
result, header = Oboe::API.start_trace('rack', header) do
|
13
|
+
env['HTTP_X_TRACE'] = Oboe::Context.toString()
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
result
|
17
|
+
rescue Exception => e
|
18
|
+
header = e.instance_variable_get(:@xtrace)
|
19
|
+
raise
|
20
|
+
ensure
|
21
|
+
env['HTTP_X_TRACE'] = header if header
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
if false and defined?(::Rails.configuration.middleware)
|
27
|
+
puts "[oboe/loading] Instrumenting rack" if Oboe::Config[:verbose]
|
28
|
+
::Rails.configuration.middleware.insert 0, Oboe::Middleware
|
29
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
module Oboe
|
3
|
+
module Inst
|
4
|
+
module Rails
|
5
|
+
def self.load_initializer
|
6
|
+
# Force load the tracelytics Rails initializer if there is one
|
7
|
+
# Prefer oboe.rb but give priority to tracelytics.rb if it exists
|
8
|
+
if ::Rails::VERSION::MAJOR > 2
|
9
|
+
rails_root = "#{::Rails.root.to_s}"
|
10
|
+
else
|
11
|
+
rails_root = "#{RAILS_ROOT}"
|
12
|
+
end
|
13
|
+
|
14
|
+
if File.exists?("#{rails_root}/config/initializers/tracelytics.rb")
|
15
|
+
tr_initializer = "#{rails_root}/config/initializers/tracelytics.rb"
|
16
|
+
else
|
17
|
+
tr_initializer = "#{rails_root}/config/initializers/oboe.rb"
|
18
|
+
end
|
19
|
+
require tr_initializer if File.exists?(tr_initializer)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.load_instrumentation
|
23
|
+
pattern = File.join(File.dirname(__FILE__), 'inst', '*.rb')
|
24
|
+
Dir.glob(pattern) do |f|
|
25
|
+
begin
|
26
|
+
require f
|
27
|
+
rescue => e
|
28
|
+
$stderr.puts "[oboe/loading] Error loading rails insrumentation file '#{f}' : #{e}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
if ::Rails::VERSION::MAJOR > 2
|
32
|
+
puts "Tracelytics oboe gem #{Gem.loaded_specs['oboe'].version.to_s} successfully loaded."
|
33
|
+
else
|
34
|
+
puts "Tracelytics oboe gem #{Oboe::Version::STRING} successfully loaded."
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
if defined?(::Rails)
|
42
|
+
if ::Rails::VERSION::MAJOR > 2
|
43
|
+
module Oboe
|
44
|
+
class Railtie < ::Rails::Railtie
|
45
|
+
config.after_initialize do
|
46
|
+
Oboe::Inst::Rails.load_instrumentation
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
else
|
51
|
+
Oboe::Inst::Rails.load_initializer
|
52
|
+
Oboe::Inst::Rails.load_instrumentation
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
data/lib/oboe/loading.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright (c) 2012 by Tracelytics, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
module Oboe
|
5
|
+
module Loading
|
6
|
+
|
7
|
+
def self.require_api
|
8
|
+
require 'oboe/version'
|
9
|
+
|
10
|
+
pattern = File.join(File.dirname(__FILE__), 'api', '*.rb')
|
11
|
+
Dir.glob(pattern) do |f|
|
12
|
+
require f
|
13
|
+
end
|
14
|
+
require 'oboe/api'
|
15
|
+
|
16
|
+
begin
|
17
|
+
Oboe::API.extend_with_tracing
|
18
|
+
rescue LoadError => e
|
19
|
+
Oboe::API.extend_with_noop
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'oboe/config'
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.load_framework_instrumentation
|
26
|
+
pattern = File.join(File.dirname(__FILE__), 'frameworks/*/', '*.rb')
|
27
|
+
Dir.glob(pattern) do |f|
|
28
|
+
begin
|
29
|
+
require f
|
30
|
+
rescue => e
|
31
|
+
$stderr.puts "[oboe/loading] Error loading framework file '#{f}' : #{e}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Oboe::Loading.require_api
|
39
|
+
Oboe::Loading.load_framework_instrumentation
|
40
|
+
|
data/lib/oboe/version.rb
ADDED
data/lib/oboe_fu.rb
ADDED
data/lib/oboe_metal.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
# Copyright (c) 2012 by Tracelytics, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
module Oboe_metal
|
5
|
+
class Context
|
6
|
+
def self.log(layer, label, options = {})
|
7
|
+
evt = Oboe::Context.createEvent()
|
8
|
+
evt.addInfo("Layer", layer.to_s)
|
9
|
+
evt.addInfo("Label", label.to_s)
|
10
|
+
|
11
|
+
options.each_pair do |k, v|
|
12
|
+
evt.addInfo(k.to_s, v.to_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
evt.addInfo("Backtrace", Kernel.caller.join("\r\n"))
|
16
|
+
|
17
|
+
Oboe.reporter.sendReport(evt)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
module OboeMethodProfiling
|
24
|
+
def self.included klass
|
25
|
+
klass.extend ClassMethods
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
def profile_method(method_name, profile_name, store_args=false, store_return=false, profile=false)
|
30
|
+
#this only gets file and line where profiling is turned on, presumably
|
31
|
+
#right after the function definition. ruby 1.9 has nice introspection (Method.source_location)
|
32
|
+
#but its appears no such luck for ruby 1.8
|
33
|
+
version = RbConfig::CONFIG['ruby_version']
|
34
|
+
file = nil
|
35
|
+
line = nil
|
36
|
+
if version and version.match(/^1.9/)
|
37
|
+
info = self.method(method_name).source_location
|
38
|
+
if !info.nil?
|
39
|
+
file = info[0]
|
40
|
+
line = info[1]
|
41
|
+
end
|
42
|
+
else
|
43
|
+
info = Kernel.caller[0].split(':')
|
44
|
+
file = info.first
|
45
|
+
line = info.last
|
46
|
+
end
|
47
|
+
|
48
|
+
#profiling via ruby-prof, is it possible to get return value of profiled code?
|
49
|
+
code = "def _oboe_profiled_#{method_name}(*args, &block)
|
50
|
+
def pps(*args)
|
51
|
+
old_out = $stdout
|
52
|
+
begin
|
53
|
+
s = StringIO.new
|
54
|
+
$stdout = s
|
55
|
+
pp(*args)
|
56
|
+
ensure
|
57
|
+
$stdout = old_out
|
58
|
+
end
|
59
|
+
s.string
|
60
|
+
end
|
61
|
+
|
62
|
+
# file and line number are fetched in Context.log
|
63
|
+
# because we have access to the correct backtrace there
|
64
|
+
entry_kvs = {'Language' => 'ruby',
|
65
|
+
'ProfileName' => '#{profile_name}',
|
66
|
+
'FunctionName' => '#{method_name}',
|
67
|
+
'Class' => self.class.to_s.rpartition('::').last,
|
68
|
+
'Module' => self.class.to_s.rpartition('::').first,
|
69
|
+
'File' => '#{file}',
|
70
|
+
'LineNumber' => '#{line}'
|
71
|
+
}
|
72
|
+
|
73
|
+
if #{store_args}
|
74
|
+
entry_kvs['Args'] = pps *args
|
75
|
+
end
|
76
|
+
|
77
|
+
Oboe::Context.log(nil, 'profile_entry', entry_kvs)
|
78
|
+
|
79
|
+
ret = _oboe_orig_#{method_name}(*args, &block)
|
80
|
+
|
81
|
+
exit_kvs = {'Language' => 'ruby',
|
82
|
+
'ProfileName' => '#{profile_name}'
|
83
|
+
}
|
84
|
+
|
85
|
+
if #{store_return}
|
86
|
+
exit_kvs['ReturnValue'] = pps ret
|
87
|
+
end
|
88
|
+
|
89
|
+
Oboe::Context.log(nil, 'profile_exit', exit_kvs)
|
90
|
+
|
91
|
+
ret
|
92
|
+
end"
|
93
|
+
class_eval code, __FILE__, __LINE__
|
94
|
+
alias_method "_oboe_orig_#{method_name}", method_name
|
95
|
+
alias_method method_name, "_oboe_profiled_#{method_name}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
module Oboe
|
101
|
+
include Oboe_metal
|
102
|
+
|
103
|
+
# TODO: Ensure that the :tracing_mode is set to "always", "through", or "never"
|
104
|
+
Config = {
|
105
|
+
:tracing_mode => "through",
|
106
|
+
:reporter_host => "127.0.0.1",
|
107
|
+
:sample_rate => 1000000
|
108
|
+
}
|
109
|
+
|
110
|
+
def self.passthrough?
|
111
|
+
["always", "through"].include?(Oboe::Config[:tracing_mode])
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.always?
|
115
|
+
Oboe::Config[:tracing_mode] == "always"
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.through?
|
119
|
+
Oboe::Config[:tracing_mode] == "through"
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.never?
|
123
|
+
Oboe::Config[:tracing_mode] == "never"
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.now?
|
127
|
+
Oboe::Context.isValid and not Oboe.never?
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.start?
|
131
|
+
not Oboe::Context.isValid and Oboe.always?
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.continue?
|
135
|
+
Oboe::Context.isValid and not Oboe.never?
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.log(layer, label, options = {})
|
139
|
+
Context.log(layer, label, options = options)
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.reporter
|
143
|
+
if !@reporter
|
144
|
+
@reporter = Oboe::UdpReporter.new(Oboe::Config[:reporter_host])
|
145
|
+
end
|
146
|
+
|
147
|
+
return @reporter
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
Oboe_metal::Context.init()
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oboe
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 1.3.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Tracelytics, Inc.
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-09-12 00:00:00 Z
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: The oboe gem provides Tracelytics instrumentation for Ruby and Ruby frameworkes.
|
22
|
+
email: contact@tracelytics.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions:
|
26
|
+
- ext/oboe_metal/extconf.rb
|
27
|
+
extra_rdoc_files:
|
28
|
+
- LICENSE
|
29
|
+
files:
|
30
|
+
- lib/oboe_metal.rb
|
31
|
+
- lib/oboe.rb
|
32
|
+
- lib/oboe/loading.rb
|
33
|
+
- lib/oboe/api.rb
|
34
|
+
- lib/oboe/api/memcache.rb
|
35
|
+
- lib/oboe/api/layerinit.rb
|
36
|
+
- lib/oboe/api/util.rb
|
37
|
+
- lib/oboe/api/logging.rb
|
38
|
+
- lib/oboe/api/tracing.rb
|
39
|
+
- lib/oboe/version.rb
|
40
|
+
- lib/oboe/config.rb
|
41
|
+
- lib/oboe/frameworks/rails/inst/memcache.rb
|
42
|
+
- lib/oboe/frameworks/rails/inst/http.rb
|
43
|
+
- lib/oboe/frameworks/rails/inst/rack.rb
|
44
|
+
- lib/oboe/frameworks/rails/inst/action_controller.rb
|
45
|
+
- lib/oboe/frameworks/rails/inst/dalli.rb
|
46
|
+
- lib/oboe/frameworks/rails/inst/active_record.rb
|
47
|
+
- lib/oboe/frameworks/rails/inst/memcached.rb
|
48
|
+
- lib/oboe/frameworks/rails/rails.rb
|
49
|
+
- lib/oboe_fu.rb
|
50
|
+
- ext/oboe_metal/noop/noop.c
|
51
|
+
- ext/oboe_metal/src/oboe_wrap.cxx
|
52
|
+
- ext/oboe_metal/src/oboe.hpp
|
53
|
+
- install.rb
|
54
|
+
- init.rb
|
55
|
+
- LICENSE
|
56
|
+
- ext/oboe_metal/extconf.rb
|
57
|
+
homepage: http://tracelytics.com
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 3
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.8.24
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Tracelytics instrumentation gem
|
90
|
+
test_files: []
|
91
|
+
|