logfile_interval 1.1.0 → 1.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0f1a02f57605b2eb8eacf703a456dbe9038abcd
4
- data.tar.gz: f1d68cd7e72dc15023f6c3f8ae72d7e2eb104102
3
+ metadata.gz: 37c52b3b1355cf1589c84a6f2f8e76233222eb80
4
+ data.tar.gz: 5ec64eb915a57de6c94974756d4a3d8a58042dc6
5
5
  SHA512:
6
- metadata.gz: 3bc11945565915aaa028f61f01b670340a2765640abf44aca2d8b1d36cb6a6b09c8626b7e3d964e3e3a7f0479893240defa0b600feec3f98e1f6c5176c5cda8a
7
- data.tar.gz: cb91a1b9aad9bd67aa5fa1ccfa9a9f0d69cab5bbc177ecdfc4ac4f80d08c1edcf39cbf5df250c8251913ca50a2d4e9abf17e92335c41b9b10b17dc32bddf5cc5
6
+ metadata.gz: 2b6eb7f3ecbfc8b12fa5900c02ca45e6f58ec1730018500c860c3be7e63ee0a83f402ee000e9141720ec13f6d89c7585dc6befbde89ec86929f51707e8fc47f1
7
+ data.tar.gz: 865b1ae02eb35830c8723f3b9ad5b013a3f0a335eaecc05cc95f077f468db34855af91510a00d77d4a0caf45183f708263daa78c99cb6da9f7b12c574e2bc5be
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- logfile_interval (1.1.0)
4
+ logfile_interval (1.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -2,27 +2,92 @@
2
2
 
3
3
  Logfile parser and aggregator.
4
4
 
5
- It iterates over each line of logfiles, parses each line and aggregates all lines in a time interval into a single
6
- record made up of the sum, the average, the number of occurences per value or average of the deltas between lines.
5
+ It iterates over 1 or more logfiles, parses each line and aggregates them into time intervals. Each interval object
6
+ includes aggregated data for each field of the logfile.
7
7
 
8
- ## Installation
8
+ Aggregated data can be for example the sum, the average value or the number of occurences of each value.
9
9
 
10
- Add this line to your application's Gemfile:
10
+ ## Example
11
+ This example will parse an access.log file and aggregate the data into 5 minute intervals.
11
12
 
12
- gem 'logfile_interval'
13
+ In each interval, it counts
14
+ * the number of requests per IP address
15
+ * the number of requests for each HTTP status code
16
+ * the number of requests for each HTTP status code and IP address.
13
17
 
14
- And then execute:
18
+ Full script is in [readme.rb](bin/readme.rb).
19
+ ### Code
20
+ ```ruby
21
+ require 'pp'
22
+ require 'date'
23
+ require 'logfile_interval'
15
24
 
16
- $ bundle
25
+ class AccessLog < LogfileInterval::LineParser::Base
26
+ # Example line:
27
+ # 74.75.19.145 - - [31/Mar/2013:06:54:12 -0700] "GET /ppa/google_chrome HTTP/1.1" 200 7855 "https://www.google.com/" "Mozilla/5.0 Chrome/25.0.1364.160"
17
28
 
18
- Or install it yourself as:
29
+ set_regex /^([\d\.]+)\s+.*\s+\[(\d\d.*\d\d)\]\s+"(?:GET|POST|PUT|HEAD|DELETE)\s+(\S+)\s+HTTP\S+"\s+(\d+)\s+/
19
30
 
20
- $ gem install logfile_interval
31
+ add_column :name => 'ip', :pos => 1, :aggregator => :count, :group_by => 'ip'
32
+ add_column :name => 'timestamp', :pos => 2, :aggregator => :timestamp
33
+ add_column :name => 'code', :pos => 4, :aggregator => :count, :group_by => 'code'
34
+ add_column :name => 'code_by_ip', :pos => 4, :aggregator => :count, :group_by => 'ip'
21
35
 
22
- ## Usage
36
+ def time
37
+ DateTime.strptime(self.timestamp, '%d/%b/%Y:%H:%M:%S %z').to_time
38
+ end
39
+ end
40
+
41
+ path = ENV['ACCESS_LOG_PATH']
42
+ file = LogfileInterval::Logfile.new(path, AccessLog)
43
+ unless file.exist?
44
+ puts "#{path} is not found"
45
+ exit 1
46
+ end
23
47
 
48
+ builder = LogfileInterval::IntervalBuilder.new(file, 300)
49
+ builder.each_interval do |interval|
50
+ next unless interval.size > 0
51
+
52
+ puts
53
+ puts "start time of interval: #{interval.start_time}"
54
+ puts "number of seconds in interval: #{interval.length}"
55
+ puts "number of requests found in interval: #{interval.size}"
56
+ puts "number of requests per ip address in interval:"
57
+ pp interval[:ip]
58
+ puts "number of requests per http code in interval:"
59
+ pp interval[:code]
60
+ puts "for each http code, number of requests grouped by ip:"
61
+ pp interval[:code_by_ip]
62
+ end
63
+ ```
64
+ ### Output
65
+ Logfile used for example: [access.log](spec/support/logfiles/access.log.3).
66
+ ```
67
+ start time of interval: 2012-01-01 16:30:00 -0800
68
+ number of seconds in interval: 300
69
+ number of requests found in interval: 4
70
+ number of requests per ip address in interval:
71
+ {"78.54.172.146"=>3, "66.249.68.148"=>1}
72
+ number of requests per http code in interval:
73
+ {"200"=>3, "302"=>1}
74
+ for each ip, number of requests grouped by http code:
75
+ {"200"=>{"78.54.172.146"=>2, "66.249.68.148"=>1}, "302"=>{"78.54.172.146"=>1}}
76
+
77
+ start time of interval: 2012-01-01 16:25:00 -0800
78
+ number of seconds in interval: 300
79
+ number of requests found in interval: 3
80
+ number of requests per ip address in interval:
81
+ {"78.54.172.146"=>1, "173.192.238.51"=>1, "66.249.67.176"=>1}
82
+ number of requests per http code in interval:
83
+ {"200"=>1, "301"=>2}
84
+ for each ip, number of requests grouped by http code:
85
+ {"200"=>{"78.54.172.146"=>1}, "301"=>{"173.192.238.51"=>1, "66.249.67.176"=>1}}
86
+ ```
87
+
88
+ ## Usage
24
89
  ### Write a LineParser class
25
- #### Example
90
+ The first step is to define a LineParser class as in the example above. The parser lists the fields that must be parsed, how a timestamp can be extracted from each line and how to aggregate values into intervals.
26
91
  ```ruby
27
92
  module LogfileInterval
28
93
  module LineParser
@@ -46,8 +111,7 @@ module LogfileInterval
46
111
  end
47
112
  end
48
113
  ```
49
- #### Writing a parser class
50
- The parser must define:
114
+ #### The parser must define:
51
115
  * A regex that extracts the fields out of each line.
52
116
  * A set of columns that will to be parsed and aggregated in time intervals.
53
117
  * A 'time' method that converts the mandatory timestamp field of a line into a Time object.
@@ -57,7 +121,7 @@ The parser must define:
57
121
  * pos: the position of the captured field in the regex matched data
58
122
  * aggregator : the aggregation mode for this field
59
123
  * conversion: the parser will convert the field to an integer or a float when building the parsed record
60
- * group_by: group_by value is the name of another field. The aggregator will apply the aggregator to this field for each distinct value found in the other field.
124
+ * group_by: group_by value is the name of another field. Values will be aggregated for each 'name', 'group_by' pair.
61
125
 
62
126
  #### Aggregator types and options
63
127
  * timestamp: the timestamp field will be used to determine to which interval the line belongs, each line MUST have a timestamp
@@ -121,8 +185,20 @@ interval_builder.each_interval do |interval|
121
185
  end
122
186
  ```
123
187
 
124
- ## Contributing
188
+ ## Installation
189
+ Add this line to your application's Gemfile:
190
+
191
+ gem 'logfile_interval'
125
192
 
193
+ And then execute:
194
+
195
+ $ bundle install
196
+
197
+ Or install it yourself as:
198
+
199
+ $ gem install logfile_interval
200
+
201
+ ## Contributing
126
202
  1. Fork it
127
203
  2. Create your feature branch (`git checkout -b my-new-feature`)
128
204
  3. Commit your changes (`git commit -am 'Add some feature'`)
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pp'
4
+ require 'date'
5
+ require File.join(File.expand_path('../../lib', __FILE__), 'logfile_interval')
6
+
7
+ logfile = ARGV[0]
8
+ unless File.exist?(String(logfile))
9
+ puts "#{logfile} does not exist."
10
+ exit 1
11
+ end
12
+
13
+ class AccessLogParser < LogfileInterval::LineParser::Base
14
+ # Example line:
15
+ # 74.75.19.145 - - [31/Mar/2013:06:54:12 -0700] "GET /ppa/google_chrome HTTP/1.1" 200 7855 "https://www.google.com/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22"
16
+
17
+ set_regex /^([\d\.]+)\s+\S+\s+\S+\s+\[(\d\d.*\d\d)\]\s+"(?:GET|POST|PUT|HEAD|DELETE)\s+(\S+)\s+HTTP\S+"\s+(\d+)\s+(\d+)\s+"([^"]*)"\s+"([^"]+)"$/
18
+
19
+ add_column :name => 'ip', :pos => 1, :aggregator => :count, :group_by => 'ip'
20
+ add_column :name => 'timestamp', :pos => 2, :aggregator => :timestamp
21
+ add_column :name => 'code_by_ip', :pos => 4, :aggregator => :count, :group_by => 'ip'
22
+ add_column :name => 'length', :pos => 5, :aggregator => :average, :conversion => :integer
23
+ add_column :name => 'length_by_ip', :pos => 5, :aggregator => :average, :conversion => :integer, :group_by => 'ip'
24
+ add_column :name => 'referer', :pos => 6, :aggregator => :count, :group_by => :referer
25
+ add_column :name => 'referer_by_ip', :pos => 6, :aggregator => :count, :group_by => :ip
26
+
27
+ def time
28
+ DateTime.strptime(self.timestamp, '%d/%b/%Y:%H:%M:%S %z').to_time
29
+ end
30
+ end
31
+
32
+ file = LogfileInterval::Logfile.new(logfile, AccessLogParser)
33
+ builder = LogfileInterval::IntervalBuilder.new(file, 300)
34
+ builder.each_interval do |interval|
35
+ next unless interval.size > 0
36
+
37
+ puts
38
+ puts "start_time=#{interval.start_time} size=#{interval.size}"
39
+ pp interval[:ip]
40
+ pp interval[:referer_by_ip]
41
+ STDIN.gets
42
+ end
43
+
data/bin/readme.rb ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pp'
4
+ require 'date'
5
+ require File.join(File.expand_path('../../lib', __FILE__), 'logfile_interval')
6
+
7
+ class AccessLog < LogfileInterval::LineParser::Base
8
+ # Example line:
9
+ # 74.75.19.145 - - [31/Mar/2013:06:54:12 -0700] "GET /ppa/google_chrome HTTP/1.1" 200 7855 "https://www.google.com/" "Mozilla/5.0 Chrome/25.0.1364.160"
10
+
11
+ set_regex /^([\d\.]+)\s+.*\s+\[(\d\d.*\d\d)\]\s+"(?:GET|POST|PUT|HEAD|DELETE)\s+(\S+)\s+HTTP\S+"\s+(\d+)\s+/
12
+
13
+ add_column :name => 'ip', :pos => 1, :aggregator => :count, :group_by => 'ip'
14
+ add_column :name => 'timestamp', :pos => 2, :aggregator => :timestamp
15
+ add_column :name => 'code', :pos => 4, :aggregator => :count, :group_by => 'code'
16
+ add_column :name => 'code_by_ip', :pos => 4, :aggregator => :count, :group_by => 'ip'
17
+
18
+ def time
19
+ DateTime.strptime(self.timestamp, '%d/%b/%Y:%H:%M:%S %z').to_time
20
+ end
21
+ end
22
+
23
+ path = ENV['ACCESS_LOG_PATH']
24
+ file = LogfileInterval::Logfile.new(path, AccessLog)
25
+ unless file.exist?
26
+ puts "#{path} is not found"
27
+ exit 1
28
+ end
29
+
30
+ builder = LogfileInterval::IntervalBuilder.new(file, 300)
31
+ builder.each_interval do |interval|
32
+ next unless interval.size > 0
33
+
34
+ puts
35
+ puts "start time of interval: #{interval.start_time}"
36
+ puts "number of seconds in interval: #{interval.length}"
37
+ puts "number of requests found in interval: #{interval.size}"
38
+ puts "number of requests per ip address in interval:"
39
+ pp interval[:ip]
40
+ puts "number of requests per http code in interval:"
41
+ pp interval[:code]
42
+ puts "for each ip, number of requests grouped by http code:"
43
+ pp interval[:code_by_ip]
44
+ end
@@ -1,12 +1,14 @@
1
- require "logfile_interval/version"
2
- require "logfile_interval/file_backward"
3
- require "logfile_interval/interval"
4
- require "logfile_interval/interval_builder"
5
- require "logfile_interval/logfile"
6
- require "logfile_interval/logfile_set"
7
- require "logfile_interval/line_parser/base"
8
- require "logfile_interval/line_parser/aggregator"
9
- require "logfile_interval/line_parser/counter"
1
+ lib_dir = File.expand_path('..', __FILE__)
2
+
3
+ require "#{lib_dir}/logfile_interval/version"
4
+ require "#{lib_dir}/logfile_interval/file_backward"
5
+ require "#{lib_dir}/logfile_interval/interval"
6
+ require "#{lib_dir}/logfile_interval/interval_builder"
7
+ require "#{lib_dir}/logfile_interval/logfile"
8
+ require "#{lib_dir}/logfile_interval/logfile_set"
9
+ require "#{lib_dir}/logfile_interval/line_parser/base"
10
+ require "#{lib_dir}/logfile_interval/line_parser/aggregator"
11
+ require "#{lib_dir}/logfile_interval/line_parser/counter"
10
12
 
11
13
  module LogfileInterval
12
14
  end
@@ -22,7 +22,11 @@ module LogfileInterval
22
22
  end
23
23
 
24
24
  def [](name)
25
- @data[name].values
25
+ @data[name.to_sym].values
26
+ end
27
+
28
+ def each(&block)
29
+ @data.each(&block)
26
30
  end
27
31
 
28
32
  def add_record(record)
@@ -20,7 +20,7 @@ module LogfileInterval
20
20
  end
21
21
 
22
22
  def value(group = nil)
23
- average(key(group))
23
+ val(key(group))
24
24
  end
25
25
 
26
26
  def values
@@ -47,10 +47,14 @@ module LogfileInterval
47
47
 
48
48
  def each
49
49
  @val.each_key do |k|
50
- yield k, average(k)
50
+ yield k, val(k)
51
51
  end
52
52
  end
53
53
 
54
+ def val(k)
55
+ @val[k]
56
+ end
57
+
54
58
  def average(k)
55
59
  @size[k] > 0 ? @val[k].to_f / @size[k].to_f : 0
56
60
  end
@@ -59,7 +63,6 @@ module LogfileInterval
59
63
  class Sum < Base
60
64
  def add(value, group_by = nil)
61
65
  @val.add(key(group_by), value)
62
- @size.set(key(group_by), 1)
63
66
  end
64
67
  end
65
68
 
@@ -68,12 +71,15 @@ module LogfileInterval
68
71
  @val.add(key(group_by), value)
69
72
  @size.increment(key(group_by))
70
73
  end
74
+
75
+ def val(k)
76
+ average(k)
77
+ end
71
78
  end
72
79
 
73
80
  class Count < Base
74
81
  def add(value, group_by = nil)
75
82
  @val.add(key(group_by), 1)
76
- @size.set(key(group_by), 1)
77
83
  end
78
84
  end
79
85
 
@@ -85,7 +91,6 @@ module LogfileInterval
85
91
  def add(value, group_by)
86
92
  raise ArgumentError, 'group_by argument is mandatory for GroupAndCount#add' unless group_by
87
93
  @val.increment_subkey(value, key(group_by))
88
- @size.set(key(group_by), 1)
89
94
  end
90
95
  end
91
96
 
@@ -102,6 +107,10 @@ module LogfileInterval
102
107
  end
103
108
  @previous.set(key(group_by), value)
104
109
  end
110
+
111
+ def val(k)
112
+ average(k)
113
+ end
105
114
  end
106
115
  end
107
116
  end
@@ -22,19 +22,23 @@ module LogfileInterval
22
22
  def add_column(options)
23
23
  name = options.fetch(:name)
24
24
  pos = options.fetch(:pos)
25
- aggregator = options.fetch(:aggregator)
26
25
  conversion = options.fetch(:conversion, :string)
26
+ group_by = options.fetch(:group_by, nil)
27
+ aggregator = options.fetch(:aggregator)
27
28
  unless AGGREGATION_FUNCTIONS.include?(aggregator)
28
29
  raise ArgumentError, "aggregator must be one of #{AGGREGATION_FUNCTIONS.join(', ')}"
29
30
  end
30
31
 
31
- if aggregator == :count && options[:group_by] && options[:group_by] != name
32
+ name = name.to_sym
33
+ group_by = group_by.to_sym unless group_by.nil?
34
+
35
+ if aggregator == :count && group_by && group_by != name
32
36
  aggregator = :group_and_count
33
37
  end
34
38
 
35
39
  aggregator = Aggregator.klass(aggregator)
36
40
  columns[name] = { :pos => pos, :aggregator => aggregator, :conversion => conversion }
37
- columns[name][:group_by] = options[:group_by]
41
+ columns[name][:group_by] = group_by
38
42
 
39
43
  define_method(name) do
40
44
  @data[name]
@@ -1,8 +1,6 @@
1
1
  module LogfileInterval
2
2
  module LineParser
3
3
  class Counter < Hash
4
- class ValueTypeError < StandardError; end
5
-
6
4
  def increment(key)
7
5
  if self.has_key?(key)
8
6
  self[key] += 1
@@ -7,8 +7,12 @@ module LogfileInterval
7
7
  @parser = parser
8
8
  end
9
9
 
10
+ def exist?
11
+ filename && File.exist?(@filename)
12
+ end
13
+
10
14
  def first_timestamp
11
- return nil unless File.exist?(@filename)
15
+ return unless exist?
12
16
  File.open(@filename) do |f|
13
17
  while line = f.gets
14
18
  if record = parser.create_record(line)
@@ -19,6 +23,7 @@ module LogfileInterval
19
23
  end
20
24
 
21
25
  def each_line
26
+ return unless exist?
22
27
  f = FileBackward.new(@filename)
23
28
  while(line = f.gets)
24
29
  yield line.chomp
@@ -1,3 +1,3 @@
1
1
  module LogfileInterval
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
@@ -13,7 +13,7 @@ module LogfileInterval
13
13
 
14
14
  context :each_interval do
15
15
  before :each do
16
- Time.stub(:now).and_return(Time.new(2013,12,01,16,0,0,'-08:00'))
16
+ Time.stub(:now).and_return(Time.new(2013,12,01,16,0,1,'-08:00'))
17
17
  @intervals = []
18
18
  @builder.each_interval do |interval|
19
19
  @intervals << interval
@@ -27,6 +27,7 @@ module LogfileInterval
27
27
  context 'first interval' do
28
28
  it 'got records from both logfiles' do
29
29
  @intervals.first.size.should == 4
30
+ @intervals.first.end_time.should == Time.new(2013,12,01,16,0,0,'-08:00')
30
31
  @intervals.first[:total_time].should == 700.0/4
31
32
  @intervals.first[:num_bytes].should == 52000
32
33
  @intervals.first[:rss].round(5).should == 0.60
@@ -38,6 +39,7 @@ module LogfileInterval
38
39
  context 'second interval' do
39
40
  it 'got records from second logfile only' do
40
41
  @intervals.last.size.should == 2
42
+ @intervals.last.end_time.should == Time.new(2013,12,01,15,55,0,'-08:00')
41
43
  @intervals.last[:total_time].should == 300
42
44
  @intervals.last[:num_bytes].should == 41000
43
45
  @intervals.last[:rss].round(5).should == 0.20
@@ -46,5 +48,15 @@ module LogfileInterval
46
48
  end
47
49
  end
48
50
  end
51
+
52
+ context :last_interval do
53
+ it 'returns the most recent interval' do
54
+ Time.stub(:now).and_return(Time.new(2013,12,01,16,0,1,'-08:00'))
55
+ interval = @builder.last_interval
56
+ interval.end_time.should == Time.new(2013,12,01,16,0,0,'-08:00')
57
+ interval.size.should == 4
58
+ interval[:num_bytes].should == 52000
59
+ end
60
+ end
49
61
  end
50
62
  end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ module LogfileInterval
4
+ module LineParser
5
+ describe Counter do
6
+ it 'behaves like a hash' do
7
+ c = Counter.new
8
+ c[:a] = 1
9
+ c.keys.should == [:a]
10
+ c.values.should == [1]
11
+ c.delete(:a)
12
+ c.keys.should be_empty
13
+
14
+ c[:a] = 1
15
+ c[:b] = 2
16
+ c.keys.sort.should == [:a, :b]
17
+ end
18
+
19
+ it 'returns 0 when key does not exist' do
20
+ c = Counter.new
21
+ c[:a].should == 0
22
+ end
23
+
24
+ describe :increment do
25
+ it 'adds 1 to value for key argument' do
26
+ c = Counter.new
27
+ c[:a] = 1
28
+ c.increment(:a)
29
+ c[:a].should == 2
30
+ end
31
+
32
+ it 'creates new key when missing' do
33
+ c = Counter.new
34
+ c.increment(:a)
35
+ c[:a].should == 1
36
+ end
37
+ end
38
+
39
+ describe :add do
40
+ it 'adds number to hash value' do
41
+ c = Counter.new
42
+ c[:a] = 1
43
+ c.add(:a, 5)
44
+ c[:a].should == 6
45
+ end
46
+
47
+ it 'creates a new key when missing' do
48
+ c = Counter.new
49
+ c.add(:a, 4)
50
+ c[:a].should == 4
51
+ end
52
+ end
53
+
54
+ describe :increment_subkey do
55
+ it 'saves values of type Counter' do
56
+ c = Counter.new
57
+ c.increment_subkey(:a, :sub)
58
+ c[:a].should be_a(Counter)
59
+ c[:a][:sub].should == 1
60
+ end
61
+
62
+ it 'raises an error when trying to increment an existing integer key' do
63
+ c = Counter.new
64
+ c[:a] = 1
65
+ lambda { c.increment_subkey(:a, :sub) }.should raise_error(RuntimeError)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -9,9 +9,9 @@ module LogfileInterval
9
9
 
10
10
  set_regex /^([\d\.]+)\s+\S+\s+\S+\s+\[(\d\d.*\d\d)\]\s+"(?:GET|POST|PUT|HEAD|DELETE)\s+(\S+)\s+HTTP\S+"\s+(\d+)\s+(\d+)\s+"([^"]*)"\s+"([^"]+)"$/
11
11
 
12
- add_column :name => 'ip', :pos => 1, :aggregator => :count, :group_by => 'id'
12
+ add_column :name => 'ip', :pos => 1, :aggregator => :count, :group_by => 'ip'
13
13
  add_column :name => 'timestamp', :pos => 2, :aggregator => :timestamp
14
- add_column :name => 'code', :pos => 4, :aggregator => :count, :group_by => 'id'
14
+ add_column :name => 'code', :pos => 4, :aggregator => :count, :group_by => 'ip'
15
15
  add_column :name => 'length', :pos => 5, :aggregator => :average, :conversion => :integer
16
16
  add_column :name => 'length_by_ip', :pos => 5, :aggregator => :average, :conversion => :integer, :group_by => 'ip'
17
17
 
@@ -0,0 +1,7 @@
1
+ 66.249.67.176 - - [01/Jan/2012:16:25:47 -0800] "GET /packages/show/1 HTTP/1.1" 301 185 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
2
+ 173.192.238.51 - - [01/Jan/2012:16:26:31 -0800] "GET / HTTP/1.1" 301 185 "-" "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.19; aggregator:Spinn3r (Spinn3r 3.1);"
3
+ 78.54.172.146 - - [01/Jan/2012:16:26:51 -0800] "GET /package/core/oneiric/main/base/abrowser HTTP/1.1" 200 6801 "http://www.google.com/url?sa=t&rct=j&q=abrowser" "Mozilla/5.0 (Ubuntu; X11; Linux x86_64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"
4
+ 78.54.172.146 - - [01/Jan/2012:16:30:51 -0800] "GET /package/core/oneiric/main/base/firefox HTTP/1.1" 200 6801 "http://www.google.com/url?sa=t&rct=j&q=firefox" "Mozilla/5.0 (Ubuntu; X11; Linux x86_64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"
5
+ 66.249.68.148 - - [01/Jan/2012:16:30:51 -0800] "GET /package/core/hardy/main/updates/libldap2-dev HTTP/1.1" 200 7058 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
6
+ 78.54.172.146 - - [01/Jan/2012:16:30:51 -0800] "GET /package/show/2 HTTP/1.1" 302 6801 "http://www.google.com/url?sa=t&rct=j&q=abrowser" "Mozilla/5.0 (Ubuntu; X11; Linux x86_64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"
7
+ 78.54.172.146 - - [01/Jan/2012:16:31:51 -0800] "GET /package/core/oneiric/main/base/abrowser-6.0 HTTP/1.1" 200 6801 "http://www.google.com/url?sa=t&rct=j&q=abrowser" "Mozilla/5.0 (Ubuntu; X11; Linux x86_64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logfile_interval
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philippe Le Rohellec
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-08 00:00:00.000000000 Z
11
+ date: 2014-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -83,7 +83,9 @@ dependencies:
83
83
  description: Logfile parser and aggregator
84
84
  email:
85
85
  - philippe@lerohellec.com
86
- executables: []
86
+ executables:
87
+ - aggregate_access_log.rb
88
+ - readme.rb
87
89
  extensions: []
88
90
  extra_rdoc_files: []
89
91
  files:
@@ -94,6 +96,8 @@ files:
94
96
  - LICENSE.txt
95
97
  - README.md
96
98
  - Rakefile
99
+ - bin/aggregate_access_log.rb
100
+ - bin/readme.rb
97
101
  - docs/design.rb
98
102
  - docs/design2.rb
99
103
  - docs/design3.rb
@@ -113,6 +117,7 @@ files:
113
117
  - spec/lib/interval_spec.rb
114
118
  - spec/lib/line_parser/aggregator_spec.rb
115
119
  - spec/lib/line_parser/base_spec.rb
120
+ - spec/lib/line_parser/counter_spec.rb
116
121
  - spec/lib/logfile_set_spec.rb
117
122
  - spec/lib/logfile_spec.rb
118
123
  - spec/spec_helper.rb
@@ -121,6 +126,7 @@ files:
121
126
  - spec/support/logfiles/access.log
122
127
  - spec/support/logfiles/access.log.1
123
128
  - spec/support/logfiles/access.log.2
129
+ - spec/support/logfiles/access.log.3
124
130
  - spec/support/logfiles/timing.log
125
131
  - spec/support/logfiles/timing.log.1
126
132
  homepage: https://github.com/plerohellec/logfile_interval
@@ -152,6 +158,7 @@ test_files:
152
158
  - spec/lib/interval_spec.rb
153
159
  - spec/lib/line_parser/aggregator_spec.rb
154
160
  - spec/lib/line_parser/base_spec.rb
161
+ - spec/lib/line_parser/counter_spec.rb
155
162
  - spec/lib/logfile_set_spec.rb
156
163
  - spec/lib/logfile_spec.rb
157
164
  - spec/spec_helper.rb
@@ -160,5 +167,6 @@ test_files:
160
167
  - spec/support/logfiles/access.log
161
168
  - spec/support/logfiles/access.log.1
162
169
  - spec/support/logfiles/access.log.2
170
+ - spec/support/logfiles/access.log.3
163
171
  - spec/support/logfiles/timing.log
164
172
  - spec/support/logfiles/timing.log.1