skylight 0.3.17 → 0.3.18
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 +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/skylight/api.rb +20 -4
- data/lib/skylight/cli.rb +30 -31
- data/lib/skylight/helpers.rb +2 -2
- data/lib/skylight/probes/redis.rb +30 -0
- data/lib/skylight/railtie.rb +1 -1
- data/lib/skylight/version.rb +1 -1
- data/lib/skylight/worker/collector.rb +13 -4
- data/lib/sql_lexer.rb +1 -0
- data/lib/sql_lexer/lexer.rb +20 -13
- data/lib/sql_lexer/string_scanner.rb +11 -0
- data/lib/sql_lexer/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3075ceb0a4b8ed3fe217362f3600422de59ab1f
|
4
|
+
data.tar.gz: 44909ca961dc7dad62831f66bc69a845a77bd7fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0207565d0fbc49a04a4663b622efc9823883aa96315541cc5f365643a2ee588fe91db3af1b3427a1657b40a5fa6a82e48dd4bf9cb15dd0c09890b3c57141b0ab
|
7
|
+
data.tar.gz: 81b0262fcf344f564dec9ee76ae10a9086d1a330a6d77b959c58355c466e381ab9943339088c53eed2f9001cbdd52984ca14e5f25ab007a18475ecdb5ced8d8d
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 0.3.18 (July 17, 2014)
|
2
|
+
|
3
|
+
* [FEATURE] Redis probe (Not enabled by default. See http://docs.skylight.io/agent/#railtie)
|
4
|
+
* [FEATURE] Support app creation with token instead of email/password
|
5
|
+
* [BUGFIX] App creation now works even when Webmock is enabled
|
6
|
+
* [BUGFIX] Fix instrumentation for methods ending in special chars
|
7
|
+
* [BUGFIX] Improved SQL parsing
|
8
|
+
* [IMPROVEMENT] Respect collector token expiration to reduce token requests
|
9
|
+
|
1
10
|
## 0.3.17 (July 1, 2014)
|
2
11
|
|
3
12
|
* Fix warning for Cache.instrument overwrite
|
data/lib/skylight/api.rb
CHANGED
@@ -3,6 +3,20 @@ module Skylight
|
|
3
3
|
class Api
|
4
4
|
attr_reader :config, :http
|
5
5
|
|
6
|
+
class CreateFailed < StandardError
|
7
|
+
attr_reader :res
|
8
|
+
|
9
|
+
def initialize(res)
|
10
|
+
@res = res
|
11
|
+
super "failed with status #{res.status}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def errors
|
15
|
+
return unless res.body.is_a?(Hash)
|
16
|
+
res.body['errors']
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
6
20
|
def initialize(config, service = :accounts)
|
7
21
|
@config = config
|
8
22
|
@http = Util::HTTP.new(config, service)
|
@@ -24,10 +38,12 @@ module Skylight
|
|
24
38
|
end
|
25
39
|
end
|
26
40
|
|
27
|
-
def create_app(name)
|
28
|
-
|
29
|
-
|
30
|
-
res
|
41
|
+
def create_app(name, token=nil)
|
42
|
+
params = { app: { name: name } }
|
43
|
+
params[:token] = token if token
|
44
|
+
res = @http.post('/apps', params)
|
45
|
+
raise CreateFailed, res unless res.success?
|
46
|
+
res
|
31
47
|
end
|
32
48
|
|
33
49
|
end
|
data/lib/skylight/cli.rb
CHANGED
@@ -10,20 +10,19 @@ module Skylight
|
|
10
10
|
# @api private
|
11
11
|
class CLI < Thor
|
12
12
|
|
13
|
-
desc "setup", "Sets up a new app"
|
14
|
-
def setup
|
13
|
+
desc "setup TOKEN", "Sets up a new app using the provided token"
|
14
|
+
def setup(token=nil)
|
15
15
|
if File.exist?(config_path)
|
16
16
|
say "Your app is already on Skylight. http://www.skylight.io", :green
|
17
17
|
return
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
unless res = api.create_app(app_name)
|
23
|
-
say "Could not create the application", :red
|
24
|
-
return
|
20
|
+
unless token
|
21
|
+
api.authentication = login
|
25
22
|
end
|
26
23
|
|
24
|
+
res = api.create_app(app_name, token)
|
25
|
+
|
27
26
|
config[:application] = res.get('app.id')
|
28
27
|
config[:authentication] = res.get('app.token')
|
29
28
|
config.write(config_path)
|
@@ -43,6 +42,9 @@ repository and deploy from there. You can learn more about the process at:
|
|
43
42
|
http://docs.skylight.io/getting-started/#deploy
|
44
43
|
|
45
44
|
OUT
|
45
|
+
rescue Api::CreateFailed => e
|
46
|
+
say "Could not create the application", :red
|
47
|
+
say e.errors.inspect, :orange if e.errors
|
46
48
|
rescue Interrupt
|
47
49
|
end
|
48
50
|
|
@@ -51,6 +53,8 @@ repository and deploy from there. You can learn more about the process at:
|
|
51
53
|
def app_name
|
52
54
|
@app_name ||=
|
53
55
|
begin
|
56
|
+
name = nil
|
57
|
+
|
54
58
|
if File.exist?("config/application.rb")
|
55
59
|
# This looks like a Rails app, lets make sure we have the railtie loaded
|
56
60
|
# skylight.rb checks for Rails, but when running the CLI, Skylight loads before Rails does
|
@@ -60,30 +64,35 @@ repository and deploy from there. You can learn more about the process at:
|
|
60
64
|
error "Unable to load Railtie. Please notify support@skylight.io."
|
61
65
|
end
|
62
66
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
+
# Get the name in a process so that we don't pollute our environment here
|
68
|
+
# This is especially important since users may have things like WebMock that
|
69
|
+
# will prevent us from communicating with the Skylight API
|
70
|
+
begin
|
71
|
+
namefile = Tempfile.new('skylight-app-name')
|
72
|
+
`rails runner 'File.open(\"#{namefile.path}\", \"w\") {|f| f.write(Rails.application.class.name) }'`
|
73
|
+
name = namefile.read.split("::").first.underscore.titleize
|
74
|
+
ensure
|
75
|
+
namefile.close
|
76
|
+
namefile.unlink
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
if !name || name.strip.empty?
|
81
|
+
name = File.basename(File.expand_path('.')).titleize
|
67
82
|
end
|
68
|
-
end
|
69
|
-
end
|
70
83
|
|
71
|
-
|
72
|
-
|
84
|
+
name
|
85
|
+
end
|
73
86
|
end
|
74
87
|
|
75
88
|
def login
|
89
|
+
say "Please enter your email and password below or get a token from https://www.skylight.io/app/setup.", :cyan
|
90
|
+
|
76
91
|
10.times do
|
77
92
|
email = highline.ask("Email: ")
|
78
93
|
password = highline.ask("Password: ") { |q| q.echo = "*" }
|
79
94
|
|
80
95
|
if token = api.login(email, password)
|
81
|
-
# Write the token
|
82
|
-
FileUtils.mkdir_p(File.dirname(credentials_path))
|
83
|
-
File.open(credentials_path, 'w') do |f|
|
84
|
-
f.puts YAML.dump('token' => token)
|
85
|
-
end
|
86
|
-
|
87
96
|
return token
|
88
97
|
end
|
89
98
|
|
@@ -95,12 +104,6 @@ repository and deploy from there. You can learn more about the process at:
|
|
95
104
|
return
|
96
105
|
end
|
97
106
|
|
98
|
-
def load_credentials_from_file
|
99
|
-
return unless File.exist?(credentials_path)
|
100
|
-
return unless yaml = YAML.load_file(credentials_path)
|
101
|
-
yaml['token']
|
102
|
-
end
|
103
|
-
|
104
107
|
def relative_config_path
|
105
108
|
'config/skylight.yml'
|
106
109
|
end
|
@@ -109,10 +112,6 @@ repository and deploy from there. You can learn more about the process at:
|
|
109
112
|
File.expand_path(relative_config_path)
|
110
113
|
end
|
111
114
|
|
112
|
-
def credentials_path
|
113
|
-
File.expand_path(config[:'me.credentials_path'])
|
114
|
-
end
|
115
|
-
|
116
115
|
def api
|
117
116
|
@api ||= Api.new(config)
|
118
117
|
end
|
data/lib/skylight/helpers.rb
CHANGED
@@ -99,7 +99,7 @@ module Skylight
|
|
99
99
|
desc = opts[:description].to_s if opts[:description]
|
100
100
|
|
101
101
|
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
102
|
-
alias_method :"#{name}
|
102
|
+
alias_method :"before_instrument_#{name}", :"#{name}"
|
103
103
|
|
104
104
|
def #{name}(*args, &blk)
|
105
105
|
span = Skylight.instrument(
|
@@ -108,7 +108,7 @@ module Skylight
|
|
108
108
|
description: #{desc.inspect})
|
109
109
|
|
110
110
|
begin
|
111
|
-
#{name}
|
111
|
+
before_instrument_#{name}(*args, &blk)
|
112
112
|
ensure
|
113
113
|
Skylight.done(span) if span
|
114
114
|
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
|
data/lib/skylight/railtie.rb
CHANGED
data/lib/skylight/version.rb
CHANGED
@@ -180,11 +180,20 @@ module Skylight
|
|
180
180
|
return
|
181
181
|
end
|
182
182
|
|
183
|
-
|
184
|
-
tok =
|
183
|
+
session = res.body['session']
|
184
|
+
tok, expires_at = session['token'], session['expires_at'] if session
|
185
|
+
|
186
|
+
if tok && expires_at
|
187
|
+
if expires_at <= now
|
188
|
+
error "token is expired: token=%s; expires_at=%s"
|
189
|
+
return
|
190
|
+
end
|
191
|
+
|
192
|
+
# 30 minute buffer or split the difference
|
193
|
+
@refresh_at = expires_at - now > 3600 ?
|
194
|
+
now + ((expires_at - now) / 2) :
|
195
|
+
expires_at - 1800
|
185
196
|
|
186
|
-
if tok
|
187
|
-
@refresh_at = now + 1800 # 30 minutes
|
188
197
|
@http_report = Util::HTTP.new(config, :report)
|
189
198
|
@http_report.authentication = tok
|
190
199
|
else
|
data/lib/sql_lexer.rb
CHANGED
data/lib/sql_lexer/lexer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require "strscan"
|
2
4
|
|
3
5
|
module SqlLexer
|
@@ -18,8 +20,8 @@ module SqlLexer
|
|
18
20
|
OptWS = %Q<[#{WS}]*>
|
19
21
|
End = %Q<;|$>
|
20
22
|
|
21
|
-
InOp = %
|
22
|
-
ArrayOp = %q<ARRAY>
|
23
|
+
InOp = %Q<IN(?=#{OptWS}\\()>
|
24
|
+
ArrayOp = %q<ARRAY(?=\[)>
|
23
25
|
ColonColonOp = %Q<::(?=[#{StartID}])>
|
24
26
|
ArrayIndexOp = %q<\\[(?:\-?\d+(?::\-?\d+)?|NULL)\\]>
|
25
27
|
SpecialOps = %Q<#{InOp}(?=[#{WS}])|#{ColonColonOp}|#{ArrayOp}|#{ArrayIndexOp}>
|
@@ -42,7 +44,7 @@ module SqlLexer
|
|
42
44
|
|
43
45
|
AfterID = %Q<[#{WS};#{StartNonBind}]|(?:#{OpPart})|(?:#{ColonColonOp})|(?:#{ArrayIndexOp})|$>
|
44
46
|
ID = %Q<[#{StartID}][#{PartID}]*(?=#{AfterID})>
|
45
|
-
AfterOp = %Q<[#{WS}]|[#{StartAnyId}]|[#{StartBind}]|(#{StartNonBind})
|
47
|
+
AfterOp = %Q<[#{WS}]|[#{StartAnyId}]|[#{StartBind}]|(#{StartNonBind})|;|$>
|
46
48
|
Op = %Q<(?:#{OpPart})+(?=#{AfterOp})>
|
47
49
|
QuotedID = %Q<#{StartQuotedID}(?:[^"]|"")*">
|
48
50
|
TickedID = %Q<#{StartTickedID}(?:[^`]|``)*`>
|
@@ -228,7 +230,7 @@ module SqlLexer
|
|
228
230
|
# SQL allows for nested comments so this takes a bit more work
|
229
231
|
while @scanner.skip_until(TkBlockCommentStart)
|
230
232
|
count = 1
|
231
|
-
pos = @scanner.
|
233
|
+
pos = @scanner.charpos - 2
|
232
234
|
|
233
235
|
while true
|
234
236
|
# Determine whether we close the comment or start nesting
|
@@ -253,7 +255,7 @@ module SqlLexer
|
|
253
255
|
|
254
256
|
if count == 0
|
255
257
|
# We've closed all comments
|
256
|
-
length = @scanner.
|
258
|
+
length = @scanner.charpos - pos
|
257
259
|
# Dup the string if necessary so we aren't destructive to the original value
|
258
260
|
@scanner.string = @input.dup if @scanner.string == @input
|
259
261
|
# Replace the comment with spaces
|
@@ -267,7 +269,7 @@ module SqlLexer
|
|
267
269
|
|
268
270
|
# Remove single line comments
|
269
271
|
while @scanner.skip_until(TkComment)
|
270
|
-
pos = @scanner.
|
272
|
+
pos = @scanner.charpos
|
271
273
|
len = @scanner.matched_size
|
272
274
|
# Dup the string if necessary so we aren't destructive to the original value
|
273
275
|
@scanner.string = @input.dup if @scanner.string == @input
|
@@ -418,7 +420,7 @@ module SqlLexer
|
|
418
420
|
iterations = 0
|
419
421
|
|
420
422
|
@skip_binds = true
|
421
|
-
pos = @scanner.
|
423
|
+
pos = @scanner.charpos - 1
|
422
424
|
|
423
425
|
while nest > 0
|
424
426
|
iterations += 1
|
@@ -448,7 +450,7 @@ module SqlLexer
|
|
448
450
|
end
|
449
451
|
|
450
452
|
@binds << pos
|
451
|
-
@binds << @scanner.
|
453
|
+
@binds << @scanner.charpos - pos
|
452
454
|
|
453
455
|
@skip_binds = false
|
454
456
|
|
@@ -460,7 +462,7 @@ module SqlLexer
|
|
460
462
|
iterations = 0
|
461
463
|
|
462
464
|
@skip_binds = true
|
463
|
-
pos = @scanner.
|
465
|
+
pos = @scanner.charpos - 6
|
464
466
|
|
465
467
|
while nest > 0
|
466
468
|
iterations += 1
|
@@ -498,7 +500,7 @@ module SqlLexer
|
|
498
500
|
end
|
499
501
|
|
500
502
|
@binds << pos
|
501
|
-
@binds << @scanner.
|
503
|
+
@binds << @scanner.charpos - pos
|
502
504
|
|
503
505
|
@skip_binds = false
|
504
506
|
|
@@ -511,12 +513,17 @@ module SqlLexer
|
|
511
513
|
end
|
512
514
|
|
513
515
|
def process_bind
|
514
|
-
pos =
|
515
|
-
|
516
|
+
pos = nil
|
517
|
+
|
518
|
+
unless @skip_binds
|
519
|
+
pos = @scanner.charpos
|
520
|
+
end
|
521
|
+
|
522
|
+
@scanner.skip(TkBind)
|
516
523
|
|
517
524
|
unless @skip_binds
|
518
525
|
@binds << pos
|
519
|
-
@binds <<
|
526
|
+
@binds << @scanner.charpos - pos
|
520
527
|
end
|
521
528
|
|
522
529
|
@state = :tokens
|
data/lib/sql_lexer/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skylight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tilde, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07-
|
11
|
+
date: 2014-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- lib/skylight/probes/excon.rb
|
93
93
|
- lib/skylight/probes/excon/middleware.rb
|
94
94
|
- lib/skylight/probes/net_http.rb
|
95
|
+
- lib/skylight/probes/redis.rb
|
95
96
|
- lib/skylight/railtie.rb
|
96
97
|
- lib/skylight/subscriber.rb
|
97
98
|
- lib/skylight/util.rb
|
@@ -165,6 +166,7 @@ files:
|
|
165
166
|
- lib/skylight/worker/standalone.rb
|
166
167
|
- lib/sql_lexer.rb
|
167
168
|
- lib/sql_lexer/lexer.rb
|
169
|
+
- lib/sql_lexer/string_scanner.rb
|
168
170
|
- lib/sql_lexer/version.rb
|
169
171
|
homepage: http://www.skylight.io
|
170
172
|
licenses: []
|