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.
- 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,91 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
# @api private
|
|
3
|
+
module Probes
|
|
4
|
+
class ProbeRegistration
|
|
5
|
+
attr_reader :klass_name, :require_paths, :probe
|
|
6
|
+
|
|
7
|
+
def initialize(klass_name, require_paths, probe)
|
|
8
|
+
@klass_name = klass_name
|
|
9
|
+
@require_paths = Array(require_paths)
|
|
10
|
+
@probe = probe
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def install
|
|
14
|
+
probe.install
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.require_hooks
|
|
19
|
+
@require_hooks ||= {}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.installed
|
|
23
|
+
@installed ||= {}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.is_available?(klass_name)
|
|
27
|
+
!!Skylight::Util::Inflector.safe_constantize(klass_name)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.register(*args)
|
|
31
|
+
registration = ProbeRegistration.new(*args)
|
|
32
|
+
|
|
33
|
+
if is_available?(registration.klass_name)
|
|
34
|
+
installed[registration.klass_name] = registration
|
|
35
|
+
registration.install
|
|
36
|
+
else
|
|
37
|
+
register_require_hook(registration)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.require_hook(require_path)
|
|
42
|
+
return unless Skylight.native?
|
|
43
|
+
|
|
44
|
+
registration = lookup_by_require_path(require_path)
|
|
45
|
+
return unless registration
|
|
46
|
+
|
|
47
|
+
# Double check constant is available
|
|
48
|
+
if is_available?(registration.klass_name)
|
|
49
|
+
installed[registration.klass_name] = registration
|
|
50
|
+
registration.install
|
|
51
|
+
|
|
52
|
+
# Don't need this to be called again
|
|
53
|
+
unregister_require_hook(registration)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.register_require_hook(registration)
|
|
58
|
+
registration.require_paths.each do |p|
|
|
59
|
+
require_hooks[p] = registration
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.unregister_require_hook(registration)
|
|
64
|
+
registration.require_paths.each do |p|
|
|
65
|
+
require_hooks.delete(p)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def self.lookup_by_require_path(require_path)
|
|
70
|
+
require_hooks[require_path]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Allow hooking require
|
|
76
|
+
# @api private
|
|
77
|
+
module ::Kernel
|
|
78
|
+
alias require_without_sk require
|
|
79
|
+
|
|
80
|
+
def require(name)
|
|
81
|
+
ret = require_without_sk(name)
|
|
82
|
+
|
|
83
|
+
begin
|
|
84
|
+
Skylight::Probes.require_hook(name)
|
|
85
|
+
rescue Exception
|
|
86
|
+
# FIXME: Log these errors
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
ret
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
module Probes
|
|
3
|
+
module Excon
|
|
4
|
+
class Probe
|
|
5
|
+
def install
|
|
6
|
+
if defined?(::Excon::Middleware)
|
|
7
|
+
# Don't require until installation since it depends on Excon being loaded
|
|
8
|
+
require 'skylight/probes/excon/middleware'
|
|
9
|
+
|
|
10
|
+
idx = ::Excon.defaults[:middlewares].index(::Excon::Middleware::Instrumentor)
|
|
11
|
+
|
|
12
|
+
# TODO: Handle possibility of idx being nil
|
|
13
|
+
::Excon.defaults[:middlewares].insert(idx, Skylight::Probes::Excon::Middleware)
|
|
14
|
+
else
|
|
15
|
+
# Using $stderr here isn't great, but we don't have a logger accessible
|
|
16
|
+
$stderr.puts "[SKYLIGHT] [#{Skylight::VERSION}] The installed version of Excon doesn't " \
|
|
17
|
+
"support Middlewares. The Excon probe will be disabled."
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
register("Excon", "excon", Excon::Probe.new)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'skylight/formatters/http'
|
|
2
|
+
|
|
3
|
+
module Skylight
|
|
4
|
+
module Probes
|
|
5
|
+
module Excon
|
|
6
|
+
class Middleware < ::Excon::Middleware::Base
|
|
7
|
+
|
|
8
|
+
# This probably won't work since config isn't defined
|
|
9
|
+
include Util::Logging
|
|
10
|
+
|
|
11
|
+
def initialize(*)
|
|
12
|
+
@requests = {}
|
|
13
|
+
super
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# TODO:
|
|
17
|
+
# - Consider whether a LIFO queue would be sufficient
|
|
18
|
+
# - Check that errors can't be called without a request
|
|
19
|
+
|
|
20
|
+
def request_call(datum)
|
|
21
|
+
begin_instrumentation(datum)
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def response_call(datum)
|
|
26
|
+
super
|
|
27
|
+
ensure
|
|
28
|
+
end_instrumentation(datum)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def error_call(datum)
|
|
32
|
+
super
|
|
33
|
+
ensure
|
|
34
|
+
end_instrumentation(datum)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def begin_instrumentation(datum)
|
|
40
|
+
method = datum[:method].to_s
|
|
41
|
+
scheme = datum[:scheme]
|
|
42
|
+
host = datum[:host]
|
|
43
|
+
# TODO: Maybe don't show other default ports like 443
|
|
44
|
+
port = datum[:port] != 80 ? datum[:port] : nil
|
|
45
|
+
path = datum[:path]
|
|
46
|
+
query = datum[:query]
|
|
47
|
+
|
|
48
|
+
opts = Formatters::HTTP.build_opts(method, scheme, host, port, path, query)
|
|
49
|
+
|
|
50
|
+
@requests[datum.object_id] = Skylight.instrument(opts)
|
|
51
|
+
rescue Exception => e
|
|
52
|
+
error "failed to begin instrumentation for Excon; msg=%s", e.message
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def end_instrumentation(datum)
|
|
56
|
+
@requests[datum.object_id].done
|
|
57
|
+
@requests.delete(datum)
|
|
58
|
+
rescue Exception => e
|
|
59
|
+
error "failed to end instrumentation for Excon; msg=%s", e.message
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'skylight/formatters/http'
|
|
2
|
+
|
|
3
|
+
module Skylight
|
|
4
|
+
module Probes
|
|
5
|
+
module NetHTTP
|
|
6
|
+
class Probe
|
|
7
|
+
def install
|
|
8
|
+
Net::HTTP.class_eval do
|
|
9
|
+
alias request_without_sk request
|
|
10
|
+
|
|
11
|
+
def request(req, body = nil, &block)
|
|
12
|
+
unless started?
|
|
13
|
+
return request_without_sk(req, body, &block)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
method = req.method
|
|
17
|
+
|
|
18
|
+
# req['host'] also includes special handling for default ports
|
|
19
|
+
host, port = req['host'] ? req['host'].split(':') : nil
|
|
20
|
+
|
|
21
|
+
# If we're connected with a persistent socket
|
|
22
|
+
host ||= self.address
|
|
23
|
+
port ||= self.port
|
|
24
|
+
|
|
25
|
+
path = req.path
|
|
26
|
+
scheme = use_ssl? ? "https" : "http"
|
|
27
|
+
|
|
28
|
+
# Contained in the path
|
|
29
|
+
query = nil
|
|
30
|
+
|
|
31
|
+
opts = Formatters::HTTP.build_opts(method, scheme, host, port, path, query)
|
|
32
|
+
|
|
33
|
+
Skylight.instrument(opts) do
|
|
34
|
+
request_without_sk(req, body, &block)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
register("Net::HTTP", "net/http", NetHTTP::Probe.new)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
module Probes
|
|
3
|
+
module Redis
|
|
4
|
+
class Probe
|
|
5
|
+
def install
|
|
6
|
+
::Redis::Client.class_eval do
|
|
7
|
+
alias call_without_sk call
|
|
8
|
+
|
|
9
|
+
def call(command, &block)
|
|
10
|
+
command_name = command[0]
|
|
11
|
+
|
|
12
|
+
return call_without_sk(command, &block) if command_name == :auth
|
|
13
|
+
|
|
14
|
+
opts = {
|
|
15
|
+
category: "db.redis.command",
|
|
16
|
+
title: command_name.upcase.to_s
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
Skylight.instrument(opts) do
|
|
20
|
+
call_without_sk(command, &block)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
register("Redis", "redis", Redis::Probe.new)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Supports 3.12.0+
|
|
2
|
+
module Skylight
|
|
3
|
+
module Probes
|
|
4
|
+
module Sequel
|
|
5
|
+
class Probe
|
|
6
|
+
def install
|
|
7
|
+
require 'sequel/database/logging'
|
|
8
|
+
::Sequel::Database.class_eval do
|
|
9
|
+
alias log_yield_without_sk log_yield
|
|
10
|
+
|
|
11
|
+
def log_yield(sql, args=nil, &block)
|
|
12
|
+
log_yield_without_sk(sql, *args) do
|
|
13
|
+
::ActiveSupport::Notifications.instrument(
|
|
14
|
+
"sql.sequel",
|
|
15
|
+
sql: sql,
|
|
16
|
+
name: "SQL",
|
|
17
|
+
binds: args
|
|
18
|
+
) do
|
|
19
|
+
block.call
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
register("Sequel", "sequel", Sequel::Probe.new)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
module Probes
|
|
3
|
+
module Sinatra
|
|
4
|
+
class Probe
|
|
5
|
+
def install
|
|
6
|
+
class << ::Sinatra::Base
|
|
7
|
+
alias build_without_sk build
|
|
8
|
+
alias compile_without_sk! compile!
|
|
9
|
+
|
|
10
|
+
def compile!(verb, path, *args, &block)
|
|
11
|
+
compile_without_sk!(verb, path, *args, &block).tap do |_, _, _, wrapper|
|
|
12
|
+
# Deal with the situation where the path is a regex, and the default behavior
|
|
13
|
+
# of Ruby stringification produces an unreadable mess
|
|
14
|
+
if path.is_a?(Regexp)
|
|
15
|
+
human_readable = "<sk-regex>%r{#{path.source}}</sk-regex>"
|
|
16
|
+
wrapper.instance_variable_set(:@route_name, "#{verb} #{human_readable}")
|
|
17
|
+
else
|
|
18
|
+
wrapper.instance_variable_set(:@route_name, "#{verb} #{path}")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Newer versions of Sinatra populate env['sinatra.route']. Polyfill older
|
|
22
|
+
# versions in a targeted but hackish way.
|
|
23
|
+
if ::Sinatra::VERSION < '1.4.0'
|
|
24
|
+
def wrapper.[](app, args)
|
|
25
|
+
app.env['sinatra.route'] = @route_name
|
|
26
|
+
super
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def build(*args, &block)
|
|
33
|
+
self.use Skylight::Middleware
|
|
34
|
+
build_without_sk(*args, &block)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
::Sinatra::Base.class_eval do
|
|
39
|
+
alias dispatch_without_sk! dispatch!
|
|
40
|
+
alias compile_template_without_sk compile_template
|
|
41
|
+
|
|
42
|
+
def dispatch!(*args, &block)
|
|
43
|
+
dispatch_without_sk!(*args, &block).tap do
|
|
44
|
+
instrumenter = Skylight::Instrumenter.instance
|
|
45
|
+
next unless instrumenter
|
|
46
|
+
trace = instrumenter.current_trace
|
|
47
|
+
next unless trace
|
|
48
|
+
|
|
49
|
+
# Set the endpoint name to the route name
|
|
50
|
+
route = env['sinatra.route']
|
|
51
|
+
trace.endpoint = route if route
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def compile_template(engine, data, options, *args, &block)
|
|
56
|
+
# Pass along a useful "virtual path" to Tilt. The Tilt probe will handle
|
|
57
|
+
# instrumenting correctly.
|
|
58
|
+
case data
|
|
59
|
+
when Symbol
|
|
60
|
+
options[:sky_virtual_path] = data.to_s
|
|
61
|
+
else
|
|
62
|
+
options[:sky_virtual_path] = "Inline template (#{engine})"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
compile_template_without_sk(engine, data, options, *args, &block)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
register("Sinatra::Base", "sinatra/base", Sinatra::Probe.new)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Supports 0.2+, though Sinatra doesn't support 2.0, and Rails doesn't work with older versions
|
|
2
|
+
module Skylight
|
|
3
|
+
module Probes
|
|
4
|
+
module Tilt
|
|
5
|
+
class Probe
|
|
6
|
+
def install
|
|
7
|
+
::Tilt::Template.class_eval do
|
|
8
|
+
alias render_without_sk render
|
|
9
|
+
|
|
10
|
+
def render(*args, &block)
|
|
11
|
+
opts = {
|
|
12
|
+
category: "view.render.template",
|
|
13
|
+
title: options[:sky_virtual_path] || "Unknown template name"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
Skylight.instrument(opts) do
|
|
17
|
+
render_without_sk(*args, &block)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
register("Tilt::Template", "tilt/template", Tilt::Probe.new)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
require 'skylight'
|
|
2
|
+
require 'rails'
|
|
3
|
+
|
|
4
|
+
module Skylight
|
|
5
|
+
# @api private
|
|
6
|
+
class Railtie < Rails::Railtie
|
|
7
|
+
config.skylight = ActiveSupport::OrderedOptions.new
|
|
8
|
+
|
|
9
|
+
# The environments in which skylight should be enabled
|
|
10
|
+
config.skylight.environments = ['production']
|
|
11
|
+
|
|
12
|
+
# The path to the configuration file
|
|
13
|
+
config.skylight.config_path = "config/skylight.yml"
|
|
14
|
+
|
|
15
|
+
# The probes to load
|
|
16
|
+
# net_http is on by default
|
|
17
|
+
# Also available: excon, redis
|
|
18
|
+
config.skylight.probes = ['net_http']
|
|
19
|
+
|
|
20
|
+
initializer 'skylight.configure' do |app|
|
|
21
|
+
# Load probes even when agent is inactive to catch probe related bugs sooner
|
|
22
|
+
load_probes
|
|
23
|
+
|
|
24
|
+
config = load_skylight_config(app)
|
|
25
|
+
|
|
26
|
+
if activate?
|
|
27
|
+
if config
|
|
28
|
+
if Instrumenter.start!(config)
|
|
29
|
+
app.middleware.insert 0, Middleware, config: config
|
|
30
|
+
Rails.logger.info "[SKYLIGHT] [#{Skylight::VERSION}] Skylight agent enabled"
|
|
31
|
+
else
|
|
32
|
+
Rails.logger.info "[SKYLIGHT] [#{Skylight::VERSION}] Unable to start"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
elsif Rails.env.development?
|
|
36
|
+
log_warning config, "[SKYLIGHT] [#{Skylight::VERSION}] Running Skylight in development mode. No data will be reported until you deploy your app.\n" \
|
|
37
|
+
"(To disable this message, set `alert_log_file` in your config.)"
|
|
38
|
+
elsif !Rails.env.test?
|
|
39
|
+
log_warning config, "[SKYLIGHT] [#{Skylight::VERSION}] You are running in the #{Rails.env} environment but haven't added it to config.skylight.environments, so no data will be sent to skylight.io."
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def log_warning(config, msg)
|
|
46
|
+
if config
|
|
47
|
+
config.alert_logger.warn(msg)
|
|
48
|
+
else
|
|
49
|
+
Rails.logger.warn(msg)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def existent_paths(paths)
|
|
54
|
+
paths.respond_to?(:existent) ? paths.existent : paths.select { |f| File.exists?(f) }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def load_skylight_config(app)
|
|
58
|
+
path = config_path(app)
|
|
59
|
+
path = nil unless File.exist?(path)
|
|
60
|
+
|
|
61
|
+
unless tmp = app.config.paths['tmp'].first
|
|
62
|
+
Rails.logger.error "[SKYLIGHT] [#{Skylight::VERSION}] tmp directory missing from rails configuration"
|
|
63
|
+
return nil
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
config = Config.load(file: path, environment: Rails.env.to_s)
|
|
67
|
+
config['root'] = Rails.root
|
|
68
|
+
|
|
69
|
+
configure_logging(config, app)
|
|
70
|
+
|
|
71
|
+
config['daemon.sockdir_path'] ||= tmp
|
|
72
|
+
config['normalizers.render.view_paths'] = existent_paths(app.config.paths["app/views"]) + [Rails.root.to_s]
|
|
73
|
+
config.validate!
|
|
74
|
+
config
|
|
75
|
+
|
|
76
|
+
rescue ConfigError => e
|
|
77
|
+
Rails.logger.error "[SKYLIGHT] [#{Skylight::VERSION}] #{e.message}; disabling Skylight agent"
|
|
78
|
+
nil
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def configure_logging(config, app)
|
|
82
|
+
if logger = app.config.skylight.logger
|
|
83
|
+
config.logger = logger
|
|
84
|
+
else
|
|
85
|
+
# Configure the log file destination
|
|
86
|
+
if log_file = app.config.skylight.log_file
|
|
87
|
+
config['log_file'] = log_file
|
|
88
|
+
elsif !config.key?('log_file')
|
|
89
|
+
config['log_file'] = File.join(Rails.root, 'log/skylight.log')
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Configure the log level
|
|
93
|
+
if level = app.config.skylight.log_level
|
|
94
|
+
config['log_level'] = level
|
|
95
|
+
elsif !config.key?('log_level')
|
|
96
|
+
if level = app.config.log_level
|
|
97
|
+
config['log_level'] = level
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def config_path(app)
|
|
104
|
+
File.expand_path(config.skylight.config_path, app.root)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def environments
|
|
108
|
+
Array(config.skylight.environments).map { |e| e && e.to_s }.compact
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def activate?
|
|
112
|
+
environments.include?(Rails.env.to_s)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def load_probes
|
|
116
|
+
probes = config.skylight.probes || []
|
|
117
|
+
probes.each do |p|
|
|
118
|
+
require "skylight/probes/#{p}"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|