log_query 0.1.1 → 0.1.2
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/README.md +5 -5
- data/bin/lq +24 -4
- data/lib/log_query/messages.rb +16 -0
- data/lib/log_query/messages/heroku_router.rb +5 -0
- data/lib/log_query/messages/heroku_web/rails.rb +44 -0
- data/lib/log_query/messages/message_type_matcher.rb +1 -1
- data/lib/log_query/screen.rb +40 -7
- data/lib/log_query/version.rb +1 -1
- data/log_query.gif +0 -0
- 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: b6a5eace67508a8f9b304887399b8850934c394e
|
4
|
+
data.tar.gz: 40b0398eed248d957935748636fb9cbdb1b6b1a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fea3044667c84a0d59691382da0216465d3738480cbd87bb5ab4929e238528e499d8fe378baaea9b4391f29edaa1790e0399a0bac08703249a465ef0c9cc276
|
7
|
+
data.tar.gz: 66ca2acebdd27e20842e861848dc2da2eb08fe5eb27d795d6a6513d29b9de801e9d57693f2c79cb5a706850fb14d21d8e791fa2a5d74211190e31cdfe250a816
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# LogQuery
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
TODO: Add description
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -16,13 +14,15 @@ And then execute:
|
|
16
14
|
|
17
15
|
$ bundle
|
18
16
|
|
19
|
-
Or install
|
17
|
+
Or install the binary as:
|
20
18
|
|
21
19
|
$ gem install log_query
|
22
20
|
|
23
21
|
## Usage
|
24
22
|
|
25
|
-
|
23
|
+
`heroku logs --tail -n 1500 | lq --group_by path --measure service --average --varience --percentile 99`
|
24
|
+
|
25
|
+

|
26
26
|
|
27
27
|
## Development
|
28
28
|
|
data/bin/lq
CHANGED
@@ -16,6 +16,7 @@ global_option('-g', '--group_by ATTRIBUTE', 'Attribute to group by')
|
|
16
16
|
global_option('-m', '--measure ATTRIBUTE', 'Attribute to measure')
|
17
17
|
global_option('-a', '--average', 'Perform average')
|
18
18
|
global_option('-p', '--percentile NUMBER', Integer,'Find nth percentile')
|
19
|
+
global_option('-c', '--count', 'Count instances of attribute')
|
19
20
|
global_option('--variance', 'Perform variance')
|
20
21
|
|
21
22
|
default_command :run
|
@@ -26,16 +27,35 @@ command :run do |c|
|
|
26
27
|
screen = Screen.new
|
27
28
|
ARGF.each_line do |line|
|
28
29
|
entry = LogEntry.from_heroku_log_line(line)
|
29
|
-
|
30
|
+
message = entry.message
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
# check which type group_by is in
|
33
|
+
if options.group_by
|
34
|
+
unless Messages.class_from_attribute(options.group_by).detect { |klass| message.is_a?(klass) }
|
35
|
+
#screen.line("#{options.group_by} is not in #{message.class} with attributes #{message.class&.attributes}")
|
36
|
+
next
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# check which type measure is in
|
41
|
+
unless Messages.class_from_attribute(options.measure).detect { |klass| message.is_a?(klass) }
|
42
|
+
#screen.line("#{options.measure} is not in #{message.class} with attributes #{message.class&.attributes}")
|
43
|
+
next
|
44
|
+
end
|
45
|
+
|
46
|
+
entries << entry
|
47
|
+
|
48
|
+
data = entries.group_by { |e| e.message.send(options.group_by) } if options.group_by
|
49
|
+
data ||= { all: entries }
|
50
|
+
|
51
|
+
data.
|
52
|
+
map { |k, es| [k, DescriptiveStatistics::Stats.new(es.map { |e| e.message.send(options.measure) } )] }.
|
34
53
|
map do |k, stats|
|
35
54
|
line = "#{k}: "
|
36
55
|
line += "mean: #{stats.mean.round(2)} " if options.average
|
37
56
|
line += "variance: #{stats.variance.round(2)} " if options.variance
|
38
57
|
line += "#{options.percentile}th: #{stats.percentile(options.percentile).round(2)} " if options.percentile
|
58
|
+
line += "count: #{stats.number} " if options.count
|
39
59
|
screen.line(line)
|
40
60
|
end
|
41
61
|
|
data/lib/log_query/messages.rb
CHANGED
@@ -1,12 +1,28 @@
|
|
1
1
|
require_relative './messages/heroku_router'
|
2
|
+
require_relative './messages/heroku_web/rails'
|
2
3
|
|
3
4
|
module Messages
|
5
|
+
def self.class_from_attribute(attr)
|
6
|
+
[HerokuRouter, HerokuWeb::Rails].select do |klass|
|
7
|
+
klass.attributes.include?(attr.to_sym)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
4
11
|
def self.resolve_message(source, dyno)
|
5
12
|
case [source, dyno]
|
13
|
+
when HerokuWeb::Rails
|
14
|
+
HerokuWeb::Rails
|
6
15
|
when HerokuRouter
|
7
16
|
HerokuRouter
|
8
17
|
else
|
9
18
|
String
|
10
19
|
end
|
11
20
|
end
|
21
|
+
|
22
|
+
# A wrapper for native string class
|
23
|
+
class String < String
|
24
|
+
def self.attributes
|
25
|
+
[]
|
26
|
+
end
|
27
|
+
end
|
12
28
|
end
|
@@ -9,6 +9,10 @@ module Messages
|
|
9
9
|
ATTRIBUTES = [:sock, :at, :code, :desc, :method, :path, :host, :request_id, :fwd, :dyno, :connect, :service, :status, :bytes]
|
10
10
|
attr_accessor *ATTRIBUTES
|
11
11
|
|
12
|
+
def self.attributes
|
13
|
+
ATTRIBUTES
|
14
|
+
end
|
15
|
+
|
12
16
|
def initialize(message)
|
13
17
|
ATTRIBUTES.
|
14
18
|
select { |attr| message.include?(" #{attr}=") }.
|
@@ -22,6 +26,7 @@ module Messages
|
|
22
26
|
end
|
23
27
|
end
|
24
28
|
|
29
|
+
|
25
30
|
def parse_value(value, attribute)
|
26
31
|
case attribute
|
27
32
|
when :sock, :at, :code, :desc, :method, :host, :request_id, :fwd, :dyno, :status
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Messages
|
2
|
+
module HerokuWeb
|
3
|
+
# 2016-10-20T17:19:51.396574+00:00 app[web.1]: Started HEAD "/" for 127.0.0.1 at 2016-10-20 17:19:51 +0000
|
4
|
+
# 2016-10-20T17:19:51.508781+00:00 app[web.1]: Processing by HomeController#index as HTML
|
5
|
+
# 2016-10-20T17:19:51.575265+00:00 app[web.1]: Rendered home/index.html.erb (53.0ms)
|
6
|
+
# 2016-10-20T17:19:51.575470+00:00 app[web.1]: Completed 500 Internal Server Error in 67ms (ActiveRecord: 0.0ms)
|
7
|
+
class Rails < MessageTypeMatcher
|
8
|
+
source 'app'
|
9
|
+
dyno 'web.*'
|
10
|
+
|
11
|
+
ATTRIBUTES = {
|
12
|
+
method: /Started ([^\s]+)/,
|
13
|
+
route: /"([^"]+)"/,
|
14
|
+
ip_address: /for (([0-9]{1,3}\.){4})/,
|
15
|
+
timestamp: /at (.*)$/,
|
16
|
+
controller: /Processing by ([^\s]+)/,
|
17
|
+
format: /as (.*)$/,
|
18
|
+
template: /Rendered ([^\s]+)/,
|
19
|
+
render_time: /\(([0-9\.]+?)ms\)/,
|
20
|
+
status: /Completed ([^\s]+)/,
|
21
|
+
total_time: /in ([0-9\.]+)ms/,
|
22
|
+
active_record_time: /ActiveRecord: ([0-9\.])ms/
|
23
|
+
}
|
24
|
+
|
25
|
+
attr_accessor *(ATTRIBUTES.keys)
|
26
|
+
|
27
|
+
def self.attributes
|
28
|
+
ATTRIBUTES.keys
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(message)
|
32
|
+
ATTRIBUTES.
|
33
|
+
select { |attr, regexp| message.match(regexp) }.
|
34
|
+
map do |attr, regexp|
|
35
|
+
value = message.match(regexp)[0]
|
36
|
+
value = Integer(value) rescue value
|
37
|
+
[attr, value]
|
38
|
+
end.each do |(key, value)|
|
39
|
+
instance_variable_set("@#{key}", value)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/log_query/screen.rb
CHANGED
@@ -1,20 +1,53 @@
|
|
1
1
|
class Screen
|
2
2
|
def initialize
|
3
|
-
@
|
4
|
-
@
|
3
|
+
@old_lines = []
|
4
|
+
@new_lines = []
|
5
|
+
@current_line = 0
|
5
6
|
end
|
6
7
|
|
7
8
|
def line(value)
|
8
|
-
@
|
9
|
-
|
9
|
+
@new_lines << value
|
10
|
+
end
|
11
|
+
|
12
|
+
def move_to(row)
|
13
|
+
#puts "moving to #{row}"
|
14
|
+
#puts "current line #{@current_line}"
|
15
|
+
diff = row - @current_line
|
16
|
+
if diff > 0
|
17
|
+
#puts "moving down #{diff.abs}"
|
18
|
+
@buffer += "\e[#{diff.abs}B"
|
19
|
+
elsif diff < 0
|
20
|
+
#puts "moving up #{diff.abs}"
|
21
|
+
@buffer += "\e[#{diff.abs}A"
|
22
|
+
end
|
23
|
+
@current_line += diff
|
10
24
|
end
|
11
25
|
|
12
|
-
def
|
13
|
-
@buffer
|
14
|
-
|
26
|
+
def delete_current_line
|
27
|
+
@buffer += "\e[2K"
|
28
|
+
end
|
29
|
+
|
30
|
+
def print_line(line)
|
31
|
+
@buffer += "#{line}\n"
|
32
|
+
@current_line += 1
|
15
33
|
end
|
16
34
|
|
17
35
|
def draw
|
36
|
+
@buffer = ""
|
37
|
+
# pad line buffers
|
38
|
+
line_count = [@old_lines.size, @new_lines.size].max
|
39
|
+
@old_lines.fill(nil, @old_lines.size, line_count) if @old_lines.size < line_count
|
40
|
+
@new_lines.fill(nil, @new_lines.size, line_count) if @new_lines.size < line_count
|
41
|
+
|
42
|
+
@old_lines.zip(@new_lines).each_with_index do |(old, new), index|
|
43
|
+
if old != new
|
44
|
+
move_to(index)
|
45
|
+
delete_current_line
|
46
|
+
print_line(new)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
@old_lines = @new_lines
|
50
|
+
@new_lines = []
|
18
51
|
print @buffer
|
19
52
|
end
|
20
53
|
end
|
data/lib/log_query/version.rb
CHANGED
data/log_query.gif
ADDED
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: log_query
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jasper Lyons
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: descriptive_statistics
|
@@ -74,10 +74,12 @@ files:
|
|
74
74
|
- lib/log_query/log_entry.rb
|
75
75
|
- lib/log_query/messages.rb
|
76
76
|
- lib/log_query/messages/heroku_router.rb
|
77
|
+
- lib/log_query/messages/heroku_web/rails.rb
|
77
78
|
- lib/log_query/messages/message_type_matcher.rb
|
78
79
|
- lib/log_query/screen.rb
|
79
80
|
- lib/log_query/version.rb
|
80
81
|
- log_query.gemspec
|
82
|
+
- log_query.gif
|
81
83
|
homepage: https://github.com/releaseplatform/log_query
|
82
84
|
licenses:
|
83
85
|
- MIT
|