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/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