truex-skylight 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +277 -0
- data/CLA.md +9 -0
- data/CONTRIBUTING.md +1 -0
- data/LICENSE.md +79 -0
- data/README.md +4 -0
- data/bin/skylight +3 -0
- data/ext/extconf.rb +186 -0
- data/ext/libskylight.yml +6 -0
- data/ext/skylight_memprof.c +115 -0
- data/ext/skylight_native.c +416 -0
- data/ext/skylight_native.h +20 -0
- data/lib/skylight.rb +2 -0
- data/lib/skylight/api.rb +79 -0
- data/lib/skylight/cli.rb +146 -0
- data/lib/skylight/compat.rb +47 -0
- data/lib/skylight/config.rb +498 -0
- data/lib/skylight/core.rb +122 -0
- data/lib/skylight/data/cacert.pem +3894 -0
- data/lib/skylight/formatters/http.rb +17 -0
- data/lib/skylight/gc.rb +107 -0
- data/lib/skylight/helpers.rb +137 -0
- data/lib/skylight/instrumenter.rb +290 -0
- data/lib/skylight/middleware.rb +75 -0
- data/lib/skylight/native.rb +69 -0
- data/lib/skylight/normalizers.rb +133 -0
- data/lib/skylight/normalizers/action_controller/process_action.rb +35 -0
- data/lib/skylight/normalizers/action_controller/send_file.rb +76 -0
- data/lib/skylight/normalizers/action_view/render_collection.rb +18 -0
- data/lib/skylight/normalizers/action_view/render_partial.rb +18 -0
- data/lib/skylight/normalizers/action_view/render_template.rb +18 -0
- data/lib/skylight/normalizers/active_record/sql.rb +79 -0
- data/lib/skylight/normalizers/active_support/cache.rb +50 -0
- data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
- data/lib/skylight/normalizers/default.rb +21 -0
- data/lib/skylight/normalizers/moped/query.rb +141 -0
- data/lib/skylight/probes.rb +91 -0
- data/lib/skylight/probes/excon.rb +25 -0
- data/lib/skylight/probes/excon/middleware.rb +65 -0
- data/lib/skylight/probes/net_http.rb +44 -0
- data/lib/skylight/probes/redis.rb +30 -0
- data/lib/skylight/probes/sequel.rb +30 -0
- data/lib/skylight/probes/sinatra.rb +74 -0
- data/lib/skylight/probes/tilt.rb +27 -0
- data/lib/skylight/railtie.rb +122 -0
- data/lib/skylight/sinatra.rb +4 -0
- data/lib/skylight/subscriber.rb +92 -0
- data/lib/skylight/trace.rb +191 -0
- data/lib/skylight/util.rb +16 -0
- data/lib/skylight/util/allocation_free.rb +17 -0
- data/lib/skylight/util/clock.rb +53 -0
- data/lib/skylight/util/gzip.rb +15 -0
- data/lib/skylight/util/hostname.rb +17 -0
- data/lib/skylight/util/http.rb +218 -0
- data/lib/skylight/util/inflector.rb +110 -0
- data/lib/skylight/util/logging.rb +87 -0
- data/lib/skylight/util/multi_io.rb +21 -0
- data/lib/skylight/util/native_ext_fetcher.rb +205 -0
- data/lib/skylight/util/platform.rb +67 -0
- data/lib/skylight/util/ssl.rb +50 -0
- data/lib/skylight/vendor/active_support/notifications.rb +207 -0
- data/lib/skylight/vendor/active_support/notifications/fanout.rb +159 -0
- data/lib/skylight/vendor/active_support/notifications/instrumenter.rb +72 -0
- data/lib/skylight/vendor/active_support/per_thread_registry.rb +52 -0
- data/lib/skylight/vendor/cli/highline.rb +1034 -0
- data/lib/skylight/vendor/cli/highline/color_scheme.rb +134 -0
- data/lib/skylight/vendor/cli/highline/compatibility.rb +16 -0
- data/lib/skylight/vendor/cli/highline/import.rb +41 -0
- data/lib/skylight/vendor/cli/highline/menu.rb +381 -0
- data/lib/skylight/vendor/cli/highline/question.rb +481 -0
- data/lib/skylight/vendor/cli/highline/simulate.rb +48 -0
- data/lib/skylight/vendor/cli/highline/string_extensions.rb +111 -0
- data/lib/skylight/vendor/cli/highline/style.rb +181 -0
- data/lib/skylight/vendor/cli/highline/system_extensions.rb +242 -0
- data/lib/skylight/vendor/cli/thor.rb +473 -0
- data/lib/skylight/vendor/cli/thor/actions.rb +318 -0
- data/lib/skylight/vendor/cli/thor/actions/create_file.rb +105 -0
- data/lib/skylight/vendor/cli/thor/actions/create_link.rb +60 -0
- data/lib/skylight/vendor/cli/thor/actions/directory.rb +119 -0
- data/lib/skylight/vendor/cli/thor/actions/empty_directory.rb +137 -0
- data/lib/skylight/vendor/cli/thor/actions/file_manipulation.rb +314 -0
- data/lib/skylight/vendor/cli/thor/actions/inject_into_file.rb +109 -0
- data/lib/skylight/vendor/cli/thor/base.rb +652 -0
- data/lib/skylight/vendor/cli/thor/command.rb +136 -0
- data/lib/skylight/vendor/cli/thor/core_ext/hash_with_indifferent_access.rb +80 -0
- data/lib/skylight/vendor/cli/thor/core_ext/io_binary_read.rb +12 -0
- data/lib/skylight/vendor/cli/thor/core_ext/ordered_hash.rb +100 -0
- data/lib/skylight/vendor/cli/thor/error.rb +28 -0
- data/lib/skylight/vendor/cli/thor/group.rb +282 -0
- data/lib/skylight/vendor/cli/thor/invocation.rb +172 -0
- data/lib/skylight/vendor/cli/thor/parser.rb +4 -0
- data/lib/skylight/vendor/cli/thor/parser/argument.rb +74 -0
- data/lib/skylight/vendor/cli/thor/parser/arguments.rb +171 -0
- data/lib/skylight/vendor/cli/thor/parser/option.rb +121 -0
- data/lib/skylight/vendor/cli/thor/parser/options.rb +218 -0
- data/lib/skylight/vendor/cli/thor/rake_compat.rb +72 -0
- data/lib/skylight/vendor/cli/thor/runner.rb +322 -0
- data/lib/skylight/vendor/cli/thor/shell.rb +88 -0
- data/lib/skylight/vendor/cli/thor/shell/basic.rb +393 -0
- data/lib/skylight/vendor/cli/thor/shell/color.rb +148 -0
- data/lib/skylight/vendor/cli/thor/shell/html.rb +127 -0
- data/lib/skylight/vendor/cli/thor/util.rb +270 -0
- data/lib/skylight/vendor/cli/thor/version.rb +3 -0
- data/lib/skylight/vendor/thread_safe.rb +126 -0
- data/lib/skylight/vendor/thread_safe/non_concurrent_cache_backend.rb +133 -0
- data/lib/skylight/vendor/thread_safe/synchronized_cache_backend.rb +76 -0
- data/lib/skylight/version.rb +4 -0
- data/lib/skylight/vm/gc.rb +70 -0
- data/lib/sql_lexer.rb +6 -0
- data/lib/sql_lexer/lexer.rb +579 -0
- data/lib/sql_lexer/string_scanner.rb +11 -0
- data/lib/sql_lexer/version.rb +3 -0
- metadata +179 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
module Skylight
|
2
|
+
module Formatters
|
3
|
+
module HTTP
|
4
|
+
def self.build_opts(method, scheme, host, port, path, query)
|
5
|
+
{ category: "api.http.#{method.downcase}",
|
6
|
+
title: "#{method.upcase} #{host}",
|
7
|
+
annotations: {
|
8
|
+
method: method.upcase,
|
9
|
+
scheme: scheme,
|
10
|
+
host: host,
|
11
|
+
port: port ? port.to_i : nil,
|
12
|
+
path: path,
|
13
|
+
query: query }}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/skylight/gc.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Skylight
|
4
|
+
# @api private
|
5
|
+
class GC
|
6
|
+
METHODS = [ :enable, :total_time ]
|
7
|
+
TH_KEY = :SK_GC_CURR_WINDOW
|
8
|
+
MAX_COUNT = 1000
|
9
|
+
MAX_TIME = 30_000_000
|
10
|
+
|
11
|
+
include Util::Logging
|
12
|
+
|
13
|
+
attr_reader :config
|
14
|
+
|
15
|
+
def initialize(config, profiler)
|
16
|
+
@listeners = []
|
17
|
+
@config = config
|
18
|
+
@lock = Mutex.new
|
19
|
+
@time = 0
|
20
|
+
|
21
|
+
if METHODS.all? { |m| profiler.respond_to?(m) }
|
22
|
+
@profiler = profiler
|
23
|
+
@time = @profiler.total_time
|
24
|
+
else
|
25
|
+
debug "disabling GC profiling"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def enable
|
30
|
+
@profiler.enable if @profiler
|
31
|
+
end
|
32
|
+
|
33
|
+
def track
|
34
|
+
unless @profiler
|
35
|
+
win = Window.new(nil)
|
36
|
+
else
|
37
|
+
win = Window.new(self)
|
38
|
+
|
39
|
+
@lock.synchronize do
|
40
|
+
__update
|
41
|
+
@listeners << win
|
42
|
+
|
43
|
+
# Cleanup any listeners that might have leaked
|
44
|
+
until @listeners[0].time < MAX_TIME
|
45
|
+
@listeners.shift
|
46
|
+
end
|
47
|
+
|
48
|
+
if @listeners.length > MAX_COUNT
|
49
|
+
@listeners.shift
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
win
|
55
|
+
end
|
56
|
+
|
57
|
+
def release(win)
|
58
|
+
@lock.synchronize do
|
59
|
+
@listeners.delete(win)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def update
|
64
|
+
@lock.synchronize do
|
65
|
+
__update
|
66
|
+
end
|
67
|
+
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def __update
|
74
|
+
time = @profiler.total_time
|
75
|
+
diff = time - @time
|
76
|
+
@time = time
|
77
|
+
|
78
|
+
if diff > 0
|
79
|
+
@listeners.each do |l|
|
80
|
+
l.add(diff)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class Window
|
86
|
+
attr_reader :time
|
87
|
+
|
88
|
+
def initialize(global)
|
89
|
+
@global = global
|
90
|
+
@time = 0
|
91
|
+
end
|
92
|
+
|
93
|
+
def update
|
94
|
+
@global.update if @global
|
95
|
+
end
|
96
|
+
|
97
|
+
def add(time)
|
98
|
+
@time += time
|
99
|
+
end
|
100
|
+
|
101
|
+
def release
|
102
|
+
@global.release(self) if @global
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module Skylight
|
2
|
+
# Instrumenting a specific method will cause an event to be created every time that method is called.
|
3
|
+
# The event will be inserted at the appropriate place in the Skylight trace.
|
4
|
+
#
|
5
|
+
# To instrument a method, the first thing to do is include {Skylight::Helpers Skylight::Helpers}
|
6
|
+
# into the class that you will be instrumenting. Then, annotate each method that
|
7
|
+
# you wish to instrument with {Skylight::Helpers::ClassMethods#instrument_method instrument_method}.
|
8
|
+
module Helpers
|
9
|
+
|
10
|
+
# @see Skylight::Helpers
|
11
|
+
module ClassMethods
|
12
|
+
# @api private
|
13
|
+
def method_added(name)
|
14
|
+
super
|
15
|
+
|
16
|
+
if opts = @__sk_instrument_next_method
|
17
|
+
@__sk_instrument_next_method = nil
|
18
|
+
title = "#{to_s}##{name}"
|
19
|
+
__sk_instrument_method_on(self, name, title, opts)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# @api private
|
24
|
+
def singleton_method_added(name)
|
25
|
+
super
|
26
|
+
|
27
|
+
if opts = @__sk_instrument_next_method
|
28
|
+
@__sk_instrument_next_method = nil
|
29
|
+
title = "#{to_s}.#{name}"
|
30
|
+
__sk_instrument_method_on(__sk_singleton_class, name, title, opts)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @overload instrument_method
|
35
|
+
# Instruments the following method
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# class MyClass
|
39
|
+
# include Skylight::Helpers
|
40
|
+
#
|
41
|
+
# instrument_method
|
42
|
+
# def my_method
|
43
|
+
# do_expensive_stuff
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# @overload instrument_method([name], opts={})
|
49
|
+
# @param [Symbol|String] [name]
|
50
|
+
# @param [Hash] opts
|
51
|
+
# @option opts [String] :category ('app.method')
|
52
|
+
# @option opts [String] :title (ClassName#method_name)
|
53
|
+
# @option opts [String] :description
|
54
|
+
#
|
55
|
+
# You may also declare the methods to instrument at any time by passing the name
|
56
|
+
# of the method as the first argument to `instrument_method`.
|
57
|
+
#
|
58
|
+
# @example With name
|
59
|
+
# class MyClass
|
60
|
+
# include Skylight::Helpers
|
61
|
+
#
|
62
|
+
# def my_method
|
63
|
+
# do_expensive_stuff
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# instrument_method :my_method
|
67
|
+
#
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# By default, the event will be titled using the name of the class and the
|
71
|
+
# method. For example, in our previous example, the event name will be:
|
72
|
+
# +MyClass#my_method+. You can customize this by passing using the *:title* option.
|
73
|
+
#
|
74
|
+
# @example Without name
|
75
|
+
# class MyClass
|
76
|
+
# include Skylight::Helpers
|
77
|
+
#
|
78
|
+
# instrument_method title: 'Expensive work'
|
79
|
+
# def my_method
|
80
|
+
# do_expensive_stuff
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
def instrument_method(*args)
|
84
|
+
opts = args.pop if Hash === args.last
|
85
|
+
|
86
|
+
if name = args.pop
|
87
|
+
title = "#{to_s}##{name}"
|
88
|
+
__sk_instrument_method_on(self, name, title, opts || {})
|
89
|
+
else
|
90
|
+
@__sk_instrument_next_method = opts || {}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def __sk_instrument_method_on(klass, name, title, opts)
|
97
|
+
category = (opts[:category] || "app.method").to_s
|
98
|
+
title = (opts[:title] || title).to_s
|
99
|
+
desc = opts[:description].to_s if opts[:description]
|
100
|
+
|
101
|
+
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
102
|
+
alias_method :"before_instrument_#{name}", :"#{name}"
|
103
|
+
|
104
|
+
def #{name}(*args, &blk)
|
105
|
+
span = Skylight.instrument(
|
106
|
+
category: :"#{category}",
|
107
|
+
title: #{title.inspect},
|
108
|
+
description: #{desc.inspect})
|
109
|
+
|
110
|
+
begin
|
111
|
+
before_instrument_#{name}(*args, &blk)
|
112
|
+
ensure
|
113
|
+
Skylight.done(span) if span
|
114
|
+
end
|
115
|
+
end
|
116
|
+
RUBY
|
117
|
+
end
|
118
|
+
|
119
|
+
if respond_to?(:singleton_class)
|
120
|
+
alias :__sk_singleton_class :singleton_class
|
121
|
+
else
|
122
|
+
def __sk_singleton_class
|
123
|
+
class << self; self; end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# @api private
|
129
|
+
def self.included(base)
|
130
|
+
base.class_eval do
|
131
|
+
@__sk_instrument_next_method = nil
|
132
|
+
extend ClassMethods
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,290 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'strscan'
|
3
|
+
require 'skylight/api'
|
4
|
+
|
5
|
+
module Skylight
|
6
|
+
# @api private
|
7
|
+
class Instrumenter
|
8
|
+
KEY = :__skylight_current_trace
|
9
|
+
LOCK = Mutex.new
|
10
|
+
DESC_LOCK = Mutex.new
|
11
|
+
|
12
|
+
TOO_MANY_UNIQUES = "<too many unique descriptions>"
|
13
|
+
|
14
|
+
include Util::Logging
|
15
|
+
|
16
|
+
class TraceInfo
|
17
|
+
def current
|
18
|
+
Thread.current[KEY]
|
19
|
+
end
|
20
|
+
|
21
|
+
def current=(trace)
|
22
|
+
Thread.current[KEY] = trace
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.instance
|
27
|
+
@instance
|
28
|
+
end
|
29
|
+
|
30
|
+
# Do start
|
31
|
+
# @param [Config] config The config
|
32
|
+
def self.start!(config = nil)
|
33
|
+
return @instance if @instance
|
34
|
+
|
35
|
+
LOCK.synchronize do
|
36
|
+
return @instance if @instance
|
37
|
+
@instance = new(config).start!
|
38
|
+
end
|
39
|
+
rescue => e
|
40
|
+
message = sprintf("[SKYLIGHT] [#{Skylight::VERSION}] Unable to start Instrumenter; msg=%s; class=%s", e.message, e.class)
|
41
|
+
if config && config.respond_to?(:logger)
|
42
|
+
config.logger.warn message
|
43
|
+
else
|
44
|
+
warn message
|
45
|
+
end
|
46
|
+
false
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.stop!
|
50
|
+
LOCK.synchronize do
|
51
|
+
return unless @instance
|
52
|
+
# This is only really helpful for getting specs to pass.
|
53
|
+
@instance.current_trace = nil
|
54
|
+
|
55
|
+
@instance.shutdown
|
56
|
+
@instance = nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
at_exit do
|
61
|
+
if RUBY_VERSION == '1.9.2'
|
62
|
+
# workaround for MRI bug losing exit status in at_exit block
|
63
|
+
# http://bugs.ruby-lang.org/issues/5218
|
64
|
+
exit_status = $!.status if $!.is_a?(SystemExit)
|
65
|
+
stop!
|
66
|
+
exit exit_status if exit_status
|
67
|
+
else
|
68
|
+
stop!
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
attr_reader :config, :gc, :trace_info
|
73
|
+
|
74
|
+
def self.new(config)
|
75
|
+
config ||= {}
|
76
|
+
config = Config.load(config) unless config.is_a?(Config)
|
77
|
+
config.validate!
|
78
|
+
|
79
|
+
inst = native_new(config.to_env)
|
80
|
+
inst.send(:initialize, config)
|
81
|
+
inst
|
82
|
+
end
|
83
|
+
|
84
|
+
def initialize(config)
|
85
|
+
@gc = config.gc
|
86
|
+
@config = config
|
87
|
+
@subscriber = Subscriber.new(config, self)
|
88
|
+
|
89
|
+
@trace_info = @config[:trace_info] || TraceInfo.new
|
90
|
+
@descriptions = Hash.new { |h,k| h[k] = {} }
|
91
|
+
end
|
92
|
+
|
93
|
+
def current_trace
|
94
|
+
@trace_info.current
|
95
|
+
end
|
96
|
+
|
97
|
+
def current_trace=(trace)
|
98
|
+
@trace_info.current = trace
|
99
|
+
end
|
100
|
+
|
101
|
+
def start!
|
102
|
+
# Warn if there was an error installing Skylight.
|
103
|
+
# We do this here since we can't report these issues via Gem install without stopping install entirely.
|
104
|
+
Skylight.check_install_errors(config)
|
105
|
+
|
106
|
+
unless Skylight.native?
|
107
|
+
Skylight.warn_skylight_native_missing(config)
|
108
|
+
return
|
109
|
+
end
|
110
|
+
|
111
|
+
t { "starting instrumenter" }
|
112
|
+
@config.validate!
|
113
|
+
|
114
|
+
unless validate_authentication
|
115
|
+
warn "invalid authentication token"
|
116
|
+
return
|
117
|
+
end
|
118
|
+
|
119
|
+
t { "starting native instrumenter" }
|
120
|
+
unless native_start
|
121
|
+
warn "failed to start instrumenter"
|
122
|
+
return
|
123
|
+
end
|
124
|
+
|
125
|
+
@config.gc.enable
|
126
|
+
@subscriber.register!
|
127
|
+
|
128
|
+
self
|
129
|
+
|
130
|
+
rescue Exception => e
|
131
|
+
log_error "failed to start instrumenter; msg=%s; config=%s", e.message, @config.inspect
|
132
|
+
t { e.backtrace.join("\n") }
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
|
136
|
+
def shutdown
|
137
|
+
@subscriber.unregister!
|
138
|
+
native_stop
|
139
|
+
end
|
140
|
+
|
141
|
+
def trace(endpoint, cat, title=nil, desc=nil, annot=nil)
|
142
|
+
# If a trace is already in progress, continue with that one
|
143
|
+
if trace = @trace_info.current
|
144
|
+
return yield(trace) if block_given?
|
145
|
+
return trace
|
146
|
+
end
|
147
|
+
|
148
|
+
begin
|
149
|
+
trace = Trace.new(self, endpoint, Util::Clock.nanos, cat, title, desc, annot)
|
150
|
+
rescue Exception => e
|
151
|
+
log_error e.message
|
152
|
+
t { e.backtrace.join("\n") }
|
153
|
+
return
|
154
|
+
end
|
155
|
+
|
156
|
+
@trace_info.current = trace
|
157
|
+
return trace unless block_given?
|
158
|
+
|
159
|
+
begin
|
160
|
+
yield trace
|
161
|
+
|
162
|
+
ensure
|
163
|
+
@trace_info.current = nil
|
164
|
+
t { "submitting trace" }
|
165
|
+
trace.submit
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def disable
|
170
|
+
@disabled = true
|
171
|
+
yield
|
172
|
+
ensure
|
173
|
+
@disabled = false
|
174
|
+
end
|
175
|
+
|
176
|
+
def disabled?
|
177
|
+
@disabled
|
178
|
+
end
|
179
|
+
|
180
|
+
@scanner = StringScanner.new('')
|
181
|
+
def self.match?(string, regex)
|
182
|
+
@scanner.string = string
|
183
|
+
@scanner.match?(regex)
|
184
|
+
end
|
185
|
+
|
186
|
+
def match?(string, regex)
|
187
|
+
self.class.match?(string, regex)
|
188
|
+
end
|
189
|
+
|
190
|
+
def done(span)
|
191
|
+
return unless trace = @trace_info.current
|
192
|
+
trace.done(span)
|
193
|
+
end
|
194
|
+
|
195
|
+
def instrument(cat, title=nil, desc=nil, annot=nil)
|
196
|
+
raise ArgumentError, 'cat is required' unless cat
|
197
|
+
|
198
|
+
unless trace = @trace_info.current
|
199
|
+
return yield if block_given?
|
200
|
+
return
|
201
|
+
end
|
202
|
+
|
203
|
+
cat = cat.to_s
|
204
|
+
|
205
|
+
unless match?(cat, CATEGORY_REGEX)
|
206
|
+
warn "invalid skylight instrumentation category; value=%s", cat
|
207
|
+
return yield if block_given?
|
208
|
+
return
|
209
|
+
end
|
210
|
+
|
211
|
+
cat = "other.#{cat}" unless match?(cat, TIER_REGEX)
|
212
|
+
|
213
|
+
unless sp = trace.instrument(cat, title, desc, annot)
|
214
|
+
return yield if block_given?
|
215
|
+
return
|
216
|
+
end
|
217
|
+
|
218
|
+
return sp unless block_given?
|
219
|
+
|
220
|
+
begin
|
221
|
+
yield sp
|
222
|
+
ensure
|
223
|
+
trace.done(sp)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def limited_description(description)
|
228
|
+
endpoint = @trace_info.current.endpoint
|
229
|
+
|
230
|
+
DESC_LOCK.synchronize do
|
231
|
+
set = @descriptions[endpoint]
|
232
|
+
|
233
|
+
if set.size >= 100
|
234
|
+
return TOO_MANY_UNIQUES
|
235
|
+
end
|
236
|
+
|
237
|
+
set[description] = true
|
238
|
+
description
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def process(trace)
|
243
|
+
t { fmt "processing trace" }
|
244
|
+
|
245
|
+
if ignore?(trace)
|
246
|
+
t { fmt "ignoring trace" }
|
247
|
+
return false
|
248
|
+
end
|
249
|
+
|
250
|
+
begin
|
251
|
+
native_submit_trace(trace)
|
252
|
+
true
|
253
|
+
rescue => e
|
254
|
+
warn "failed to submit trace to worker; err=%s", e
|
255
|
+
false
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def ignore?(trace)
|
260
|
+
@config.ignored_endpoints.include?(trace.endpoint)
|
261
|
+
end
|
262
|
+
|
263
|
+
# Validates that the provided authentication token is valid. This is done
|
264
|
+
# by issuing a request for a session token and checking the response
|
265
|
+
def validate_authentication
|
266
|
+
# If a session token is specified, don't bother attempting to validate
|
267
|
+
if config[:session_token]
|
268
|
+
debug "using pre-generated session token"
|
269
|
+
true
|
270
|
+
else
|
271
|
+
api = Api.new(config)
|
272
|
+
api.authentication = config[:authentication]
|
273
|
+
|
274
|
+
case res = api.validate_authentication
|
275
|
+
when :ok
|
276
|
+
true
|
277
|
+
when :invalid
|
278
|
+
false
|
279
|
+
when :unknown
|
280
|
+
warn "unable to validate authentication token"
|
281
|
+
true
|
282
|
+
else
|
283
|
+
error "[BUG] unexpected validate_token result; res=%s", res
|
284
|
+
true
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
end
|
290
|
+
end
|