truex-skylight 0.6.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.
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