skylight-core 2.0.0.beta1

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 (86) hide show
  1. checksums.yaml +7 -0
  2. data/lib/skylight/core/config.rb +454 -0
  3. data/lib/skylight/core/errors.rb +6 -0
  4. data/lib/skylight/core/fanout.rb +44 -0
  5. data/lib/skylight/core/formatters/http.rb +23 -0
  6. data/lib/skylight/core/gc.rb +107 -0
  7. data/lib/skylight/core/instrumentable.rb +144 -0
  8. data/lib/skylight/core/instrumenter.rb +249 -0
  9. data/lib/skylight/core/middleware.rb +101 -0
  10. data/lib/skylight/core/normalizers/action_controller/process_action.rb +50 -0
  11. data/lib/skylight/core/normalizers/action_controller/send_file.rb +50 -0
  12. data/lib/skylight/core/normalizers/action_view/render_collection.rb +22 -0
  13. data/lib/skylight/core/normalizers/action_view/render_partial.rb +21 -0
  14. data/lib/skylight/core/normalizers/action_view/render_template.rb +21 -0
  15. data/lib/skylight/core/normalizers/active_job/enqueue_at.rb +21 -0
  16. data/lib/skylight/core/normalizers/active_model_serializers/render.rb +26 -0
  17. data/lib/skylight/core/normalizers/active_record/instantiation.rb +17 -0
  18. data/lib/skylight/core/normalizers/active_record/sql.rb +33 -0
  19. data/lib/skylight/core/normalizers/active_support/cache.rb +20 -0
  20. data/lib/skylight/core/normalizers/active_support/cache_clear.rb +16 -0
  21. data/lib/skylight/core/normalizers/active_support/cache_decrement.rb +16 -0
  22. data/lib/skylight/core/normalizers/active_support/cache_delete.rb +16 -0
  23. data/lib/skylight/core/normalizers/active_support/cache_exist.rb +16 -0
  24. data/lib/skylight/core/normalizers/active_support/cache_fetch_hit.rb +16 -0
  25. data/lib/skylight/core/normalizers/active_support/cache_generate.rb +16 -0
  26. data/lib/skylight/core/normalizers/active_support/cache_increment.rb +16 -0
  27. data/lib/skylight/core/normalizers/active_support/cache_read.rb +16 -0
  28. data/lib/skylight/core/normalizers/active_support/cache_read_multi.rb +16 -0
  29. data/lib/skylight/core/normalizers/active_support/cache_write.rb +16 -0
  30. data/lib/skylight/core/normalizers/coach/handler_finish.rb +36 -0
  31. data/lib/skylight/core/normalizers/coach/middleware_finish.rb +23 -0
  32. data/lib/skylight/core/normalizers/couch_potato/query.rb +20 -0
  33. data/lib/skylight/core/normalizers/data_mapper/sql.rb +12 -0
  34. data/lib/skylight/core/normalizers/default.rb +27 -0
  35. data/lib/skylight/core/normalizers/elasticsearch/request.rb +20 -0
  36. data/lib/skylight/core/normalizers/faraday/request.rb +37 -0
  37. data/lib/skylight/core/normalizers/grape/endpoint.rb +30 -0
  38. data/lib/skylight/core/normalizers/grape/endpoint_render.rb +26 -0
  39. data/lib/skylight/core/normalizers/grape/endpoint_run.rb +33 -0
  40. data/lib/skylight/core/normalizers/grape/endpoint_run_filters.rb +23 -0
  41. data/lib/skylight/core/normalizers/moped/query.rb +100 -0
  42. data/lib/skylight/core/normalizers/sequel/sql.rb +12 -0
  43. data/lib/skylight/core/normalizers/sql.rb +49 -0
  44. data/lib/skylight/core/normalizers.rb +170 -0
  45. data/lib/skylight/core/probes/action_controller.rb +31 -0
  46. data/lib/skylight/core/probes/action_view.rb +37 -0
  47. data/lib/skylight/core/probes/active_model_serializers.rb +55 -0
  48. data/lib/skylight/core/probes/elasticsearch.rb +37 -0
  49. data/lib/skylight/core/probes/excon/middleware.rb +72 -0
  50. data/lib/skylight/core/probes/excon.rb +26 -0
  51. data/lib/skylight/core/probes/faraday.rb +22 -0
  52. data/lib/skylight/core/probes/grape.rb +80 -0
  53. data/lib/skylight/core/probes/httpclient.rb +46 -0
  54. data/lib/skylight/core/probes/middleware.rb +58 -0
  55. data/lib/skylight/core/probes/mongo.rb +171 -0
  56. data/lib/skylight/core/probes/mongoid.rb +21 -0
  57. data/lib/skylight/core/probes/moped.rb +39 -0
  58. data/lib/skylight/core/probes/net_http.rb +64 -0
  59. data/lib/skylight/core/probes/redis.rb +71 -0
  60. data/lib/skylight/core/probes/sequel.rb +33 -0
  61. data/lib/skylight/core/probes/sinatra.rb +69 -0
  62. data/lib/skylight/core/probes/tilt.rb +27 -0
  63. data/lib/skylight/core/probes.rb +129 -0
  64. data/lib/skylight/core/railtie.rb +166 -0
  65. data/lib/skylight/core/subscriber.rb +124 -0
  66. data/lib/skylight/core/test.rb +98 -0
  67. data/lib/skylight/core/trace.rb +190 -0
  68. data/lib/skylight/core/user_config.rb +61 -0
  69. data/lib/skylight/core/util/allocation_free.rb +26 -0
  70. data/lib/skylight/core/util/clock.rb +56 -0
  71. data/lib/skylight/core/util/deploy.rb +132 -0
  72. data/lib/skylight/core/util/gzip.rb +21 -0
  73. data/lib/skylight/core/util/inflector.rb +112 -0
  74. data/lib/skylight/core/util/logging.rb +127 -0
  75. data/lib/skylight/core/util/platform.rb +77 -0
  76. data/lib/skylight/core/util/proxy.rb +13 -0
  77. data/lib/skylight/core/util.rb +14 -0
  78. data/lib/skylight/core/vendor/active_support/notifications.rb +207 -0
  79. data/lib/skylight/core/vendor/active_support/per_thread_registry.rb +52 -0
  80. data/lib/skylight/core/vendor/thread_safe/non_concurrent_cache_backend.rb +133 -0
  81. data/lib/skylight/core/vendor/thread_safe/synchronized_cache_backend.rb +76 -0
  82. data/lib/skylight/core/vendor/thread_safe.rb +126 -0
  83. data/lib/skylight/core/version.rb +6 -0
  84. data/lib/skylight/core/vm/gc.rb +70 -0
  85. data/lib/skylight/core.rb +99 -0
  86. metadata +254 -0
@@ -0,0 +1,17 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module ActiveRecord
4
+ class Instantiation < Normalizer
5
+ register "instantiation.active_record"
6
+
7
+ CAT = "db.active_record.instantiation".freeze
8
+
9
+ def normalize(trace, name, payload)
10
+ # Payload also includes `:record_count` but this will be variable
11
+ [ CAT, "#{payload[:class_name]} Instantiation", nil]
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ require 'skylight/core/normalizers/sql'
2
+
3
+ module Skylight::Core
4
+ module Normalizers
5
+ module ActiveRecord
6
+ # Normalizer for SQL requests
7
+ class SQL < Skylight::Core::Normalizers::SQL
8
+ register "sql.active_record"
9
+
10
+ def normalize(trace, name, payload)
11
+ ret = super
12
+ return :skip if ret == :skip
13
+
14
+ name, title, description, meta = ret
15
+
16
+ meta ||= {}
17
+
18
+ # FIXME: This may not be correct if the class has a different connection
19
+ begin
20
+ config = ::ActiveRecord::Base.connection_config
21
+ meta[:adapter] = config[:adapter]
22
+ meta[:database] = config[:database]
23
+ rescue => e
24
+ warn "Unable to get ActiveRecord config; e=#{e}"
25
+ end
26
+
27
+ [name, title, description, meta]
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class Cache < Normalizer
5
+ %w(clear
6
+ decrement
7
+ delete
8
+ exist
9
+ fetch_hit
10
+ generate
11
+ increment
12
+ read
13
+ read_multi
14
+ write).each do |type|
15
+ require "skylight/core/normalizers/active_support/cache_#{type}"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight::Core
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 ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight::Core
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 ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight::Core
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 ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight::Core
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 ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight::Core
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 ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight::Core
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 ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight::Core
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 ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight::Core
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 ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight::Core
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 ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight::Core
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 ]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,36 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module Coach
4
+ class HandlerFinish < Normalizer
5
+ register "coach.handler.finish"
6
+
7
+ CAT = "app.coach.handler".freeze
8
+
9
+ # See information on the events Coach emits here:
10
+ # https://github.com/gocardless/coach#instrumentation
11
+
12
+ # Run when the handler first starts, we need to set the trace endpoint to be the
13
+ # handler name.
14
+ #
15
+ # We can expect the payload to have the :middleware key.
16
+ def normalize(trace, name, payload)
17
+ trace.endpoint = payload[:middleware]
18
+ [ CAT, payload[:middleware], nil ]
19
+ end
20
+
21
+ def normalize_after(trace, span, name, payload)
22
+ return unless config.enable_segments?
23
+
24
+ segments = []
25
+
26
+ response_status = payload.fetch(:response, {}).fetch(:status, '').to_s
27
+ segments << "error" if response_status.start_with?('4', '5')
28
+
29
+ if segments.any?
30
+ trace.endpoint += "<sk-segment>#{segments.join("+")}</sk-segment>"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,23 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module Coach
4
+ class MiddlewareFinish < Normalizer
5
+ register "coach.middleware.finish"
6
+
7
+ CAT = "app.coach.middleware".freeze
8
+
9
+ # See information on the events Coach emits here:
10
+ # https://github.com/gocardless/coach#instrumentation
11
+
12
+ # Called whenever a new middleware is executed. We can expect this to happen
13
+ # within a Coach::Handler.
14
+ #
15
+ # We can expect the payload to have the :middleware key.
16
+ def normalize(trace, name, payload)
17
+ trace.endpoint = payload[:middleware]
18
+ [ CAT, payload[:middleware], nil ]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ require "json"
2
+
3
+ module Skylight::Core
4
+ module Normalizers
5
+ module CouchPotato
6
+ class Query < Normalizer
7
+ register "couch_potato.load"
8
+ register "couch_potato.view"
9
+
10
+ CAT = "db.couch_db.query".freeze
11
+
12
+ def normalize(trace, name, payload)
13
+ description = payload[:name] if payload
14
+ _name = name.sub('couch_potato.', '')
15
+ [CAT, _name, description]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ require 'skylight/core/normalizers/sql'
2
+
3
+ module Skylight::Core
4
+ module Normalizers
5
+ module DataMapper
6
+ # Normalizer for SQL requests
7
+ class SQL < Skylight::Core::Normalizers::SQL
8
+ register "sql.data_mapper"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,27 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+
4
+ # The default normalizer, used if no other is found.
5
+ class Default
6
+
7
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
8
+ # @param name [String]
9
+ # @param payload [Hash]
10
+ # @option payload [String] :title
11
+ # @option payload [String] :description
12
+ # @return [Array, :skip] the normalized array or `:skip` if `name` is not part of a known {Skylight::TIERS tier}
13
+ def normalize(trace, name, payload)
14
+ if name =~ Skylight::TIER_REGEX
15
+ [
16
+ name,
17
+ payload[:title],
18
+ payload[:description]
19
+ ]
20
+ else
21
+ :skip
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module Elasticsearch
4
+ class Request < Normalizer
5
+ register "request.elasticsearch"
6
+
7
+ CAT = "db.elasticsearch.request".freeze
8
+
9
+ def normalize(trace, name, payload)
10
+ path = payload[:path].split('/')
11
+ title = [payload[:method], path[0]].compact.join(' ')
12
+ desc = {}
13
+ desc[:type] = path[1] if path[1]
14
+ desc[:id] = '?' if path[2]
15
+ [ CAT, title, desc.empty? ? nil : desc.to_json ]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module Faraday
4
+ class Request < Normalizer
5
+ register "request.faraday"
6
+
7
+ DISABLED_KEY = :__skylight_faraday_disabled
8
+
9
+ def self.disable
10
+ Thread.current[DISABLED_KEY] = true
11
+ yield
12
+ ensure
13
+ Thread.current[DISABLED_KEY] = false
14
+ end
15
+
16
+ def disabled?
17
+ !!Thread.current[DISABLED_KEY]
18
+ end
19
+
20
+ def normalize(_trace, _name, payload)
21
+ uri = payload[:url]
22
+
23
+ if disabled?
24
+ return :skip
25
+ end
26
+
27
+ opts = Formatters::HTTP.build_opts(payload[:method], uri.scheme, uri.host, uri.port, uri.path, uri.query)
28
+ description = opts[:title]
29
+
30
+ # We use "Faraday" as the title to differentiate it in the UI in
31
+ # case it's wrapping or is wrapped by another HTTP backend
32
+ [opts[:category], "Faraday", description, opts[:meta]]
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,30 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module Grape
4
+ class Endpoint < Normalizer
5
+ %w(run
6
+ render
7
+ run_filters).each do |type|
8
+ require "skylight/core/normalizers/grape/endpoint_#{type}"
9
+ end
10
+
11
+ private
12
+
13
+ def get_method(endpoint)
14
+ method = endpoint.options[:method].first
15
+ method = "#{method}..." if endpoint.options[:method].length > 1
16
+ method
17
+ end
18
+
19
+ def get_path(endpoint)
20
+ endpoint.options[:path].join("/")
21
+ end
22
+
23
+ def get_namespace(endpoint)
24
+ ::Grape::Namespace.joined_space(endpoint.namespace_stackable(:namespace))
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module Grape
4
+ class EndpointRender < Endpoint
5
+ register "endpoint_render.grape"
6
+
7
+ CAT = "app.grape.endpoint".freeze
8
+
9
+ def normalize(trace, name, payload)
10
+ if endpoint = payload[:endpoint]
11
+ path = get_path(endpoint)
12
+ namespace = get_namespace(endpoint)
13
+ method = get_method(endpoint)
14
+
15
+ title = [method, namespace, path].join(' ').gsub(/\s+/, ' ')
16
+
17
+ [CAT, title, nil]
18
+ else
19
+ :skip
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,33 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module Grape
4
+ class EndpointRun < Endpoint
5
+ register "endpoint_run.grape"
6
+
7
+ def normalize(trace, name, payload)
8
+ trace.endpoint = get_endpoint_name(payload[:endpoint]) if payload[:endpoint]
9
+
10
+ # We don't necessarily want this to be all instrumented since it's fairly internal.
11
+ # However, it is a good place to get the endpoint name.
12
+ :skip
13
+ end
14
+
15
+ private
16
+
17
+ def get_endpoint_name(endpoint)
18
+ method = get_method(endpoint)
19
+ path = get_path(endpoint)
20
+ namespace = get_namespace(endpoint)
21
+
22
+ if namespace && !namespace.empty?
23
+ path = "/#{path}" if path[0] != '/'
24
+ path = "#{namespace}#{path}"
25
+ end
26
+
27
+ "#{endpoint.options[:for]} [#{method}] #{path}"
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module Grape
4
+ class EndpointRunFilters < Endpoint
5
+ register "endpoint_run_filters.grape"
6
+
7
+ CAT = "app.grape.filters".freeze
8
+
9
+ def normalize(trace, name, payload)
10
+ filters = payload[:filters]
11
+ type = payload[:type]
12
+
13
+ if (!filters || filters.empty?) || !type
14
+ return :skip
15
+ end
16
+
17
+ [CAT, "#{type.to_s.capitalize} Filters", nil]
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,100 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module Moped
4
+ class Query < Normalizer
5
+ register "query.moped"
6
+
7
+ CAT = "db.mongo.query".freeze
8
+
9
+ # Normalizes a Moped operation
10
+ #
11
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
12
+ # @param name [String] ignored, only present to match API
13
+ # @param payload [Hash]
14
+ # @option payload [Array<Moped::Protocol::*>] :ops array of performed operations. Supported operations are
15
+ # `Query`, `GetMore`, `Insert`, `Update`, and `Delete`.
16
+ # @option payload [String] :prefix ignored, provided by Moped
17
+ # @return [Array, :skip] the normalized array or `:skip` if not a known operation type
18
+ def normalize(trace, name, payload)
19
+ # payload: { prefix: " MOPED: #{address.resolved}", ops: operations }
20
+
21
+ # We can sometimes have multiple operations. However, it seems like this only happens when doing things
22
+ # like an insert, followed by a get last error, so we can probably ignore all but the first.
23
+ operation = payload[:ops] ? payload[:ops].first : nil
24
+ type = operation && operation.class.to_s =~ /^Moped::Protocol::(.+)$/ ? $1 : nil
25
+
26
+ case type
27
+ when "Query".freeze then normalize_query(operation)
28
+ when "GetMore".freeze then normalize_get_more(operation)
29
+ when "Insert".freeze then normalize_insert(operation)
30
+ when "Update".freeze then normalize_update(operation)
31
+ when "Delete".freeze then normalize_delete(operation)
32
+ else :skip
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def normalize_query(operation)
39
+ title = normalize_title("QUERY".freeze, operation)
40
+
41
+ hash = extract_binds(operation.selector)
42
+ description = hash.to_json
43
+
44
+ [CAT, title, description, { database: operation.database }]
45
+ end
46
+
47
+ def normalize_get_more(operation)
48
+ title = normalize_title("GET_MORE".freeze, operation)
49
+
50
+ [CAT, title, nil, { database: operation.database }]
51
+ end
52
+
53
+ def normalize_insert(operation)
54
+ title = normalize_title("INSERT".freeze, operation)
55
+
56
+ [CAT, title, nil, { database: operation.database }]
57
+ end
58
+
59
+ def normalize_update(operation)
60
+ title = normalize_title("UPDATE".freeze, operation)
61
+
62
+ selector_hash = extract_binds(operation.selector)
63
+ update_hash = extract_binds(operation.update)
64
+
65
+ description = { selector: selector_hash, update: update_hash }.to_json
66
+
67
+ [CAT, title, description, { database: operation.database }]
68
+ end
69
+
70
+ def normalize_delete(operation)
71
+ title = normalize_title("DELETE".freeze, operation)
72
+
73
+ hash = extract_binds(operation.selector)
74
+ description = hash.to_json
75
+
76
+ [CAT, title, description, { database: operation.database }]
77
+ end
78
+
79
+ def normalize_title(type, operation)
80
+ "#{type} #{operation.collection}"
81
+ end
82
+
83
+ def extract_binds(hash)
84
+ ret = {}
85
+
86
+ hash.each do |k,v|
87
+ if v.is_a?(Hash)
88
+ ret[k] = extract_binds(v)
89
+ else
90
+ ret[k] = '?'.freeze
91
+ end
92
+ end
93
+
94
+ ret
95
+ end
96
+
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,12 @@
1
+ require 'skylight/core/normalizers/sql'
2
+
3
+ module Skylight::Core
4
+ module Normalizers
5
+ module Sequel
6
+ # Normalizer for SQL requests
7
+ class SQL < Skylight::Core::Normalizers::SQL
8
+ register "sql.sequel"
9
+ end
10
+ end
11
+ end
12
+ end