rslog 0.0.14 → 0.0.15
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/bin/rslog +1 -1
- data/lib/rslog.rb +44 -16
- data/lib/rslog/args_handler.rb +19 -0
- data/lib/rslog/parser.rb +25 -0
- data/lib/rslog/presenter.rb +34 -27
- data/lib/rslog/validator.rb +23 -19
- metadata +4 -11
- data/lib/rslog/container.rb +0 -58
- data/lib/rslog/data_parser.rb +0 -22
- data/lib/rslog/decorators.rb +0 -24
- data/lib/rslog/extractor.rb +0 -27
- data/lib/rslog/input_parser.rb +0 -29
- data/lib/rslog/opts.rb +0 -45
- data/lib/rslog/tools/array.rb +0 -13
- data/lib/rslog/tools/hash.rb +0 -23
- data/lib/rslog/worker.rb +0 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e78583883f5087e1ce4e44c7d497ce68f1d7d9b37500bfc8223b4316a7b83853
|
|
4
|
+
data.tar.gz: 31f56aadc5936705e58b6e1b1f85b6b141d288e5d58acb542c1ef929d0cb2727
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 29ebd59a174be7ff7841bf2216b8520752067bddf0a81edfe1f46ad87df25c1f9377bd742ffccd1cb9b2367810ca4bbaf5fe6970e7cb34d2b3c1ddfea480fe4c
|
|
7
|
+
data.tar.gz: 0adb1f65ce181f65cb3a0415d9145c39c46c282236b4f4f8da8ae765f3f4a8319b3ccb44ef2ec2f2268cdc593c549cf1b3353c315b4e01277c1af13e85c2cb47
|
data/bin/rslog
CHANGED
data/lib/rslog.rb
CHANGED
|
@@ -1,26 +1,54 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require_relative 'rslog/
|
|
5
|
-
require_relative 'rslog/worker'
|
|
6
|
-
require_relative 'rslog/opts'
|
|
7
|
-
require_relative 'rslog/input_parser'
|
|
8
|
-
require_relative 'rslog/extractor'
|
|
4
|
+
require_relative 'rslog/args_handler'
|
|
9
5
|
require_relative 'rslog/validator'
|
|
10
|
-
require_relative 'rslog/
|
|
11
|
-
require_relative 'rslog/decorators'
|
|
6
|
+
require_relative 'rslog/parser'
|
|
12
7
|
require_relative 'rslog/presenter'
|
|
8
|
+
require 'set'
|
|
13
9
|
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
module RSlog
|
|
11
|
+
VERSION = '0.0.15'
|
|
16
12
|
|
|
17
|
-
class
|
|
18
|
-
|
|
13
|
+
class Main
|
|
14
|
+
def self.run
|
|
15
|
+
file_names = RSlog::ArgsHandler.handle(ARGV)
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
return unless file_names.any?
|
|
18
|
+
|
|
19
|
+
file_names.each do |file_name|
|
|
20
|
+
unless file_names.all?{|f| File.file?(f) }
|
|
21
|
+
puts "There is no file names given. Check input."
|
|
22
|
+
return
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
lines = IO.readlines(file_name)
|
|
26
|
+
|
|
27
|
+
RSlog::Validator.execute(lines)
|
|
28
|
+
|
|
29
|
+
config_sets.each do |conf|
|
|
30
|
+
parsed = RSlog::Parser.new(lines, conf).execute
|
|
31
|
+
RSlog::Presenter.new(parsed, conf).present
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.config_sets
|
|
37
|
+
[
|
|
38
|
+
{ title: %(List of webpages with most page views ordered from most pages views to less page views:),
|
|
39
|
+
format_string: "%-20s %3d",
|
|
40
|
+
suffix: "visits",
|
|
41
|
+
calc: proc { |visits| visits.size } },
|
|
42
|
+
|
|
43
|
+
{ title: "List of webpages with most unique page views also ordered:",
|
|
44
|
+
format_string: "%-20s %3d",
|
|
45
|
+
suffix: 'unique views',
|
|
46
|
+
calc: proc { |visits| Set.new(visits).size } },
|
|
47
|
+
|
|
48
|
+
{ title: "Average visits sorted:",
|
|
49
|
+
suffix: 'average visits',
|
|
50
|
+
calc: proc { |visits| Set.new(visits).size.to_f / visits.size } }
|
|
51
|
+
]
|
|
52
|
+
end
|
|
22
53
|
end
|
|
23
54
|
end
|
|
24
|
-
|
|
25
|
-
# For development
|
|
26
|
-
# RSlog.run.talk
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Class to hold data and implement processing
|
|
4
|
+
#
|
|
5
|
+
module RSlog
|
|
6
|
+
module ArgsHandler
|
|
7
|
+
def self.handle(args)
|
|
8
|
+
options = args.select{|el| !(el =~ /^-/).nil?}
|
|
9
|
+
file_names = args - options
|
|
10
|
+
|
|
11
|
+
puts "R(uby)S(imple)log statistics" if options.delete('-h') || args.empty?
|
|
12
|
+
puts "Version #{RSlog::VERSION}" if options.delete('-v') || args.empty?
|
|
13
|
+
puts "Unknown options #{options.join(', ')}" if options.any?
|
|
14
|
+
|
|
15
|
+
file_names
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
data/lib/rslog/parser.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Class to hold data and implement processing
|
|
4
|
+
#
|
|
5
|
+
module RSlog
|
|
6
|
+
class Parser
|
|
7
|
+
attr_reader :calc, :separator
|
|
8
|
+
attr_accessor :source, :container
|
|
9
|
+
|
|
10
|
+
def initialize(source, conf)
|
|
11
|
+
@calc = conf.fetch(:calc) { proc }
|
|
12
|
+
@separator = conf.fetch(:separator) { ' ' }
|
|
13
|
+
@source = source
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def execute
|
|
17
|
+
Array(source)
|
|
18
|
+
.map{|item| item.split(separator)} #extract, returns Array
|
|
19
|
+
.group_by{|page_name, _visits| page_name } #group, returns Hash
|
|
20
|
+
.map{|page_name, visits| [page_name, calc.call(visits)] } #calculate, returns Array
|
|
21
|
+
.sort_by{|_page_name, visits_by_page| visits_by_page } #sort, returns Array
|
|
22
|
+
.reverse
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/rslog/presenter.rb
CHANGED
|
@@ -1,32 +1,39 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
require_relative 'tools/array'
|
|
5
|
-
|
|
6
|
-
# Class to present result in needed format
|
|
3
|
+
# Class for format result according to passed 'format_string'
|
|
7
4
|
#
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
5
|
+
# result is array of formatted strings
|
|
6
|
+
# e.g
|
|
7
|
+
# [ "/about 1 visits",
|
|
8
|
+
# "/about/2 1 visits",
|
|
9
|
+
# "/home 1 visits",
|
|
10
|
+
# "/contact 1 visits",
|
|
11
|
+
# "/help_page/1 1 visits" ]
|
|
12
|
+
#
|
|
13
|
+
module RSlog
|
|
14
|
+
class Presenter
|
|
15
|
+
attr_reader :title, :format_string, :suffix
|
|
16
|
+
attr_accessor :source
|
|
17
|
+
|
|
18
|
+
def initialize(source, conf)
|
|
19
|
+
@source = source
|
|
20
|
+
@title = conf.fetch(:title) { 'Stat Pages' }
|
|
21
|
+
@format_string = conf.fetch(:format_string) { "%-20s %5.2f" }
|
|
22
|
+
@suffix = conf.fetch(:suffix) { 'visits' }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def present
|
|
26
|
+
puts title
|
|
27
|
+
puts _formatted
|
|
28
|
+
puts
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def _formatted
|
|
34
|
+
source.map do |row|
|
|
35
|
+
"#{format(format_string, *row)} #{suffix}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
31
38
|
end
|
|
32
39
|
end
|
data/lib/rslog/validator.rb
CHANGED
|
@@ -1,30 +1,34 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative 'tools/array'
|
|
4
|
-
|
|
5
3
|
# Class to validate if we have valid data in lines, for example well formatted IPs
|
|
4
|
+
#
|
|
5
|
+
# Checks if IPs are comply with regex
|
|
6
|
+
# Output message "Valid IPs"/"Invalid IPs"
|
|
6
7
|
#
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
module RSlog
|
|
9
|
+
module Validator
|
|
10
|
+
TEMPLATES = {
|
|
11
|
+
# IP address regex, source https://regexr.com/38odc
|
|
12
|
+
ip: /\b(?:(?:2(?:[0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9])\.){3}(?:(?:2([0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9]))\b/
|
|
13
|
+
}.freeze
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
MESSAGES = {
|
|
16
|
+
valid: proc { |validator_name| "All #{validator_name.upcase}s are valid" },
|
|
17
|
+
invalid: proc { |validator_name| "Some #{validator_name.upcase}s are NOT valid" }
|
|
18
|
+
}.freeze
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
def self.execute(source)
|
|
21
|
+
puts
|
|
22
|
+
puts MESSAGES[valid?(source)].call(:ip)
|
|
23
|
+
puts
|
|
24
|
+
end
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
private
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
def self.valid?(source)
|
|
29
|
+
return :valid if source.all? TEMPLATES[:ip]
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
:invalid
|
|
32
|
+
end
|
|
29
33
|
end
|
|
30
34
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rslog
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.15
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrey Eremeev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-06-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Ruby script to get overall Statistic for weblog logs!
|
|
14
14
|
email: a.eremeev@outlook.com
|
|
@@ -19,17 +19,10 @@ extra_rdoc_files: []
|
|
|
19
19
|
files:
|
|
20
20
|
- bin/rslog
|
|
21
21
|
- lib/rslog.rb
|
|
22
|
-
- lib/rslog/
|
|
23
|
-
- lib/rslog/
|
|
24
|
-
- lib/rslog/decorators.rb
|
|
25
|
-
- lib/rslog/extractor.rb
|
|
26
|
-
- lib/rslog/input_parser.rb
|
|
27
|
-
- lib/rslog/opts.rb
|
|
22
|
+
- lib/rslog/args_handler.rb
|
|
23
|
+
- lib/rslog/parser.rb
|
|
28
24
|
- lib/rslog/presenter.rb
|
|
29
|
-
- lib/rslog/tools/array.rb
|
|
30
|
-
- lib/rslog/tools/hash.rb
|
|
31
25
|
- lib/rslog/validator.rb
|
|
32
|
-
- lib/rslog/worker.rb
|
|
33
26
|
homepage: https://rubygems.org/gems/rslog
|
|
34
27
|
licenses:
|
|
35
28
|
- MIT
|
data/lib/rslog/container.rb
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Class to hold data and implement processing
|
|
4
|
-
#
|
|
5
|
-
class Container
|
|
6
|
-
attr_accessor(*%i[
|
|
7
|
-
argv file_name messages errors data options validator types result
|
|
8
|
-
])
|
|
9
|
-
|
|
10
|
-
def initialize
|
|
11
|
-
@errors = []
|
|
12
|
-
@messages = []
|
|
13
|
-
@validator = :ip
|
|
14
|
-
@types = %i[all uniq]
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def file_name?
|
|
18
|
-
!file_name.empty? && no_errors?
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def data?
|
|
22
|
-
messages.include?('Data in place') && no_errors?
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def no_errors?
|
|
26
|
-
errors.empty?
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def add_message(str)
|
|
30
|
-
messages << str
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def add_error(str)
|
|
34
|
-
errors << str
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def talk
|
|
38
|
-
puts messages.join("\n")
|
|
39
|
-
puts errors.join("\n")
|
|
40
|
-
self
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def process_all
|
|
44
|
-
InputParser.new(self).execute
|
|
45
|
-
Extractor.new(self).execute if file_name?
|
|
46
|
-
validate_parse_present if data?
|
|
47
|
-
talk
|
|
48
|
-
self
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def validate_parse_present
|
|
52
|
-
Validator.new(self).execute
|
|
53
|
-
types.each do |type|
|
|
54
|
-
DataParser.new(self).execute(type)
|
|
55
|
-
Presenter.new(self).execute(type, :text)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
data/lib/rslog/data_parser.rb
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'tools/array'
|
|
4
|
-
require_relative 'tools/hash'
|
|
5
|
-
|
|
6
|
-
# Class to parse data from given array
|
|
7
|
-
#
|
|
8
|
-
class DataParser < Worker
|
|
9
|
-
# type = :count (default) -> just count in groups
|
|
10
|
-
# type = :uniq -> uniq entries in groups
|
|
11
|
-
def execute(type)
|
|
12
|
-
container.result =
|
|
13
|
-
container.data
|
|
14
|
-
.group_by_index(0)
|
|
15
|
-
.send("count_by_groups_#{type}")
|
|
16
|
-
.to_a
|
|
17
|
-
.sort_by { |item| item[1] }
|
|
18
|
-
.reverse
|
|
19
|
-
.map { |elem_arr| elem_arr.map(&:to_s).join(' ') }
|
|
20
|
-
self
|
|
21
|
-
end
|
|
22
|
-
end
|
data/lib/rslog/decorators.rb
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Class to present result in needed format
|
|
4
|
-
#
|
|
5
|
-
module Decorators
|
|
6
|
-
def self.all_title
|
|
7
|
-
'List of webpages with most page views ordered from most views to less'
|
|
8
|
-
end
|
|
9
|
-
def self.all_suffix
|
|
10
|
-
'visits'
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.uniq_title
|
|
14
|
-
'List list of webpages with most unique page views also ordered'
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def self.uniq_suffix
|
|
18
|
-
'unique views'
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def self.separator
|
|
22
|
-
'-----------------------------'
|
|
23
|
-
end
|
|
24
|
-
end
|
data/lib/rslog/extractor.rb
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Class for extracting data from file
|
|
4
|
-
#
|
|
5
|
-
class Extractor < Worker
|
|
6
|
-
def execute
|
|
7
|
-
check
|
|
8
|
-
self
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
private
|
|
12
|
-
|
|
13
|
-
def file_name
|
|
14
|
-
container.file_name
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def check
|
|
18
|
-
if File.zero?(file_name)
|
|
19
|
-
container.add_message 'Empty file'
|
|
20
|
-
else
|
|
21
|
-
container.data = File.open(file_name, 'r').to_a
|
|
22
|
-
container.add_message 'Data in place'
|
|
23
|
-
end
|
|
24
|
-
rescue StandardError => e
|
|
25
|
-
container.add_error e
|
|
26
|
-
end
|
|
27
|
-
end
|
data/lib/rslog/input_parser.rb
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'optparse'
|
|
4
|
-
require_relative 'opts'
|
|
5
|
-
|
|
6
|
-
# Class to parse input filenames and args
|
|
7
|
-
#
|
|
8
|
-
class InputParser < Worker
|
|
9
|
-
include Opts
|
|
10
|
-
|
|
11
|
-
def execute
|
|
12
|
-
handle_opts
|
|
13
|
-
handle_args
|
|
14
|
-
self
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
private
|
|
18
|
-
|
|
19
|
-
def handle_opts
|
|
20
|
-
Opts.create_opts.parse!(into: container.options)
|
|
21
|
-
rescue OptionParser::InvalidOption => e
|
|
22
|
-
container.add_error e
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def handle_args
|
|
26
|
-
container.file_name = ARGV.select { |str| str =~ /.\.log|.\.txt/ }[0] || ''
|
|
27
|
-
container.add_error 'No file_name provided' if container.file_name.empty?
|
|
28
|
-
end
|
|
29
|
-
end
|
data/lib/rslog/opts.rb
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Service module to give opts
|
|
4
|
-
#
|
|
5
|
-
module Opts
|
|
6
|
-
VERSION = {
|
|
7
|
-
descr: ['-v', '--version', 'Show version and exit'],
|
|
8
|
-
action: proc do
|
|
9
|
-
puts "#{File.basename($PROGRAM_NAME)}: #{RSlog::VERSION}"
|
|
10
|
-
end
|
|
11
|
-
}.freeze
|
|
12
|
-
|
|
13
|
-
HELP = {
|
|
14
|
-
descr: ['-h', '--help', 'Prints this message and exit'],
|
|
15
|
-
action: proc do |opts|
|
|
16
|
-
puts opts
|
|
17
|
-
end
|
|
18
|
-
}.freeze
|
|
19
|
-
|
|
20
|
-
def self.create_opts
|
|
21
|
-
OptionParser.new do |opts|
|
|
22
|
-
banner(opts)
|
|
23
|
-
help(opts)
|
|
24
|
-
version(opts)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def self.banner(opts)
|
|
29
|
-
opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} FILENAME"
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def self.help(opts)
|
|
33
|
-
opts.on(*Opts::VERSION[:descr]) do
|
|
34
|
-
Opts::VERSION[:action].call
|
|
35
|
-
exit
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def self.version(opts)
|
|
40
|
-
opts.on(*Opts::HELP[:descr]) do
|
|
41
|
-
Opts::HELP[:action].call(opts)
|
|
42
|
-
exit
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
data/lib/rslog/tools/array.rb
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Monkey patch for Array class
|
|
4
|
-
#
|
|
5
|
-
class Array
|
|
6
|
-
def group_by_index(index = 0)
|
|
7
|
-
group_by { |str| str.split(' ')[index] }
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def to_multiline_string(suffix = '')
|
|
11
|
-
map { |item| "#{item} #{suffix}" }.join("\n")
|
|
12
|
-
end
|
|
13
|
-
end
|
data/lib/rslog/tools/hash.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'set'
|
|
4
|
-
|
|
5
|
-
# Monkey patch for a Hash class to make counts
|
|
6
|
-
#
|
|
7
|
-
class Hash
|
|
8
|
-
def count_by_groups_all
|
|
9
|
-
res = {}
|
|
10
|
-
each do |group_key, arr|
|
|
11
|
-
res[group_key] = arr.size
|
|
12
|
-
end
|
|
13
|
-
res
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def count_by_groups_uniq
|
|
17
|
-
res = {}
|
|
18
|
-
each do |group_key, arr|
|
|
19
|
-
res[group_key] = Set.new(arr).size
|
|
20
|
-
end
|
|
21
|
-
res
|
|
22
|
-
end
|
|
23
|
-
end
|
data/lib/rslog/worker.rb
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Class to hold worker functionality
|
|
4
|
-
#
|
|
5
|
-
class Worker
|
|
6
|
-
attr_reader :container
|
|
7
|
-
|
|
8
|
-
def initialize(container)
|
|
9
|
-
@container = container
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def execute
|
|
13
|
-
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
|
|
14
|
-
end
|
|
15
|
-
end
|