truex-skylight 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +277 -0
  3. data/CLA.md +9 -0
  4. data/CONTRIBUTING.md +1 -0
  5. data/LICENSE.md +79 -0
  6. data/README.md +4 -0
  7. data/bin/skylight +3 -0
  8. data/ext/extconf.rb +186 -0
  9. data/ext/libskylight.yml +6 -0
  10. data/ext/skylight_memprof.c +115 -0
  11. data/ext/skylight_native.c +416 -0
  12. data/ext/skylight_native.h +20 -0
  13. data/lib/skylight.rb +2 -0
  14. data/lib/skylight/api.rb +79 -0
  15. data/lib/skylight/cli.rb +146 -0
  16. data/lib/skylight/compat.rb +47 -0
  17. data/lib/skylight/config.rb +498 -0
  18. data/lib/skylight/core.rb +122 -0
  19. data/lib/skylight/data/cacert.pem +3894 -0
  20. data/lib/skylight/formatters/http.rb +17 -0
  21. data/lib/skylight/gc.rb +107 -0
  22. data/lib/skylight/helpers.rb +137 -0
  23. data/lib/skylight/instrumenter.rb +290 -0
  24. data/lib/skylight/middleware.rb +75 -0
  25. data/lib/skylight/native.rb +69 -0
  26. data/lib/skylight/normalizers.rb +133 -0
  27. data/lib/skylight/normalizers/action_controller/process_action.rb +35 -0
  28. data/lib/skylight/normalizers/action_controller/send_file.rb +76 -0
  29. data/lib/skylight/normalizers/action_view/render_collection.rb +18 -0
  30. data/lib/skylight/normalizers/action_view/render_partial.rb +18 -0
  31. data/lib/skylight/normalizers/action_view/render_template.rb +18 -0
  32. data/lib/skylight/normalizers/active_record/sql.rb +79 -0
  33. data/lib/skylight/normalizers/active_support/cache.rb +50 -0
  34. data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
  35. data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
  36. data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
  37. data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
  38. data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
  39. data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
  40. data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
  41. data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
  42. data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
  43. data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
  44. data/lib/skylight/normalizers/default.rb +21 -0
  45. data/lib/skylight/normalizers/moped/query.rb +141 -0
  46. data/lib/skylight/probes.rb +91 -0
  47. data/lib/skylight/probes/excon.rb +25 -0
  48. data/lib/skylight/probes/excon/middleware.rb +65 -0
  49. data/lib/skylight/probes/net_http.rb +44 -0
  50. data/lib/skylight/probes/redis.rb +30 -0
  51. data/lib/skylight/probes/sequel.rb +30 -0
  52. data/lib/skylight/probes/sinatra.rb +74 -0
  53. data/lib/skylight/probes/tilt.rb +27 -0
  54. data/lib/skylight/railtie.rb +122 -0
  55. data/lib/skylight/sinatra.rb +4 -0
  56. data/lib/skylight/subscriber.rb +92 -0
  57. data/lib/skylight/trace.rb +191 -0
  58. data/lib/skylight/util.rb +16 -0
  59. data/lib/skylight/util/allocation_free.rb +17 -0
  60. data/lib/skylight/util/clock.rb +53 -0
  61. data/lib/skylight/util/gzip.rb +15 -0
  62. data/lib/skylight/util/hostname.rb +17 -0
  63. data/lib/skylight/util/http.rb +218 -0
  64. data/lib/skylight/util/inflector.rb +110 -0
  65. data/lib/skylight/util/logging.rb +87 -0
  66. data/lib/skylight/util/multi_io.rb +21 -0
  67. data/lib/skylight/util/native_ext_fetcher.rb +205 -0
  68. data/lib/skylight/util/platform.rb +67 -0
  69. data/lib/skylight/util/ssl.rb +50 -0
  70. data/lib/skylight/vendor/active_support/notifications.rb +207 -0
  71. data/lib/skylight/vendor/active_support/notifications/fanout.rb +159 -0
  72. data/lib/skylight/vendor/active_support/notifications/instrumenter.rb +72 -0
  73. data/lib/skylight/vendor/active_support/per_thread_registry.rb +52 -0
  74. data/lib/skylight/vendor/cli/highline.rb +1034 -0
  75. data/lib/skylight/vendor/cli/highline/color_scheme.rb +134 -0
  76. data/lib/skylight/vendor/cli/highline/compatibility.rb +16 -0
  77. data/lib/skylight/vendor/cli/highline/import.rb +41 -0
  78. data/lib/skylight/vendor/cli/highline/menu.rb +381 -0
  79. data/lib/skylight/vendor/cli/highline/question.rb +481 -0
  80. data/lib/skylight/vendor/cli/highline/simulate.rb +48 -0
  81. data/lib/skylight/vendor/cli/highline/string_extensions.rb +111 -0
  82. data/lib/skylight/vendor/cli/highline/style.rb +181 -0
  83. data/lib/skylight/vendor/cli/highline/system_extensions.rb +242 -0
  84. data/lib/skylight/vendor/cli/thor.rb +473 -0
  85. data/lib/skylight/vendor/cli/thor/actions.rb +318 -0
  86. data/lib/skylight/vendor/cli/thor/actions/create_file.rb +105 -0
  87. data/lib/skylight/vendor/cli/thor/actions/create_link.rb +60 -0
  88. data/lib/skylight/vendor/cli/thor/actions/directory.rb +119 -0
  89. data/lib/skylight/vendor/cli/thor/actions/empty_directory.rb +137 -0
  90. data/lib/skylight/vendor/cli/thor/actions/file_manipulation.rb +314 -0
  91. data/lib/skylight/vendor/cli/thor/actions/inject_into_file.rb +109 -0
  92. data/lib/skylight/vendor/cli/thor/base.rb +652 -0
  93. data/lib/skylight/vendor/cli/thor/command.rb +136 -0
  94. data/lib/skylight/vendor/cli/thor/core_ext/hash_with_indifferent_access.rb +80 -0
  95. data/lib/skylight/vendor/cli/thor/core_ext/io_binary_read.rb +12 -0
  96. data/lib/skylight/vendor/cli/thor/core_ext/ordered_hash.rb +100 -0
  97. data/lib/skylight/vendor/cli/thor/error.rb +28 -0
  98. data/lib/skylight/vendor/cli/thor/group.rb +282 -0
  99. data/lib/skylight/vendor/cli/thor/invocation.rb +172 -0
  100. data/lib/skylight/vendor/cli/thor/parser.rb +4 -0
  101. data/lib/skylight/vendor/cli/thor/parser/argument.rb +74 -0
  102. data/lib/skylight/vendor/cli/thor/parser/arguments.rb +171 -0
  103. data/lib/skylight/vendor/cli/thor/parser/option.rb +121 -0
  104. data/lib/skylight/vendor/cli/thor/parser/options.rb +218 -0
  105. data/lib/skylight/vendor/cli/thor/rake_compat.rb +72 -0
  106. data/lib/skylight/vendor/cli/thor/runner.rb +322 -0
  107. data/lib/skylight/vendor/cli/thor/shell.rb +88 -0
  108. data/lib/skylight/vendor/cli/thor/shell/basic.rb +393 -0
  109. data/lib/skylight/vendor/cli/thor/shell/color.rb +148 -0
  110. data/lib/skylight/vendor/cli/thor/shell/html.rb +127 -0
  111. data/lib/skylight/vendor/cli/thor/util.rb +270 -0
  112. data/lib/skylight/vendor/cli/thor/version.rb +3 -0
  113. data/lib/skylight/vendor/thread_safe.rb +126 -0
  114. data/lib/skylight/vendor/thread_safe/non_concurrent_cache_backend.rb +133 -0
  115. data/lib/skylight/vendor/thread_safe/synchronized_cache_backend.rb +76 -0
  116. data/lib/skylight/version.rb +4 -0
  117. data/lib/skylight/vm/gc.rb +70 -0
  118. data/lib/sql_lexer.rb +6 -0
  119. data/lib/sql_lexer/lexer.rb +579 -0
  120. data/lib/sql_lexer/string_scanner.rb +11 -0
  121. data/lib/sql_lexer/version.rb +3 -0
  122. metadata +179 -0
@@ -0,0 +1,110 @@
1
+ module Skylight
2
+ module Util
3
+ module Inflector
4
+ extend self
5
+
6
+ # From https://github.com/rails/rails/blob/f8e5022c73679f41db9bb6743179bab4571fb28e/activesupport/lib/active_support/inflector/methods.rb
7
+
8
+ # Tries to find a constant with the name specified in the argument string.
9
+ #
10
+ # 'Module'.constantize # => Module
11
+ # 'Test::Unit'.constantize # => Test::Unit
12
+ #
13
+ # The name is assumed to be the one of a top-level constant, no matter
14
+ # whether it starts with "::" or not. No lexical context is taken into
15
+ # account:
16
+ #
17
+ # C = 'outside'
18
+ # module M
19
+ # C = 'inside'
20
+ # C # => 'inside'
21
+ # 'C'.constantize # => 'outside', same as ::C
22
+ # end
23
+ #
24
+ # NameError is raised when the name is not in CamelCase or the constant is
25
+ # unknown.
26
+ def constantize(camel_cased_word)
27
+ names = camel_cased_word.split('::')
28
+
29
+ # Trigger a builtin NameError exception including the ill-formed constant in the message.
30
+ Object.const_get(camel_cased_word) if names.empty?
31
+
32
+ # Remove the first blank element in case of '::ClassName' notation.
33
+ names.shift if names.size > 1 && names.first.empty?
34
+
35
+ names.inject(Object) do |constant, name|
36
+ if constant == Object
37
+ constant.const_get(name)
38
+ else
39
+ candidate = constant.const_get(name)
40
+ next candidate if constant.const_defined?(name, false)
41
+ next candidate unless Object.const_defined?(name)
42
+
43
+ # Go down the ancestors to check it it's owned
44
+ # directly before we reach Object or the end of ancestors.
45
+ constant = constant.ancestors.inject do |const, ancestor|
46
+ break const if ancestor == Object
47
+ break ancestor if ancestor.const_defined?(name, false)
48
+ const
49
+ end
50
+
51
+ # owner is in Object, so raise
52
+ constant.const_get(name, false)
53
+ end
54
+ end
55
+ end
56
+
57
+ # Tries to find a constant with the name specified in the argument string.
58
+ #
59
+ # 'Module'.safe_constantize # => Module
60
+ # 'Test::Unit'.safe_constantize # => Test::Unit
61
+ #
62
+ # The name is assumed to be the one of a top-level constant, no matter
63
+ # whether it starts with "::" or not. No lexical context is taken into
64
+ # account:
65
+ #
66
+ # C = 'outside'
67
+ # module M
68
+ # C = 'inside'
69
+ # C # => 'inside'
70
+ # 'C'.safe_constantize # => 'outside', same as ::C
71
+ # end
72
+ #
73
+ # +nil+ is returned when the name is not in CamelCase or the constant (or
74
+ # part of it) is unknown.
75
+ #
76
+ # 'blargle'.safe_constantize # => nil
77
+ # 'UnknownModule'.safe_constantize # => nil
78
+ # 'UnknownModule::Foo::Bar'.safe_constantize # => nil
79
+ def safe_constantize(camel_cased_word)
80
+ constantize(camel_cased_word)
81
+ rescue NameError => e
82
+ raise unless e.message =~ /(uninitialized constant|wrong constant name) #{const_regexp(camel_cased_word)}$/ ||
83
+ e.name.to_s == camel_cased_word.to_s
84
+ rescue ArgumentError => e
85
+ raise unless e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/
86
+ end
87
+
88
+ private
89
+
90
+ # Mount a regular expression that will match part by part of the constant.
91
+ #
92
+ # const_regexp("Foo::Bar::Baz") # => /(Foo(::Bar(::Baz)?)?|Bar|Baz)/
93
+ # const_regexp("::") # => /::/
94
+ #
95
+ # NOTE: We also add each part in singly, because sometimes a search for a missing
96
+ # constant like Skylight::Foo::Bar will return an error just saying Foo was missing
97
+ def const_regexp(camel_cased_word) #:nodoc:
98
+ parts = camel_cased_word.split("::")
99
+
100
+ return Regexp.escape(camel_cased_word) if parts.empty?
101
+
102
+ regexp = parts.reverse.inject do |acc, part|
103
+ part.empty? ? acc : "#{part}(::#{acc})?"
104
+ end
105
+
106
+ "(" + ([regexp] + parts[1..-1]).join('|') + ")"
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,87 @@
1
+ require 'logger'
2
+
3
+ module Skylight
4
+ module Util
5
+ # Log both to the specified logger and STDOUT
6
+ class AlertLogger
7
+ def initialize(logger)
8
+ @logger = logger
9
+ end
10
+
11
+ def write(*args)
12
+ STDERR.write *args
13
+ @logger.<<(*args)
14
+ end
15
+
16
+ def close
17
+ end
18
+ end
19
+
20
+ module Logging
21
+ def self.trace?
22
+ ENV[TRACE_ENV_KEY]
23
+ end
24
+
25
+ if trace?
26
+ def trace(msg, *args)
27
+ log :debug, msg, *args
28
+ end
29
+
30
+ def t
31
+ log :debug, yield
32
+ end
33
+ else
34
+ def trace(*)
35
+ end
36
+
37
+ def t
38
+ end
39
+ end
40
+
41
+ def debug(msg, *args)
42
+ log :debug, msg, *args
43
+ end
44
+
45
+ def info(msg, *args)
46
+ log :info, msg, *args
47
+ end
48
+
49
+ def warn(msg, *args)
50
+ log :warn, msg, *args
51
+ end
52
+
53
+ def error(msg, *args)
54
+ log :error, msg, *args
55
+ end
56
+
57
+ alias log_trace trace
58
+ alias log_debug debug
59
+ alias log_info info
60
+ alias log_warn warn
61
+ alias log_error error
62
+
63
+ alias fmt sprintf
64
+
65
+ def log(level, msg, *args)
66
+ return unless respond_to?(:config)
67
+ return unless c = config
68
+
69
+ if logger = c.logger
70
+ return unless logger.respond_to?(level)
71
+
72
+ if args.length > 0
73
+ logger.send level, sprintf("[SKYLIGHT] [#{Skylight::VERSION}] #{msg}", *args)
74
+ else
75
+ logger.send level, "[SKYLIGHT] [#{Skylight::VERSION}] #{msg}"
76
+ end
77
+ end
78
+ rescue Exception => e
79
+ if ENV[TRACE_ENV_KEY]
80
+ puts "[ERROR] #{e.message}"
81
+ puts e.backtrace
82
+ end
83
+ end
84
+
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,21 @@
1
+ # Util allowing proxying writes to multiple location
2
+ # Used from extconf
3
+ module Skylight
4
+ module Util
5
+ class MultiIO
6
+
7
+ def initialize(*targets)
8
+ @targets = targets
9
+ end
10
+
11
+ def write(*args)
12
+ @targets.each {|t| t.write(*args)}
13
+ end
14
+
15
+ def close
16
+ @targets.each(&:close)
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,205 @@
1
+ require 'uri'
2
+ require 'logger'
3
+ require 'net/http'
4
+ require 'fileutils'
5
+ require 'digest/sha2'
6
+ require 'skylight/util/ssl'
7
+
8
+ # Used from extconf.rb
9
+ module Skylight
10
+ module Util
11
+ class NativeExtFetcher
12
+ BASE_URL = "https://s3.amazonaws.com/skylight-agent-packages/skylight-native"
13
+ MAX_REDIRECTS = 5
14
+ MAX_RETRIES = 3
15
+
16
+ include FileUtils
17
+
18
+ class FetchError < StandardError; end
19
+
20
+ def self.fetch(opts = {})
21
+ fetcher = new(
22
+ BASE_URL,
23
+ opts[:target],
24
+ opts[:version],
25
+ opts[:checksum],
26
+ opts[:arch],
27
+ opts[:required],
28
+ opts[:platform],
29
+ opts[:logger] || Logger.new(STDOUT))
30
+
31
+ fetcher.fetch
32
+ end
33
+
34
+ def initialize(source, target, version, checksum, arch, required, platform, log)
35
+ raise "source required" unless source
36
+ raise "target required" unless target
37
+ raise "checksum required" unless checksum
38
+ raise "arch required" unless arch
39
+
40
+ @source = source
41
+ @target = target
42
+ @version = version
43
+ @checksum = checksum
44
+ @required = required
45
+ @platform = platform
46
+ @arch = arch
47
+ @log = log
48
+ end
49
+
50
+ def fetch
51
+ log "fetching native ext; curr-platform=#{@platform}; " \
52
+ "requested-arch=#{@arch}; version=#{@version}"
53
+
54
+ tar_gz = "#{@target}/#{basename}"
55
+
56
+ unless sha2 = fetch_native_ext(source_uri, tar_gz, MAX_RETRIES, MAX_REDIRECTS)
57
+ maybe_raise "could not fetch native extension"
58
+ return
59
+ end
60
+
61
+ unless verify_checksum(sha2)
62
+ maybe_raise "could not verify checksum"
63
+ return
64
+ end
65
+
66
+ Dir.chdir File.dirname(tar_gz) do
67
+ system "tar xzvf #{tar_gz}"
68
+ end
69
+
70
+ true
71
+ ensure
72
+ rm_f tar_gz if tar_gz
73
+ end
74
+
75
+ def fetch_native_ext(uri, out, attempts, redirects)
76
+ redirects.times do |i|
77
+ # Ensure the location is available
78
+ mkdir_p File.dirname(out)
79
+ rm_f out
80
+
81
+ remaining_attempts = attempts
82
+
83
+ log "attempting to fetch from remote; uri=#{uri}"
84
+
85
+ begin
86
+ host, port, use_ssl, path = deconstruct_uri(uri)
87
+
88
+ File.open out, 'w' do |f|
89
+ res, extra = http_get(host, port, use_ssl, path, f)
90
+
91
+ case res
92
+ when :success
93
+ log "successfully downloaded native ext; out=#{out}"
94
+ return extra
95
+ else
96
+ log "fetching native ext; uri=#{uri}; redirected=#{res}"
97
+ uri = res
98
+
99
+ next
100
+ end
101
+ end
102
+ rescue => e
103
+ remaining_attempts -= 1
104
+
105
+ error "failed to fetch native extension; uri=#{uri}; msg=#{e.message}; remaining-attempts=#{remaining_attempts}", e
106
+
107
+ if remaining_attempts > 0
108
+ sleep 2
109
+ retry
110
+ end
111
+
112
+ return
113
+ end
114
+ end
115
+
116
+ log "exceeded max redirects"
117
+ return
118
+ end
119
+
120
+ def http_get(host, port, use_ssl, path, out)
121
+ if http_proxy = ENV['HTTP_PROXY'] || ENV['http_proxy']
122
+ log "connecting with proxy: #{http_proxy}"
123
+ uri = URI.parse(http_proxy)
124
+ p_host, p_port = uri.host, uri.port
125
+ p_user, p_pass = uri.userinfo.split(/:/) if uri.userinfo
126
+ end
127
+
128
+ opts = {}
129
+ opts[:use_ssl] = use_ssl
130
+
131
+ if use_ssl
132
+ opts[:ca_file] = SSL.ca_cert_file_or_default
133
+ end
134
+
135
+ Net::HTTP.start(host, port, p_host, p_port, p_user, p_pass, use_ssl: use_ssl) do |http|
136
+ http.request_get path do |resp|
137
+ case resp
138
+ when Net::HTTPSuccess
139
+ digest = Digest::SHA2.new
140
+
141
+ resp.read_body do |chunk|
142
+ digest << chunk
143
+ out.write chunk
144
+ end
145
+
146
+ return [ :success, digest.hexdigest ]
147
+ when Net::HTTPRedirection
148
+ unless location = resp['location']
149
+ raise "received redirect but no location"
150
+ end
151
+
152
+ return [ :redirect, location ]
153
+ else
154
+ raise "received HTTP status code #{resp.code}"
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ def verify_checksum(actual)
161
+ unless @checksum == actual
162
+ log "checksum mismatch; expected=#{@checksum}; actual=#{actual}"
163
+ return false
164
+ end
165
+
166
+ true
167
+ rescue Exception => e
168
+ error "failed to read skylight agent archive; e=#{e.message}"
169
+ false
170
+ end
171
+
172
+ def basename
173
+ "skylight_#{@arch}.tar.gz"
174
+ end
175
+
176
+ def source_uri
177
+ "#{@source}/#{@version}/#{basename}"
178
+ end
179
+
180
+ def deconstruct_uri(uri)
181
+ uri = URI(uri)
182
+ [ uri.host, uri.port, uri.scheme == 'https', uri.request_uri ]
183
+ end
184
+
185
+ def maybe_raise(err)
186
+ error err
187
+
188
+ if @required
189
+ raise err
190
+ end
191
+ end
192
+
193
+ def log(msg)
194
+ msg = "[SKYLIGHT] #{msg}"
195
+ @log.info msg
196
+ end
197
+
198
+ def error(msg, e=nil)
199
+ msg = "[SKYLIGHT] #{msg}"
200
+ msg << "\n#{e.backtrace.join("\n")}" if e
201
+ @log.error msg
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,67 @@
1
+ require 'rbconfig'
2
+
3
+ # Used from extconf and to load libskylight
4
+ module Skylight
5
+ module Util
6
+ module Platform
7
+ # Normalize the platform OS
8
+ OS = case os = RbConfig::CONFIG['host_os'].downcase
9
+ when /linux/
10
+ "linux"
11
+ when /darwin/
12
+ "darwin"
13
+ when /freebsd/
14
+ "freebsd"
15
+ when /netbsd/
16
+ "netbsd"
17
+ when /openbsd/
18
+ "openbsd"
19
+ when /sunos|solaris/
20
+ "solaris"
21
+ when /mingw|mswin/
22
+ "windows"
23
+ else
24
+ os
25
+ end
26
+
27
+ # Normalize the platform CPU
28
+ ARCH = case cpu = RbConfig::CONFIG['host_cpu'].downcase
29
+ when /amd64|x86_64/
30
+ "x86_64"
31
+ when /i?86|x86|i86pc/
32
+ "x86"
33
+ when /ppc|powerpc/
34
+ "powerpc"
35
+ when /^arm/
36
+ "arm"
37
+ else
38
+ cpu
39
+ end
40
+
41
+ LIBEXT = case OS
42
+ when /darwin/
43
+ 'dylib'
44
+ when /linux|bsd|solaris/
45
+ 'so'
46
+ when /windows|cygwin/
47
+ 'dll'
48
+ else
49
+ 'so'
50
+ end
51
+
52
+ TUPLE = "#{ARCH}-#{OS}"
53
+
54
+ def self.tuple
55
+ TUPLE
56
+ end
57
+
58
+ def self.libext
59
+ LIBEXT
60
+ end
61
+
62
+ def self.dlext
63
+ RbConfig::CONFIG['DLEXT']
64
+ end
65
+ end
66
+ end
67
+ end