chainsaw 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 ljfauscett
1
+ Copyright (c) 2012 the fucking authors
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Chainsaw
2
2
 
3
- Parses a log file and returns lines matching the time period provided.
3
+ Parses a log file and returns lines matching the time period provided. Chainsaw tries to be smart about determining the log format and parsing it accordingly. See the list of currently supported formats below.
4
4
 
5
5
  Chronic is used to parse the time strings, so any format chronic
6
6
  supports, chainsaw supports. A list of supported formats can
@@ -47,6 +47,21 @@ If you want to print a line and wait for input (press return) before moving to t
47
47
  Chainsaw will output the found log lines to a file on the system if you specify with `-o FILENAME`.
48
48
 
49
49
  > chainsaw access.log yesterday -o yesterday.log
50
+
51
+ ## Supported log formats (we think)
52
+
53
+ * syslog
54
+ * apache/nginx access (CLF)
55
+ * apache error
56
+ * nginx error
57
+ * rack
58
+ * rails
59
+ * django
60
+ * mongodb
61
+ * redis
62
+ * puppet
63
+ * python logger
64
+ * ruby logger
50
65
 
51
66
  ## Contributing
52
67
 
data/Rakefile CHANGED
@@ -6,3 +6,5 @@ Rake::TestTask.new do |t|
6
6
  t.libs << 'test'
7
7
  t.test_files = FileList['test/*_test.rb']
8
8
  end
9
+
10
+ task :default => :test
@@ -0,0 +1,9 @@
1
+ Range.class_eval do
2
+
3
+ unless method_defined?(:cover?)
4
+ def cover?(elem)
5
+ include?(elem)
6
+ end
7
+ end
8
+
9
+ end
@@ -1,90 +1,83 @@
1
1
  module Chainsaw
2
2
  class Detector
3
-
4
- CLF_PATTERN = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} (?:-|[^ ]+) (?:-|[^ ]+) \[(\d{2}\/[a-z]{3}\/\d{4}:\d{2}:\d{2}:\d{2} -\d{4})\]/i
5
- APACHE_ERROR_PATTERN = /^\[([a-z]{3} [a-z]{3} \d{2} \d{2}:\d{2}:\d{2} \d{4})\]/i
6
- NGINX_ERROR_PATTERN = /^(\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2})/i
7
- RUBY_LOGGER_PATTERN = /^[a-z]{1}, \[(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})\.\d+ #\d+\]/i
8
- RAILS_PATTERN = /^started [a-z]+ "[^"]+" for \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} at (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} -\d{4})/i
9
- SYSLOG_PATTERN = /^([a-z]{3} ?\d{1,2} \d{2}:\d{2}:\d{2})/i
10
- REDIS_PATTERN = /^\[\d+\] ?(\d{1,2} [a-z]{3} \d{2}:\d{2}:\d{2})/i
11
- PUPPET_PATTERN = /^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]/i
12
- MONGODB_PATTERN = /^(\w{3} \w{3} \d{2} \d{2}:\d{2}:\d{2})/i
13
- RACK_PATTERN = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} (?:-|[^ ]+) (?:-|[^ ]+) \[(\d{2}\/[a-z]{3}\/\d{4} \d{2}:\d{2}:\d{2})\]/i
14
- PYTHON_PATTERN = /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/i
15
- DJANGO_PATTERN = /^\[(\d{2}\/[a-z]{3}\/\d{4} \d{2}:\d{2}:\d{2})\]/i
3
+ PATTERNS = {
4
+ :clf => {
5
+ :pattern => /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} (?:-|[^ ]+) (?:-|[^ ]+) \[(\d{2}\/[a-z]{3}\/\d{4}:\d{2}:\d{2}:\d{2} -\d{4})\]/i,
6
+ :time_format => '%d/%b/%Y:%H:%M:%S %z'
7
+ },
8
+ :apache_error => {
9
+ :pattern => /^\[([a-z]{3} [a-z]{3} \d{2} \d{2}:\d{2}:\d{2} \d{4})\]/i,
10
+ :time_format => '%a %b %d %H:%M:%S %Y'
11
+ },
12
+ :nginx_error => {
13
+ :pattern => /^(\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2})/i,
14
+ :time_format => '%Y/%m/%d %H:%M:%S'
15
+ },
16
+ :ruby_logger => {
17
+ :pattern => /^[a-z]{1}, \[(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})\.\d+ #\d+\]/i,
18
+ :time_format => '%Y-%m-%dT%H:%M:%S'
19
+ },
20
+ :rails => {
21
+ :pattern => /^started [a-z]+ "[^"]+" for \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} at (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} -\d{4})/i,
22
+ :time_format => '%Y-%m-%d %H:%M:%S %z'
23
+ },
24
+ :syslog => {
25
+ :pattern => /^([a-z]{3} ?\d{1,2} \d{2}:\d{2}:\d{2})/i,
26
+ :time_format => '%b %e %H:%M:%S'
27
+ },
28
+ :redis => {
29
+ :pattern => /^\[\d+\] ?(\d{1,2} [a-z]{3} \d{2}:\d{2}:\d{2})/i,
30
+ :time_format => '%e %b %H:%M:%S'
31
+ },
32
+ :puppet => {
33
+ :pattern => /^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]/i,
34
+ :time_format => '%Y-%m-%d %H:%M:%S'
35
+ },
36
+ :mongodb => {
37
+ :pattern => /^(\w{3} \w{3} \d{2} \d{2}:\d{2}:\d{2})/i,
38
+ :time_format => '%a %b %d %H:%M:%S'
39
+ },
40
+ :rack => {
41
+ :pattern => /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} (?:-|[^ ]+) (?:-|[^ ]+) \[(\d{2}\/[a-z]{3}\/\d{4} \d{2}:\d{2}:\d{2})\]/i,
42
+ :time_format => '%d/%b/%Y %H:%M:%S'
43
+ },
44
+ :python => {
45
+ :pattern => /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/i,
46
+ :time_format => '%Y-%m-%d %H:%M:%S'
47
+ },
48
+ :django => {
49
+ :pattern => /^\[(\d{2}\/[a-z]{3}\/\d{4} \d{2}:\d{2}:\d{2})\]/i,
50
+ :time_format => '%d/%b/%Y %H:%M:%S'
51
+ }
52
+ }
16
53
 
17
54
  def self.detect(log)
18
- format = nil
55
+ type = nil
19
56
 
20
57
  log.each_line do |line|
21
- format = _detect(line)
22
- break unless format.type.nil?
58
+ type = _detect(line)
59
+ break unless type.nil?
23
60
  end
24
61
 
25
- if format.nil?
62
+ if type.nil?
26
63
  puts "\033[31mUnable to determine log format :(\033[0m"
27
64
  exit
28
65
  else
29
- format
66
+ Format.new(type, PATTERNS[type])
30
67
  end
31
68
  end
32
69
 
33
70
  def self._detect(line)
34
- format = Format.new
35
-
36
- case line
37
- when CLF_PATTERN
38
- format.type = 'clf'
39
- format.time_format = '%d/%b/%Y:%H:%M:%S %z'
40
- format.pattern = CLF_PATTERN
41
- when APACHE_ERROR_PATTERN
42
- format.type = 'apache_error'
43
- format.time_format = '%a %b %d %H:%M:%S %Y'
44
- format.pattern = APACHE_ERROR_PATTERN
45
- when NGINX_ERROR_PATTERN
46
- format.type = 'nginx_error'
47
- format.time_format = '%Y/%m/%d %H:%M:%S'
48
- format.pattern = NGINX_ERROR_PATTERN
49
- when RUBY_LOGGER_PATTERN
50
- format.type = 'ruby_logger'
51
- format.time_format = '%Y-%m-%dT%H:%M:%S'
52
- format.pattern = RUBY_LOGGER_PATTERN
53
- when RAILS_PATTERN
54
- format.type = 'rails'
55
- format.time_format = '%Y-%m-%d %H:%M:%S %z'
56
- format.pattern = RAILS_PATTERN
57
- when SYSLOG_PATTERN
58
- format.type = 'syslog'
59
- format.time_format = '%b %e %H:%M:%S'
60
- format.pattern = SYSLOG_PATTERN
61
- when REDIS_PATTERN
62
- format.type = 'redis'
63
- format.time_format = '%e %b %H:%M:%S'
64
- format.pattern = REDIS_PATTERN
65
- when PUPPET_PATTERN
66
- format.type = 'puppet'
67
- format.time_format = '%Y-%m-%d %H:%M:%S'
68
- format.pattern = PUPPET_PATTERN
69
- when MONGODB_PATTERN
70
- format.type = 'mongodb'
71
- format.time_format = '%a %b %d %H:%M:%S'
72
- format.pattern = MONGODB_PATTERN
73
- when RACK_PATTERN
74
- format.type = 'rack'
75
- format.time_format = '%d/%b/%Y %H:%M:%S'
76
- format.pattern = RACK_PATTERN
77
- when PYTHON_PATTERN
78
- format.type = 'python'
79
- format.time_format = '%Y-%m-%d %H:%M:%S'
80
- format.pattern = PYTHON_PATTERN
81
- when DJANGO_PATTERN
82
- format.type = 'django'
83
- format.time_format = '%d/%b/%Y %H:%M:%S'
84
- format.pattern = DJANGO_PATTERN
71
+ type = nil
72
+
73
+ PATTERNS.each do |key, value|
74
+ if line.match(value[:pattern])
75
+ type = key
76
+ break
77
+ end
85
78
  end
86
79
 
87
- format
80
+ type
88
81
  end
89
82
 
90
83
  end
@@ -4,7 +4,11 @@ module Chainsaw
4
4
  attr_accessor :time_format
5
5
  attr_accessor :pattern
6
6
 
7
- def initialize
7
+ def initialize(type, attributes = {})
8
+ @type = type
9
+ attributes.each do |key, value|
10
+ send(:"#{key}=", value)
11
+ end
8
12
  end
9
13
 
10
14
  end
@@ -1,3 +1,3 @@
1
1
  module Chainsaw
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.6'
3
3
  end
data/lib/chainsaw.rb CHANGED
@@ -5,6 +5,7 @@ require 'optparse'
5
5
  require 'chronic'
6
6
 
7
7
  require 'chainsaw/cli'
8
+ require 'chainsaw/core_extensions'
8
9
  require 'chainsaw/format'
9
10
  require 'chainsaw/detector'
10
11
  require 'chainsaw/filter'
@@ -8,7 +8,7 @@ describe Chainsaw::Detector do
8
8
  format = Detector.detect(line)
9
9
  time = get_time(line, format)
10
10
 
11
- format.type.must_equal 'clf'
11
+ format.type.must_equal :clf
12
12
  time.must_equal Time.local(2012, 8, 26, 7, 42, 20)
13
13
  end
14
14
 
@@ -17,7 +17,7 @@ describe Chainsaw::Detector do
17
17
  format = Detector.detect(line)
18
18
  time = get_time(line, format)
19
19
 
20
- format.type.must_equal 'apache_error'
20
+ format.type.must_equal :apache_error
21
21
 
22
22
  time.must_equal Time.local(2012, 8, 26, 7, 42, 20)
23
23
  end
@@ -27,7 +27,7 @@ describe Chainsaw::Detector do
27
27
  format = Detector.detect(line)
28
28
  time = get_time(line, format)
29
29
 
30
- format.type.must_equal 'nginx_error'
30
+ format.type.must_equal :nginx_error
31
31
  time.must_equal Time.local(2012, 8, 29, 7, 48, 59)
32
32
  end
33
33
 
@@ -36,7 +36,7 @@ describe Chainsaw::Detector do
36
36
  format = Detector.detect(line)
37
37
  time = get_time(line, format)
38
38
 
39
- format.type.must_equal 'ruby_logger'
39
+ format.type.must_equal :ruby_logger
40
40
  time.must_equal Time.local(2012, 9, 1, 11, 21, 26)
41
41
  end
42
42
 
@@ -45,7 +45,7 @@ describe Chainsaw::Detector do
45
45
  format = Detector.detect(line)
46
46
  time = get_time(line, format)
47
47
 
48
- format.type.must_equal 'rails'
48
+ format.type.must_equal :rails
49
49
  time.must_equal Time.local(2012, 9, 1, 9, 34, 35)
50
50
  end
51
51
 
@@ -55,7 +55,7 @@ describe Chainsaw::Detector do
55
55
  time = get_time(line, format)
56
56
  year = Time.now.year
57
57
 
58
- format.type.must_equal 'syslog'
58
+ format.type.must_equal :syslog
59
59
  time.must_equal Time.local(2012, 8, 1, 17, 36, 55)
60
60
  end
61
61
 
@@ -64,7 +64,7 @@ describe Chainsaw::Detector do
64
64
  format = Detector.detect(line)
65
65
  time = get_time(line, format)
66
66
 
67
- format.type.must_equal 'redis'
67
+ format.type.must_equal :redis
68
68
  time.must_equal Time.local(2012, 4, 12, 18, 43, 33)
69
69
  end
70
70
 
@@ -73,7 +73,7 @@ describe Chainsaw::Detector do
73
73
  format = Detector.detect(line)
74
74
  time = get_time(line, format)
75
75
 
76
- format.type.must_equal 'puppet'
76
+ format.type.must_equal :puppet
77
77
  time.must_equal Time.local(2012, 02, 04, 04, 8, 52)
78
78
  end
79
79
 
@@ -82,7 +82,7 @@ describe Chainsaw::Detector do
82
82
  format = Detector.detect(line)
83
83
  time = get_time(line, format)
84
84
 
85
- format.type.must_equal 'mongodb'
85
+ format.type.must_equal :mongodb
86
86
  time.must_equal Time.local(2012, 8, 26, 7, 43, 54)
87
87
  end
88
88
 
@@ -91,7 +91,7 @@ describe Chainsaw::Detector do
91
91
  format = Detector.detect(line)
92
92
  time = get_time(line, format)
93
93
 
94
- format.type.must_equal 'rack'
94
+ format.type.must_equal :rack
95
95
  time.must_equal Time.local(2012, 9, 03, 22, 51, 16)
96
96
  end
97
97
 
@@ -100,7 +100,7 @@ describe Chainsaw::Detector do
100
100
  format = Detector.detect(line)
101
101
  time = get_time(line, format)
102
102
 
103
- format.type.must_equal 'python'
103
+ format.type.must_equal :python
104
104
  time.must_equal Time.local(2010, 12, 12, 11, 41, 42)
105
105
  end
106
106
 
@@ -109,7 +109,7 @@ describe Chainsaw::Detector do
109
109
  format = Detector.detect(line)
110
110
  time = get_time(line, format)
111
111
 
112
- format.type.must_equal 'django'
112
+ format.type.must_equal :django
113
113
  time.must_equal Time.local(2012, 9, 03, 21, 49, 47)
114
114
  end
115
115
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chainsaw
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -14,7 +14,7 @@ date: 2012-09-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: chronic
17
- requirement: &70223282814380 !ruby/object:Gem::Requirement
17
+ requirement: &70185022060360 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 0.7.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70223282814380
25
+ version_requirements: *70185022060360
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: minitest
28
- requirement: &70223282813220 !ruby/object:Gem::Requirement
28
+ requirement: &70185022059220 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 3.0.0
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70223282813220
36
+ version_requirements: *70185022059220
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: mocha
39
- requirement: &70223282812280 !ruby/object:Gem::Requirement
39
+ requirement: &70185022058220 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,7 +44,7 @@ dependencies:
44
44
  version: 0.11.4
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *70223282812280
47
+ version_requirements: *70185022058220
48
48
  description: Filter logfiles based on a time range
49
49
  email:
50
50
  - tdunn13@gmail.com
@@ -62,6 +62,7 @@ files:
62
62
  - chainsaw.gemspec
63
63
  - lib/chainsaw.rb
64
64
  - lib/chainsaw/cli.rb
65
+ - lib/chainsaw/core_extensions.rb
65
66
  - lib/chainsaw/detector.rb
66
67
  - lib/chainsaw/filter.rb
67
68
  - lib/chainsaw/format.rb