log_parser 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d0266c27679963d92c477416724cc2f4d6c6c31e
4
- data.tar.gz: de90fce1a04226daed8bec5569f1ed346404affc
3
+ metadata.gz: fb1f9e6441835510f872d57775b0a110af39da64
4
+ data.tar.gz: f66ab92bb2d953afd409289012f6ab55996f8192
5
5
  SHA512:
6
- metadata.gz: 4017645035ace98a41365b214824fb574f43f8046e1b2bd7720da9b904294fea8db2ba54ea8ab8f9478e1ea627b55c94612ef23c42d5e4fcc6fac709fa4ae434
7
- data.tar.gz: d20d3857914ae340fb92e4bbf8d1c09120cb761a2ac2d17bf0286fe8905317c26e2270e11a6036bbfbdd74fc5812a15cb2fe460dfae797c8b88f901427fb2072
6
+ metadata.gz: 28f051e09df01a61e4030debadd7ccdff952a3e7e5db684f9edb92d0fd8959c96d8d9ca4daa7bb56905ffa0c1156d65ae1e61b76fd34a43afea918f378cbc4aa
7
+ data.tar.gz: 66e4fab78c195b9f1fe2622b1059e0ddc1da9b78f6d8dec9fce3b678cb1a30697fcf2f5ed2516550e720d372b76d99c11aabf65bfb028d26a4164524a6e6c164
data/Rakefile CHANGED
@@ -1,2 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'rake/testtask'
2
4
 
5
+ task default: :test
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.pattern = 'test/**/*_test.rb'
9
+ end
@@ -0,0 +1,157 @@
1
+ module LogParser
2
+ class Client
3
+ #
4
+ # = Class
5
+ #
6
+ # Filter lines from the log file by chaining methods together:
7
+ #
8
+ # log = LogParser::Client.new('open_table.log')
9
+ # log.errors.by_message('authentication failed').since(1.day.ago)
10
+ # #=> ["[2014-11-13T23:12:14-07:00] ERROR [page_id 95239] Authentication failed with token ..."]
11
+ #
12
+
13
+ LINE_PATTERN = %r{
14
+ \[(\d+-\d+-\d+T\d+:\d+:\d+-\d+:\d+)\] # timestamp
15
+ (\s(\w+):)? # type of message (ERROR, WARNING, INFO)
16
+ (\s\[(.+)\])? # prefix (introduced by log.rb)
17
+ \s(.+)$ # message body
18
+ }x
19
+
20
+ attr_reader :file
21
+ attr_writer :lines
22
+
23
+ #
24
+ # @param [String|Pathname] log name of the file in 'log' directory or a Pathname object
25
+ # @param [Hash] options optional parameters
26
+ # @option :line_items is an array of LineItem objects
27
+ # @option :pattern a custom pattern to use for matching lines
28
+ #
29
+ def initialize(log = '', options = {})
30
+ @file = log.is_a?(String) ? LogParser.path_for(log) : log
31
+ @lines = options.fetch :line_items, []
32
+ @pattern = options.fetch :pattern, LINE_PATTERN
33
+ end
34
+
35
+ #
36
+ # Chainable
37
+ #
38
+
39
+ def errors
40
+ by_type('ERROR')
41
+ end
42
+
43
+ def warnings
44
+ by_type('WARNING')
45
+ end
46
+
47
+ def infos
48
+ by_type('INFO')
49
+ end
50
+
51
+ def since(timestamp)
52
+ chain do |items|
53
+ for line in lines
54
+ items << line if DateTime.parse(line.timestamp) > timestamp
55
+ end
56
+ end
57
+ end
58
+
59
+ def by_message(text)
60
+ chain do |items|
61
+ for line in lines
62
+ items << line if line.message =~ Regexp.new(text, Regexp::IGNORECASE)
63
+ end
64
+ end
65
+ end
66
+
67
+ def by_prefix(name)
68
+ chain do |items|
69
+ for line in lines
70
+ items << line if line.prefix == name
71
+ end
72
+ end
73
+ end
74
+
75
+ def by_type(name)
76
+ chain do |items|
77
+ for line in lines
78
+ items << line if line.type == name
79
+ end
80
+ end
81
+ end
82
+
83
+ #
84
+ # Non-chainable Helpers
85
+ #
86
+
87
+ def prefixes
88
+ items = Set.new
89
+ lines.each { |line| items << line.prefix }
90
+ items.to_a.compact
91
+ end
92
+
93
+ def uniq
94
+ lines.uniq(&:full_message)
95
+ end
96
+
97
+ def timestamps
98
+ lines.map(&:timestamp)
99
+ end
100
+
101
+ def messages
102
+ lines.map(&:message)
103
+ end
104
+
105
+ def strings
106
+ lines.map(&:to_s)
107
+ end
108
+
109
+ def count
110
+ lines.count
111
+ end
112
+
113
+ def sort
114
+ lines.sort
115
+ end
116
+
117
+ #
118
+ # Default overrides
119
+ #
120
+
121
+ def to_s
122
+ Array(@lines).map(&:to_s).to_s
123
+ end
124
+
125
+ alias inspect to_s
126
+
127
+ #
128
+ # Private
129
+ #
130
+
131
+ def scan
132
+ line_items = []
133
+ File.open(file) do |f|
134
+ line = nil
135
+ begin
136
+ line = f.gets
137
+ line_items << LineItem.new($1, $3, $5, $6) if line =~ @pattern
138
+ end while line
139
+ end
140
+ line_items
141
+ end
142
+
143
+ def chain
144
+ items = []
145
+ yield items
146
+ self.class.new(file, line_items: items)
147
+ end
148
+
149
+ def lines
150
+ @lines = scan if @lines.nil? || @lines.empty?
151
+ @lines
152
+ end
153
+
154
+ alias to_a lines
155
+ end
156
+
157
+ end
@@ -0,0 +1,19 @@
1
+ module LogParser
2
+ class LineItem < Struct.new(:timestamp, :type, :prefix, :message)
3
+ def to_s
4
+ s = "[#{timestamp}] "
5
+ s << "#{type}: " if type
6
+ s << "[#{prefix}] " if prefix
7
+ s << "#{message}"
8
+ s
9
+ end
10
+
11
+ def full_message
12
+ prefix ? "[#{prefix}] #{message}" : message
13
+ end
14
+
15
+ def <=>(other)
16
+ timestamp <=> other.timestamp
17
+ end
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
- class LogParser
2
- VERSION = '0.0.1'.freeze
1
+ module LogParser
2
+ VERSION = '0.1.0'.freeze
3
3
  end
data/lib/log_parser.rb CHANGED
@@ -1,158 +1,13 @@
1
- require "log_parser/version"
1
+ require 'log_parser/version'
2
+ require 'log_parser/line_item'
3
+ require 'log_parser/client'
2
4
 
3
- class LogParser
4
- #
5
- # = Class
6
- #
7
- # Filter lines from the log file by chaining methods together:
8
- #
9
- # log = LogParser.new('open_table.log')
10
- # log.errors.by_message('authentication failed').since(1.day.ago)
11
- # #=> ["[2014-11-13T23:12:14-07:00] ERROR [page_id 95239] Authentication failed with token ..."]
12
- #
13
-
14
- LINE_PATTERN = %r{
15
- \[(\d+-\d+-\d+T\d+:\d+:\d+-\d+:\d+)\] # timestamp
16
- (\s(\w+):)? # type of message (ERROR, WARNING, INFO)
17
- (\s\[(.+)\])? # prefix (introduced by log.rb)
18
- \s(.+)$ # message body
19
- }x
20
-
21
- attr_reader :file_path
22
- attr_writer :lines
23
-
24
- # @param log [String|Pathname] The file name in the log directory or a pathname to a log file
25
- # @param line_items [Array] (optional) An array of LineItems
26
- def initialize(log = '', line_items = [])
27
- @file_path = log.is_a?(String) ? Rails.root.join('log', log) : log
28
- @lines = line_items
29
- end
30
-
31
- #
32
- # Chainable
33
- #
34
-
35
- def errors
36
- by_type('ERROR')
37
- end
38
-
39
- def warnings
40
- by_type('WARNING')
41
- end
42
-
43
- def infos
44
- by_type('INFO')
45
- end
46
-
47
- def by_message(text)
48
- chain do |items|
49
- for line in lines
50
- items << line if line.message =~ Regexp.new(text, Regexp::IGNORECASE)
51
- end
52
- end
53
- end
54
-
55
- def since(timestamp)
56
- chain do |items|
57
- for line in lines
58
- items << line if DateTime.parse(line.timestamp) > timestamp
59
- end
60
- end
61
- end
62
-
63
- def by_prefix(name)
64
- chain do |items|
65
- for line in lines
66
- items << line if line.prefix == name
67
- end
68
- end
69
- end
70
-
71
- def by_type(name)
72
- chain do |items|
73
- for line in lines
74
- items << line if line.type == name
75
- end
76
- end
77
- end
78
-
79
- #
80
- # Helpers
81
- #
82
-
83
- def prefixes
84
- items = Set.new
85
- lines.each { |line| items << line.prefix }
86
- items.to_a.compact
87
- end
88
-
89
- def timestamps
90
- lines.map(&:timestamp)
91
- end
92
-
93
- def messages
94
- lines.map(&:message)
95
- end
96
-
97
- def strings
98
- lines.map(&:to_s)
99
- end
100
-
101
- def count
102
- lines.count
103
- end
104
-
105
- def uniq
106
- lines.uniq { |line| line.full_message }
107
- end
108
-
109
- def to_s
110
- Array(@lines).map(&:to_s).to_s
5
+ module LogParser
6
+ def self.root
7
+ File.expand_path('../..', __FILE__)
111
8
  end
112
9
 
113
- alias inspect to_s
114
-
115
- #
116
- # Private
117
- #
118
-
119
- def scan
120
- line_items = []
121
- File.open(file_path) do |f|
122
- while line = f.gets
123
- line_items << LineItem.new($1, $3, $5, $6) if line =~ LINE_PATTERN
124
- end
125
- end
126
- line_items
127
- end
128
-
129
- def chain
130
- items = []
131
- yield items
132
- self.class.new(file_path, items)
133
- end
134
-
135
- def lines
136
- @lines.presence || scan
137
- end
138
-
139
- alias to_a lines
140
-
141
- class LineItem < Struct.new(:timestamp, :type, :prefix, :message)
142
- def to_s
143
- s = "[#{timestamp}] "
144
- s << "#{type}: " if type
145
- s << "[#{prefix}] " if prefix
146
- s << "#{message}"
147
- s
148
- end
149
-
150
- def full_message
151
- prefix ? "[#{prefix}] #{message}" : message
152
- end
153
-
154
- def <=>(other)
155
- timestamp <=> other.timestamp
156
- end
10
+ def self.path_for(file)
11
+ Pathname.new(File.join(root, 'log', file))
157
12
  end
158
13
  end
@@ -0,0 +1,13 @@
1
+ require 'pathname'
2
+ require 'minitest/autorun'
3
+ require 'log_parser'
4
+
5
+ class LogParser::ClientTest < MiniTest::Unit::TestCase
6
+
7
+ def test_initialize_with_string
8
+ @log = LogParser::Client.new('production.log')
9
+ assert_kind_of Pathname, @log.file_path
10
+ assert_equal '/log', @log.file_path.to_s
11
+ end
12
+
13
+ end
@@ -0,0 +1,10 @@
1
+ require 'minitest/autorun'
2
+ require 'log_parser/line_item'
3
+
4
+ class LineItemTest < MiniTest::Unit::TestCase
5
+
6
+ def test_full_message
7
+ assert_equal '', ''
8
+ end
9
+
10
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: log_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Buckley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-14 00:00:00.000000000 Z
11
+ date: 2014-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -51,8 +51,12 @@ files:
51
51
  - README.md
52
52
  - Rakefile
53
53
  - lib/log_parser.rb
54
+ - lib/log_parser/client.rb
55
+ - lib/log_parser/line_item.rb
54
56
  - lib/log_parser/version.rb
55
57
  - log_parser.gemspec
58
+ - test/log_parser/client_test.rb
59
+ - test/log_parser/line_item_test.rb
56
60
  homepage: https://github.com/ridiculous
57
61
  licenses:
58
62
  - MIT
@@ -77,4 +81,6 @@ rubygems_version: 2.2.2
77
81
  signing_key:
78
82
  specification_version: 4
79
83
  summary: Easily search log files
80
- test_files: []
84
+ test_files:
85
+ - test/log_parser/client_test.rb
86
+ - test/log_parser/line_item_test.rb