truex-skylight 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|