oboe 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ # Copyright (c) 2012 by Tracelytics, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'oboe'
@@ -0,0 +1 @@
1
+ #Install hooks here
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2012 by Tracelytics, Inc.
2
+ # All rights reserved.
3
+
4
+ begin
5
+ require 'oboe_metal.so'
6
+ require 'rbconfig'
7
+ require 'oboe_metal'
8
+ require 'oboe/config'
9
+ require 'oboe/loading'
10
+
11
+ rescue LoadError
12
+ puts "Unsupported Tracelytics environment (no libs). Going No-op."
13
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright (c) 2012 by Tracelytics, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module API
6
+ def self.extend_with_tracing
7
+ extend Oboe::API::Logging
8
+ extend Oboe::API::Tracing
9
+ extend Oboe::API::LayerInit
10
+ end
11
+
12
+ def self.extend_with_noop
13
+ extend Oboe::API::LoggingNoop
14
+ extend Oboe::API::TracingNoop
15
+ extend Oboe::API::LayerInitNoop
16
+ end
17
+
18
+ extend Oboe::API::Util
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ module Oboe
2
+ module API
3
+ module LayerInit
4
+ # Internal: Report that instrumentation for the given layer has been
5
+ # installed, as well as the version of instrumentation and version of
6
+ # layer.
7
+ #
8
+ def report_init(layer)
9
+ platform_info = { '__Init' => 1 }
10
+ platform_info['RubyVersion'] = RUBY_VERSION
11
+ platform_info['RailsVersion'] = Rails.version if defined?(Rails)
12
+ platform_info['OboeVersion'] = Gem.loaded_specs['oboe'].try(:version).to_s
13
+
14
+ force_trace do
15
+ start_trace(layer, nil, platform_info) { }
16
+ end
17
+ end
18
+
19
+ def force_trace
20
+ saved_mode = Oboe::Config[:tracing_mode]
21
+ Oboe::Config[:tracing_mode] = 'always'
22
+ yield
23
+ ensure
24
+ Oboe::Config[:tracing_mode] = saved_mode
25
+ end
26
+ end
27
+
28
+ module LayerInitNoop
29
+ def report_init(layer)
30
+ end
31
+
32
+ def force_trace
33
+ yield
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,145 @@
1
+ # Copyright (c) 2012 by Tracelytics, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module API
6
+ module Logging
7
+
8
+ # Public: Report an event in an active trace.
9
+ #
10
+ # layer - The layer the reported event belongs to
11
+ # label - The label for the reported event. See API documentation for
12
+ # reserved labels and usage.
13
+ # opts - A hash containing key/value pairs that will be reported along
14
+ # with this event (optional).
15
+ #
16
+ # Example
17
+ #
18
+ # log('logical_layer', 'entry')
19
+ # log('logical_layer', 'info', { :list_length => 20 })
20
+ # log('logical_layer', 'exit')
21
+ #
22
+ # Returns nothing.
23
+ def log(layer, label, opts={})
24
+ log_event(layer, label, Oboe::Context.createEvent, opts)
25
+ end
26
+
27
+ # Public: Report an exception.
28
+ #
29
+ # layer - The layer the reported event belongs to
30
+ # exn - The exception to report
31
+ #
32
+ # Example
33
+ #
34
+ # begin
35
+ # function_without_oboe()
36
+ # rescue Exception => e
37
+ # log_exception('rails', e)
38
+ # raise
39
+ # end
40
+ #
41
+ # Returns nothing.
42
+ def log_exception(layer, exn)
43
+ log(layer, 'error', {
44
+ :ErrorClass => exn.class.name,
45
+ :Message => exn.message,
46
+ :ErrorBacktrace => exn.backtrace.join("\r\n")
47
+ })
48
+ end
49
+
50
+ # Public: Decide whether or not to start a trace, and report an event
51
+ # appropriately.
52
+ #
53
+ # layer - The layer the reported event belongs to
54
+ # xtrace - An xtrace metadata string, or nil.
55
+ # opts - A hash containing key/value pairs that will be reported along
56
+ # with this event (optional).
57
+ #
58
+ # Returns nothing.
59
+ def log_start(layer, xtrace, opts={})
60
+ return if Oboe::Config.never?
61
+
62
+ if xtrace
63
+ Oboe::Context.fromString(xtrace)
64
+ end
65
+
66
+ if Oboe::Config.tracing?
67
+ log_entry(layer, opts)
68
+ elsif Oboe::Config.always? or Oboe::Config.sample?
69
+ log_event(layer, 'entry', Oboe::Context.startTrace, opts)
70
+ end
71
+ end
72
+
73
+ # Public: Report an exit event.
74
+ #
75
+ # layer - The layer the reported event belongs to
76
+ #
77
+ # Returns an xtrace metadata string
78
+ def log_end(layer, opts={})
79
+ log_event(layer, 'exit', Oboe::Context.createEvent, opts)
80
+ xtrace = Oboe::Context.toString
81
+ Oboe::Context.clear
82
+ xtrace
83
+ end
84
+
85
+ def log_entry(layer, opts={})
86
+ log_event(layer, 'entry', Oboe::Context.createEvent, opts)
87
+ end
88
+
89
+ def log_exit(layer, opts={})
90
+ log_event(layer, 'exit', Oboe::Context.createEvent, opts)
91
+ end
92
+
93
+ # Internal: Report an event.
94
+ #
95
+ # layer - The layer the reported event belongs to
96
+ # label - The label for the reported event. See API documentation for
97
+ # reserved labels and usage.
98
+ # opts - A hash containing key/value pairs that will be reported along
99
+ # with this event (optional).
100
+ #
101
+ # Examples
102
+ #
103
+ # entry = Oboe::Context.createEvent
104
+ # log_event('rails', 'entry', exit, { :controller => 'user', :action => 'index' })
105
+ # exit = Oboe::Context.createEvent
106
+ # exit.addEdge(entry.getMetadata)
107
+ # log_event('rails', 'exit', exit)
108
+ #
109
+ # Returns nothing.
110
+ def log_event(layer, label, event, opts={})
111
+ event.addInfo('Layer', layer.to_s)
112
+ event.addInfo('Label', label.to_s)
113
+
114
+ opts.each do |k, v|
115
+ event.addInfo(k.to_s, v.to_s) if valid_key? k
116
+ end if !opts.nil? and opts.any?
117
+
118
+ Oboe.reporter.sendReport(event)
119
+ end
120
+ end
121
+
122
+ module LoggingNoop
123
+ def log(layer, label, opts={})
124
+ end
125
+
126
+ def log_exception(layer, exn)
127
+ end
128
+
129
+ def log_start(layer, xtrace, opts={})
130
+ end
131
+
132
+ def log_end(layer, opts={})
133
+ end
134
+
135
+ def log_entry(layer, opts={})
136
+ end
137
+
138
+ def log_exit(layer, opts={})
139
+ end
140
+
141
+ def log_event(layer, label, event, opts={})
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright (c) 2012 by Tracelytics, Inc.
2
+ # All rights reserved.
3
+ #
4
+ module Oboe
5
+ module API
6
+ module Memcache
7
+ MEMCACHE_OPS = %w{add append cas decr decrement delete fetch get get_multi incr increment prepend replace set}
8
+
9
+ def memcache_hit?(result)
10
+ result.nil? ? 0 : 1
11
+ end
12
+
13
+ def remote_host(key)
14
+ return unless defined?(Lib.memcached_server_by_key)\
15
+ and defined?(@struct) and defined?(is_unix_socket?)
16
+
17
+ server_as_array = Lib.memcached_server_by_key(@struct, args[0].to_s)
18
+ if server_as_array.is_a?(Array)
19
+ server = server_as_array.first
20
+ if is_unix_socket?(server)
21
+ return "localhost"
22
+ elsif defined?(server.hostname)
23
+ return server.hostname
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,146 @@
1
+ # Copyright (c) 2012 by Tracelytics, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module API
6
+ module Tracing
7
+
8
+ # Public: Trace a given block of code. Detect any exceptions thrown by
9
+ # the block and report errors.
10
+ #
11
+ # layer - The layer the block of code belongs to.
12
+ # opts - A hash containing key/value pairs that will be reported along
13
+ # with the first event of this layer (optional).
14
+ #
15
+ # Example
16
+ #
17
+ # def computation(n)
18
+ # fib(n)
19
+ # raise Exception.new
20
+ # end
21
+ #
22
+ # def computation_with_oboe(n)
23
+ # trace('fib', { :number => n }) do
24
+ # computation(n)
25
+ # end
26
+ # end
27
+ #
28
+ # result = computation_with_oboe(1000)
29
+ #
30
+ # Returns the result of the block.
31
+ def trace(layer, opts={})
32
+ log_entry(layer, opts)
33
+ begin
34
+ yield
35
+ rescue Exception => e
36
+ log_exception(layer, e)
37
+ raise
38
+ ensure
39
+ log_exit(layer)
40
+ end
41
+ end
42
+
43
+ # Public: Trace a given block of code which can start a trace depending
44
+ # on configuration and probability. Detect any exceptions thrown by the
45
+ # block and report errors.
46
+ #
47
+ # When start_trace returns control to the calling context, the oboe
48
+ # context will be cleared.
49
+ #
50
+ # layer - The layer the block of code belongs to.
51
+ # opts - A hash containing key/value pairs that will be reported along
52
+ # with the first event of this layer (optional).
53
+ #
54
+ # Example
55
+ #
56
+ # def handle_request(request, response)
57
+ # # ... code that modifies request and response ...
58
+ # end
59
+ #
60
+ # def handle_request_with_oboe(request, response)
61
+ # result, xtrace = start_trace('rails', request['X-Trace']) do
62
+ # handle_request(request, response)
63
+ # end
64
+ # result
65
+ # rescue Exception => e
66
+ # xtrace = e.xtrace
67
+ # ensure
68
+ # response['X-trace'] = xtrace
69
+ # end
70
+ #
71
+ # Returns a list of length two, the first element of which is the result
72
+ # of the block, and the second element of which is the oboe context that
73
+ # was set when the block completed execution.
74
+ def start_trace(layer, xtrace, opts={})
75
+ log_start(layer, xtrace, opts)
76
+ begin
77
+ result = yield
78
+ rescue Exception => e
79
+ log_exception(layer, e)
80
+ e.instance_variable_set(:@xtrace, log_end(layer))
81
+ raise
82
+ end
83
+ xtrace = log_end(layer)
84
+
85
+ [result, xtrace]
86
+ end
87
+
88
+ # Public: Trace a given block of code which can start a trace depending
89
+ # on configuration and probability. Detect any exceptions thrown by the
90
+ # block and report errors. Insert the oboe metadata into the provided for
91
+ # later user.
92
+ #
93
+ # The motivating use case for this is HTTP streaming in rails3. We need
94
+ # access to the exit event's trace id so we can set the header before any
95
+ # work is done, and before any headers are sent back to the client.
96
+ #
97
+ # layer - The layer the block of code belongs to.
98
+ # target - The target object in which to place the oboe metadata.
99
+ # opts - A hash containing key/value pairs that will be reported along
100
+ # with the first event of this layer (optional).
101
+ #
102
+ # Example:
103
+ #
104
+ # def handle_request(request, response)
105
+ # # ... code that does something with request and response ...
106
+ # end
107
+ #
108
+ # def handle_request_with_oboe(request, response)
109
+ # start_trace_with_target('rails', request['X-Trace'], response) do
110
+ # handle_request(request, response)
111
+ # end
112
+ # end
113
+ #
114
+ # Returns the result of the block.
115
+ def start_trace_with_target(layer, xtrace, target, opts={})
116
+ log_start(layer, xtrace, opts)
117
+ exit_evt = Oboe::Context.createEvent
118
+ begin
119
+ target['X-Trace'] = exit_evt.metadataString() if Oboe::Config.tracing?
120
+ yield
121
+ rescue Exception => e
122
+ log_exception(layer, e)
123
+ raise
124
+ ensure
125
+ exit_evt.addEdge(Oboe::Context.get())
126
+ log_event(layer, 'exit', exit_evt)
127
+ Oboe::Context.clear
128
+ end
129
+ end
130
+ end
131
+
132
+ module TracingNoop
133
+ def trace(layer, opts={})
134
+ yield
135
+ end
136
+
137
+ def start_trace(layer, xtrace, opts={})
138
+ [yield, xtrace]
139
+ end
140
+
141
+ def start_trace_with_target(layer, xtrace, target, opts={})
142
+ yield
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,37 @@
1
+ # Copyright (c) 2012 by Tracelytics, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module API
6
+ module Util
7
+ BACKTRACE_CUTOFF = 100
8
+
9
+ # Internal: Check whether the provided key is reserved or not. Reserved
10
+ # keys are either keys that are handled by liboboe calls or the oboe gem.
11
+ #
12
+ # key - the key to check.
13
+ #
14
+ # Return a boolean indicating whether or not key is reserved.
15
+ def valid_key?(key)
16
+ !%w[ Label Layer Edge Timestamp Timestamp_u ].include? key.to_s
17
+ end
18
+
19
+ # Internal: Get the current backtrace.
20
+ #
21
+ # ignore - Number of frames to ignore at the end of the backtrace. Use
22
+ # when you know how many layers deep in oboe the call is being
23
+ # made.
24
+ #
25
+ # Returns a string with each frame of the backtrace separated by '\r\n'.
26
+ def backtrace(ignore=1)
27
+ frames = Kernel.caller
28
+ frames_len = frames.size
29
+ if frames_len - ignore > BACKTRACE_CUTOFF
30
+ frames[ignore, BACKTRACE_CUTOFF + ignore].unshift("...")
31
+ else
32
+ frames.drop(ignore)
33
+ end.join("\r\n")
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ # Copyright (c) 2012 by Tracelytics, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ # The following is done for compatability with older versions of oboe and
6
+ # oboe_fu (0.2.x)
7
+ if not defined?(Oboe::Config)
8
+ Config = {
9
+ :tracing_mode => "through",
10
+ :reporter_host => "127.0.0.1",
11
+ :sample_rate => 3e5
12
+ }
13
+ end
14
+
15
+ class << Config
16
+ def always?
17
+ self[:tracing_mode].to_s == "always"
18
+ end
19
+
20
+ def never?
21
+ self[:tracing_mode].to_s == "never"
22
+ end
23
+
24
+ def tracing?
25
+ Oboe::Context.isValid and not never?
26
+ end
27
+
28
+ def start?
29
+ not Oboe::Context.isValid and always?
30
+ end
31
+
32
+ def sample?
33
+ # Note that this the only point in the code that currently does and
34
+ # should ever read the sample rate. When autopilot is released, modify
35
+ # the line below and that line only.
36
+ self[:sample_rate].to_i < rand(1e6)
37
+ end
38
+ end
39
+ end