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,79 @@
1
+ require "sql_lexer"
2
+ require "json"
3
+
4
+ module Skylight
5
+ module Normalizers
6
+ module ActiveRecord
7
+ class SQL < Normalizer
8
+ register "sql.active_record"
9
+ register "sql.sequel"
10
+ register "sql.data_mapper"
11
+
12
+ CAT = "db.sql.query".freeze
13
+
14
+ def normalize(trace, name, payload)
15
+ case payload[:name]
16
+ when "SCHEMA", "CACHE"
17
+ return :skip
18
+ else
19
+ name = CAT
20
+ title = payload[:name] || "SQL"
21
+ end
22
+
23
+ binds = payload[:binds]
24
+
25
+ if binds && !binds.empty?
26
+ binds = binds.map { |col, val| val.inspect }
27
+ end
28
+
29
+ extracted_title, sql, binds, _ = extract_binds(payload, binds)
30
+ title = extracted_title if extracted_title
31
+
32
+ if sql
33
+ annotations = {
34
+ sql: sql,
35
+ binds: binds,
36
+ }
37
+ end
38
+
39
+ [ name, title, sql, annotations ]
40
+ end
41
+
42
+ private
43
+ def extract_binds(payload, precalculated)
44
+ title, sql, binds = SqlLexer::Lexer.bindify(payload[:sql], precalculated, true)
45
+ [ title, sql, binds, nil ]
46
+ rescue => e
47
+ group = "sql_parse"
48
+ description = e.inspect
49
+ details = encode(backtrace: e.backtrace,
50
+ original_exception: {
51
+ class_name: e.class.name,
52
+ message: e.message
53
+ },
54
+ payload: payload,
55
+ precalculated: precalculated)
56
+
57
+ error = [group, description, details]
58
+ [ nil, nil, nil, error ]
59
+ end
60
+
61
+ # While operating in place would save memory, some of these passed in items are re-used elsewhere
62
+ # and, as such, should not be modified.
63
+ def encode(body)
64
+ if body.is_a?(Hash)
65
+ hash = {}
66
+ body.each{|k,v| hash[k] = encode(v) }
67
+ hash
68
+ elsif body.is_a?(Array)
69
+ body.map{|v| encode(v) }
70
+ elsif body.respond_to?(:encoding) && (body.encoding == Encoding::BINARY || !body.valid_encoding?)
71
+ Base64.encode64(body)
72
+ else
73
+ body
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,50 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ # NOTE: Instrumentation may not be turned on by default and is possibly buggy
5
+ # https://github.com/mperham/dalli/pull/284
6
+ class Cache < Normalizer
7
+ %w(clear
8
+ decrement
9
+ delete
10
+ exist
11
+ fetch_hit
12
+ generate
13
+ increment
14
+ read
15
+ read_multi
16
+ write).each do |type|
17
+ require "skylight/normalizers/active_support/cache_#{type}"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ # See https://github.com/rails/rails/pull/15943
25
+ if defined?(ActiveSupport::Cache::Store.instrument)
26
+ deprecated = false
27
+
28
+ # If it's deprecated, setting to false will cause a deprecation warning
29
+ # and the value will remain true
30
+ ActiveSupport::Deprecation.silence do
31
+ ActiveSupport::Cache::Store.instrument = false
32
+ deprecated = ActiveSupport::Cache::Store.instrument
33
+ end
34
+
35
+ unless deprecated
36
+ class ActiveSupport::Cache::Store
37
+ def self.instrument
38
+ true
39
+ end
40
+
41
+ def self.instrument=(val)
42
+ unless val
43
+ Rails.logger.warn "[WARNING] Skylight has patched ActiveSupport::Cache::Store.instrument to always be true. " \
44
+ "In future versions of Rails, this method will no longer be settable. " \
45
+ "See https://github.com/rails/rails/pull/15943 for more information."
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheClear < Cache
5
+ register "cache_clear.active_support"
6
+
7
+ CAT = "app.cache.clear".freeze
8
+ TITLE = "cache clear".freeze
9
+
10
+ def normalize(trace, name, payload)
11
+ [ CAT, TITLE, nil, payload ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheDecrement < Cache
5
+ register "cache_decrement.active_support"
6
+
7
+ CAT = "app.cache.decrement".freeze
8
+ TITLE = "cache decrement"
9
+
10
+ def normalize(trace, name, payload)
11
+ [ CAT, TITLE, nil, payload ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheDelete < Cache
5
+ register "cache_delete.active_support"
6
+
7
+ CAT = "app.cache.delete".freeze
8
+ TITLE = "cache delete"
9
+
10
+ def normalize(trace, name, payload)
11
+ [ CAT, TITLE, nil, payload ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheExist < Cache
5
+ register "cache_exist?.active_support"
6
+
7
+ CAT = "app.cache.exist".freeze
8
+ TITLE = "cache exist?"
9
+
10
+ def normalize(trace, name, payload)
11
+ [ CAT, TITLE, nil, payload ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheFetchHit < Cache
5
+ register "cache_fetch_hit.active_support"
6
+
7
+ CAT = "app.cache.fetch_hit".freeze
8
+ TITLE = "cache fetch hit"
9
+
10
+ def normalize(trace, name, payload)
11
+ [ CAT, TITLE, nil, payload ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheGenerate < Cache
5
+ register "cache_generate.active_support"
6
+
7
+ CAT = "app.cache.generate".freeze
8
+ TITLE = "cache generate"
9
+
10
+ def normalize(trace, name, payload)
11
+ [ CAT, TITLE, nil, payload ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheIncrement < Cache
5
+ register "cache_increment.active_support"
6
+
7
+ CAT = "app.cache.increment".freeze
8
+ TITLE = "cache increment"
9
+
10
+ def normalize(trace, name, payload)
11
+ [ CAT, TITLE, nil, payload ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheRead < Cache
5
+ register "cache_read.active_support"
6
+
7
+ CAT = "app.cache.read".freeze
8
+ TITLE = "cache read"
9
+
10
+ def normalize(trace, name, payload)
11
+ [ CAT, TITLE, nil, payload ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheReadMulti < Cache
5
+ register "cache_read_multi.active_support"
6
+
7
+ CAT = "app.cache.read_multi".freeze
8
+ TITLE = "cache read multi"
9
+
10
+ def normalize(trace, name, payload)
11
+ [ CAT, TITLE, nil, payload ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheWrite < Cache
5
+ register "cache_write.active_support"
6
+
7
+ CAT = "app.cache.write".freeze
8
+ TITLE = "cache write"
9
+
10
+ def normalize(trace, name, payload)
11
+ [ CAT, TITLE, nil, payload ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ module Skylight
2
+ module Normalizers
3
+ class Default
4
+
5
+ def normalize(trace, name, payload)
6
+ if name =~ TIER_REGEX
7
+ annot = payload.dup
8
+ [
9
+ name,
10
+ annot.delete(:title),
11
+ annot.delete(:description),
12
+ annot
13
+ ]
14
+ else
15
+ :skip
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,141 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module Moped
4
+ class Query < Normalizer
5
+ register "query.moped"
6
+
7
+ CAT = "db.mongo.query".freeze
8
+
9
+ def normalize(trace, name, payload)
10
+ # payload: { prefix: " MOPED: #{address.resolved}", ops: operations }
11
+
12
+ # We can sometimes have multiple operations. However, it seems like this only happens when doing things
13
+ # like an insert, followed by a get last error, so we can probably ignore all but the first.
14
+ operation = payload[:ops] ? payload[:ops].first : nil
15
+ type = operation && operation.class.to_s =~ /^Moped::Protocol::(.+)$/ ? $1 : nil
16
+
17
+ case type
18
+ when "Query" then normalize_query(operation)
19
+ when "GetMore" then normalize_get_more(operation)
20
+ when "Insert" then normalize_insert(operation)
21
+ when "Update" then normalize_update(operation)
22
+ when "Delete" then normalize_delete(operation)
23
+ else :skip
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def normalize_query(operation)
30
+ title = normalize_title("QUERY", operation)
31
+
32
+ hash, binds = extract_binds(operation.selector)
33
+ description = hash.to_json
34
+
35
+ annotations = build_annotations(operation)
36
+ annotations[:skip] = operation.skip
37
+ if operation.fields
38
+ annotations[:fields] = operation.fields.select{|k,v| v == 1 }.keys.map(&:to_s)
39
+ end
40
+ annotations[:binds] = binds unless binds.empty?
41
+
42
+ [CAT, title, description, annotations]
43
+ end
44
+
45
+ def normalize_get_more(operation)
46
+ title = normalize_title("GET_MORE", operation)
47
+
48
+ annotations = build_annotations(operation)
49
+ annotations[:limit] = operation.limit
50
+
51
+ [CAT, title, nil, annotations]
52
+ end
53
+
54
+ def normalize_insert(operation)
55
+ title = normalize_title("INSERT", operation)
56
+
57
+ annotations = build_annotations(operation)
58
+ annotations[:count] = operation.documents.count
59
+
60
+ [CAT, title, nil, annotations]
61
+ end
62
+
63
+ def normalize_update(operation)
64
+ title = normalize_title("UPDATE", operation)
65
+
66
+ selector_hash, selector_binds = extract_binds(operation.selector)
67
+ update_hash, update_binds = extract_binds(operation.update)
68
+
69
+ description = { selector: selector_hash, update: update_hash }.to_json
70
+
71
+ annotations = build_annotations(operation)
72
+
73
+ binds = {}
74
+ binds[:selector] = selector_binds unless selector_binds.empty?
75
+ binds[:update] = update_binds unless update_binds.empty?
76
+ annotations[:binds] = binds unless binds.empty?
77
+
78
+ [CAT, title, description, annotations]
79
+ end
80
+
81
+ def normalize_delete(operation)
82
+ title = normalize_title("DELETE", operation)
83
+
84
+ hash, binds = extract_binds(operation.selector)
85
+ description = hash.to_json
86
+
87
+ annotations = build_annotations(operation)
88
+ annotations[:binds] = binds unless binds.empty?
89
+
90
+ [CAT, title, description, annotations]
91
+ end
92
+
93
+ def normalize_title(type, operation)
94
+ "#{type} #{operation.collection}"
95
+ end
96
+
97
+ def build_annotations(operation)
98
+ annotations = {}
99
+
100
+ if operation.respond_to?(:flags)
101
+ flags = operation.flags.map{|f| flag_name(f) }
102
+ annotations[:flags] = flags unless flags.empty?
103
+ end
104
+
105
+ annotations
106
+ end
107
+
108
+ # Some flags used by Moped don't map directly to the Mongo docs
109
+ # See http://docs.mongodb.org/meta-driver/latest/legacy/mongodb-wire-protocol/
110
+ FLAG_MAP = {
111
+ tailable: "TailableCursor",
112
+ multi: "MultiUpdate"
113
+ }
114
+
115
+ def flag_name(flag)
116
+ FLAG_MAP[flag] || flag.to_s.sub(/^[a-z\d]*/) { $&.capitalize }.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }
117
+ end
118
+
119
+ def extract_binds(hash, binds=[])
120
+ ret = {}
121
+
122
+ hash.each do |k,v|
123
+ if v.is_a?(Hash)
124
+ ret[k] = extract_binds(v, binds)[0]
125
+ else
126
+ binds << stringify(hash[k])
127
+ ret[k] = '?'
128
+ end
129
+ end
130
+
131
+ [ret, binds]
132
+ end
133
+
134
+ def stringify(value)
135
+ value.is_a?(Regexp) ? value.inspect : value.to_s
136
+ end
137
+
138
+ end
139
+ end
140
+ end
141
+ end