dummy_log_generator 0.0.4 → 0.1.0

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: 38e90f1ce32f540d7c61384166fdfd4ff9f96848
4
- data.tar.gz: c12675bd60344e5f33781f02147462867a30a87e
3
+ metadata.gz: 6a76a35eb0df876125713ea8afd7d3128368e73b
4
+ data.tar.gz: e97dc9abc1fff91fcb1e4c6b5b8179b9c25cf596
5
5
  SHA512:
6
- metadata.gz: fdc71004c1590c96b72db467ac142da5482711171f0706c5236951489d865a8ce5656a4e3c85b4af819d86149168c705ac830ce95644395992c61ae17ad04e32
7
- data.tar.gz: 638c8ac586c1e18e72dee2143053657619092dfb6f679ff995d9f7b776a0357965757d452735c75e3e45194fc46be9f5f425adb9436217e05b67ac5a4d9dcf00
6
+ metadata.gz: 65200ca5573a8f275ee1dfd1c5869ce30d1e5840737ff55eefc5c45d90c0d9b7c2729976274e6d8a549183c6337d29c3484e2bbf9f4b1aa84e407752f9bd586a
7
+ data.tar.gz: 15921096adbdd0d1214a7a6afb0b9d29a74b5be39da3af8b4a0b01918597c671d903d044658fa98f7dfeca88289d7ad05e9efc9e007294e2392f4cf0cf2c4cab
data/.gitignore CHANGED
@@ -23,4 +23,6 @@ rdoc
23
23
  spec/reports
24
24
  test/tmp
25
25
  test/version_tmp
26
- tmp
26
+ dummy_log_generator.pid
27
+ dummy_log_generator.log
28
+
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ### 0.1.0
2
+
3
+ Enhancement:
4
+
5
+ * Support to output into a file (`output` option)
6
+ * No dependency on active_support
7
+ * Speed-up (Proc-based evaluation)
8
+ * Support parallel (`workers` option)
9
+
1
10
  ### 0.0.4
2
11
 
3
12
  Enhancement:
data/README.md CHANGED
@@ -27,6 +27,7 @@ Sample configuration is as follows:
27
27
  ```ruby
28
28
  # dummy_log_generator.conf
29
29
  configure 'sample' do
30
+ output dummy.log
30
31
  rate 500
31
32
  delimiter "\t"
32
33
  labeled true
@@ -40,7 +41,7 @@ configure 'sample' do
40
41
  end
41
42
  ```
42
43
 
43
- Running dummy_log_generator outputs like
44
+ Running dummy_log_generator outputs to `dummy.log` like
44
45
 
45
46
  ```
46
47
  id:422 time:[2013-11-19 02:34:58] level:INFO method:POST uri:/api/v1/textdata reqtime:3.9726677258569842 foobar:LFK6XV1N
@@ -52,6 +53,10 @@ id:424 time:[2013-11-19 02:34:58] level:WARN method:POST uri:/api/v1/textdata
52
53
 
53
54
  Following parameters for configuration is available
54
55
 
56
+ * output
57
+
58
+ Specify a filename to output, or IO object (STDOUT, STDERR)
59
+
55
60
  * rate
56
61
 
57
62
  Specify how many messages to generate per second. Default: 500 msgs / sec
@@ -88,10 +93,6 @@ You can specify following data types to your `field` parameters:
88
93
 
89
94
  * :string
90
95
 
91
- * :format
92
-
93
- You can specify a format of string as `%s`.
94
-
95
96
  * :any
96
97
 
97
98
  You can specify an array of strings, then the generator picks one from them randomly
@@ -143,9 +144,6 @@ There is a [fluent-plugin-dummydata-producer](https://github.com/tagomoris/fluen
143
144
  ## ToDO
144
145
 
145
146
  1. write tests
146
- 2. make it slim (remove active_support, etc)
147
- 3. outputs to a file (currently, outputs to STDOUT)
148
- 4. speed up (evaluate fields at only starting up)
149
147
 
150
148
  ## Contributing
151
149
 
@@ -1,8 +1,9 @@
1
1
  configure 'sample' do
2
+ # output "dummy_log_generator.log"
2
3
  rate 500
3
4
  delimiter "\t"
4
5
  labeled true
5
- field :id, type: :integer, countup: true
6
+ field :id, type: :integer, countup: true, format: "%04d"
6
7
  field :time, type: :datetime, format: "[%Y-%m-%d %H:%M:%S]", random: false
7
8
  field :level, type: :string, any: %w[DEBUG INFO WARN ERROR]
8
9
  field :method, type: :string, any: %w[GET POST PUT]
@@ -20,8 +20,6 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency "thor"
22
22
  spec.add_dependency "serverengine"
23
- spec.add_dependency "active_support"
24
- spec.add_dependency "i18n"
25
23
 
26
24
  spec.add_development_dependency "bundler", "~> 1.3"
27
25
  spec.add_development_dependency "rake"
@@ -1,8 +1,6 @@
1
- require 'logger'
2
1
  require "dummy_log_generator/version"
3
2
  require "dummy_log_generator/error"
3
+ require "dummy_log_generator/setting"
4
4
  require "dummy_log_generator/generator"
5
- require "dummy_log_generator/formatter"
6
5
  require "dummy_log_generator/worker"
7
6
  require "dummy_log_generator/dsl"
8
-
@@ -1,39 +1,39 @@
1
1
  require 'thor'
2
2
  require 'dummy_log_generator'
3
- require 'active_support/core_ext'
3
+ require 'ext/hash/keys'
4
+ require 'ext/hash/except'
4
5
 
5
6
  module DummyLogGenerator
6
7
  class CLI < Thor
7
- class_option :config, :aliases => ["-c"], :type => :string, :default => 'dummy_log_generator.conf'
8
+ # options for serverengine
9
+ class_option :pid_path, :aliases => ["-p"], :type => :string, :default => 'dummy_log_generator.pid'
8
10
  default_command :start
9
11
 
10
12
  def initialize(args = [], opts = [], config = {})
11
13
  super(args, opts, config)
12
-
13
- @options = @options.dup # avoid frozen
14
- if options[:config] && File.exists?(options[:config])
15
- dsl = instance_eval(File.read(options[:config]), options[:config])
16
- @options[:generator] = dsl.generator
17
- @options[:formatter] = dsl.formatter
18
- @options[:rate] = dsl.config.rate
19
- end
20
14
  end
21
15
 
22
16
  desc "start", "Start a dummy_log_generator"
23
- option :require, :aliases => ["-r"], :type => :string
17
+ option :config, :aliases => ["-c"], :type => :string, :default => 'dummy_log_generator.conf'
18
+ # options for serverengine
24
19
  option :daemonize, :aliases => ["-d"], :type => :boolean
25
- option :module_name, :aliases => ["-m"], :type => :string, :default => 'DummyLogGenerator::Worker'
26
- # options for dummy_log_generator
27
- option :rate, :aliases => ["-i"], :type => :numeric
20
+ option :workers, :aliases => ["-w"], :type => :numeric
21
+ option :worker_type, :type => :string, :default => 'process'
28
22
  def start
29
- opts = @options.symbolize_keys.except(:require, :config, :module_name)
23
+ @options = @options.dup # avoid frozen
24
+ if options[:config] && File.exists?(options[:config])
25
+ dsl = instance_eval(File.read(options[:config]), options[:config])
26
+ @options[:setting] = dsl.setting
27
+ # options for serverengine
28
+ @options[:workers] ||= dsl.setting.workers
29
+ end
30
30
 
31
- se = ServerEngine.create(nil, @options["module_name"].constantize, opts)
31
+ opts = @options.symbolize_keys.except(:config)
32
+ se = ServerEngine.create(nil, DummyLogGenerator::Worker, opts)
32
33
  se.run
33
34
  end
34
35
 
35
36
  desc "stop", "Stops a dummy_log_generator"
36
- option :pid_path, :aliases => ["-p"], :type => :string
37
37
  def stop
38
38
  pid = File.read(@options["pid_path"]).to_i
39
39
 
@@ -46,7 +46,6 @@ module DummyLogGenerator
46
46
  end
47
47
 
48
48
  desc "graceful_stop", "Gracefully stops a dummy_log_generator"
49
- option :pid_path, :aliases => ["-p"], :type => :string
50
49
  def graceful_stop
51
50
  pid = File.read(@options["pid_path"]).to_i
52
51
 
@@ -59,7 +58,6 @@ module DummyLogGenerator
59
58
  end
60
59
 
61
60
  desc "restart", "Restarts a dummy_log_generator"
62
- option :pid_path, :aliases => ["-p"], :type => :string
63
61
  def restart
64
62
  pid = File.read(@options["pid_path"]).to_i
65
63
 
@@ -72,7 +70,6 @@ module DummyLogGenerator
72
70
  end
73
71
 
74
72
  desc "graceful_restart", "Graceful restarts a dummy_log_generator"
75
- option :pid_path, :aliases => ["-p"], :type => :string
76
73
  def graceful_restart
77
74
  pid = File.read(@options["pid_path"]).to_i
78
75
 
@@ -1,39 +1,33 @@
1
- module DummyLogGenerator
2
- class Config
3
- attr_accessor :rate
4
-
5
- def initiaize
6
- @rate = 500
7
- end
8
- end
9
- end
10
-
11
1
  module DummyLogGenerator
12
2
  class Dsl
13
- attr_reader :generator
14
- attr_reader :formatter
15
- attr_reader :config
3
+ attr_reader :setting
16
4
 
17
5
  def initialize
18
- @generator = Generator.new
19
- @formatter = Formatter.new
20
- @config = Config.new
6
+ @setting = Setting.new
21
7
  end
22
8
 
23
9
  def rate(rate)
24
- config.rate = rate
10
+ setting.rate = rate
11
+ end
12
+
13
+ def output(output)
14
+ setting.output = output
25
15
  end
26
16
 
27
17
  def field(name, opts)
28
- generator.fields[name] = opts
18
+ setting.fields[name] = opts
29
19
  end
30
20
 
31
21
  def delimiter(delimiter)
32
- formatter.delimiter = delimiter
22
+ setting.delimiter = delimiter
33
23
  end
34
24
 
35
25
  def labeled(labeled)
36
- formatter.labeled = labeled
26
+ setting.labeled = labeled
27
+ end
28
+
29
+ def workers(workers)
30
+ setting.workers = workers
37
31
  end
38
32
  end
39
33
  end
@@ -1,35 +1,45 @@
1
1
  module DummyLogGenerator
2
2
  class Generator
3
- attr_accessor :fields
4
- attr_reader :rand
3
+ def initialize(setting)
4
+ prepare_format_proc(setting.labeled, setting.delimiter)
5
+ prepare_field_procs(setting.fields)
6
+ end
5
7
 
6
- def initialize
7
- @fields = {}
8
- @rand = ::DummyLogGenerator::Random.new
8
+ def prepare_format_proc(labeled, delimiter)
9
+ @format_proc =
10
+ if labeled
11
+ Proc.new {|fields| fields.map {|key, val| "#{key}:#{val}" }.join(delimiter) }
12
+ else
13
+ Proc.new {|fields| fields.values.join(delimiter) }
14
+ end
9
15
  end
10
16
 
11
- def generate(prev_data = {})
12
- data = {}
17
+ def prepare_field_procs(fields)
18
+ rand = ::DummyLogGenerator::Random.new
19
+ @field_procs = {}
13
20
  fields.each do |key, opts|
14
21
  opts = opts.dup
15
22
  type = opts.delete(:type)
16
- opts[:prev] = prev_data[key]
17
- data[key] = case type
18
- when :datetime
19
- rand.datetime(opts)
20
- when :string
21
- rand.string(opts)
22
- when :integer
23
- rand.integer(opts)
24
- when :float
25
- rand.float(opts)
26
- else
27
- raise ConfigError.new(type)
28
- end
23
+ if rand.respond_to?(type)
24
+ @field_procs[key] = rand.send(type, opts)
25
+ else
26
+ raise ConfigError.new(type)
27
+ end
28
+ end
29
+ end
30
+
31
+ def generate(prev_data = {})
32
+ data = {}
33
+ @field_procs.each do |key, proc|
34
+ prev = prev_data[key] || -1
35
+ data[key] = proc.call(prev)
29
36
  end
30
37
  data
31
38
  end
32
- alias_method :gen, :generate
39
+
40
+ def format(fields)
41
+ @format_proc.call(fields)
42
+ end
33
43
  end
34
44
 
35
45
  class Random
@@ -38,59 +48,82 @@ module DummyLogGenerator
38
48
  @chars = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a # no symbols and multi-bytes for now
39
49
  end
40
50
 
41
- def string(format: nil, length: 8, any: nil, prev: nil, value: nil)
42
- string = if value
43
- value.to_s
44
- elsif any
45
- self.any(any)
46
- else
47
- Array.new(length){@chars[rand(@chars.size-1)]}.join
48
- end
49
- format ? sprintf(format, string) : string
51
+ def string(length: 8, any: nil, value: nil)
52
+ if value
53
+ string = value.to_s
54
+ Proc.new { string }
55
+ elsif any
56
+ Proc.new { self.any(any) }
57
+ else
58
+ Proc.new { Array.new(length){@chars[rand(@chars.size-1)]}.join }
59
+ end
50
60
  end
51
61
 
52
- def integer(format: nil, range: nil, countup: false, prev: nil, value: nil)
53
- integer = if value
54
- value.to_i
55
- elsif range
56
- self.range(range)
57
- elsif countup
58
- prev ||= -1
59
- prev.to_i + 1
60
- else
61
- rand(0..2,147,483,647)
62
- end
63
- format ? sprintf(format, integer) : integer
62
+ def integer(format: nil, range: nil, countup: false, value: nil)
63
+ if format
64
+ if value
65
+ integer = sprintf(format, value.to_i)
66
+ Proc.new { integer }
67
+ elsif range
68
+ Proc.new { sprintf(format, self.range(range)) }
69
+ elsif countup
70
+ Proc.new {|prev| sprintf(format, prev.to_i + 1) }
71
+ else
72
+ Proc.new { sprintf(format, rand(0..2,147,483,647)) }
73
+ end
74
+ else
75
+ if value
76
+ integer = value.to_i
77
+ Proc.new { integer }
78
+ elsif range
79
+ Proc.new { self.range(range) }
80
+ elsif countup
81
+ Proc.new {|prev| prev + 1 }
82
+ else
83
+ Proc.new { rand(0..2,147,483,647) }
84
+ end
85
+ end
64
86
  end
65
87
 
66
- def float(format: nil, range: nil, prev: nil, value: nil)
67
- float = if value
68
- value.to_f
69
- elsif range
70
- self.range(range)
71
- else
72
- r = rand(1..358)
73
- r * Math.cos(r) # cheat
74
- end
75
- format ? sprintf(format, float) : float
88
+ def float(format: nil, range: nil, value: nil)
89
+ if format
90
+ if value
91
+ float = value.to_f
92
+ Proc.new { sprintf(format, float) }
93
+ elsif range
94
+ Proc.new { sprintf(format, self.range(range)) }
95
+ else
96
+ Proc.new { r = rand(1..358); sprintf(format, r * Math.cos(r)) }
97
+ end
98
+ else
99
+ if value
100
+ float = value.to_f
101
+ Proc.new { float }
102
+ elsif range
103
+ Proc.new { self.range(range) }
104
+ else
105
+ Proc.new { r = rand(1..358); r * Math.cos(r) }
106
+ end
107
+ end
76
108
  end
77
109
 
78
- def datetime(format: "%Y-%m-%d %H:%M:%S.%3N", random: false, prev: nil, value: nil)
79
- time = if value
80
- value
81
- elsif random
82
- y = rand(1970..2037);
83
- m = rand(1..12);
84
- d = rand(1..27);
85
- h = rand(0..23);
86
- min = rand(0..59);
87
- s = rand(0..59);
88
- usec = rand(0..999999);
89
- Time.local(y, m, d, h, min, s, usec)
90
- else
91
- Time.now
92
- end
93
- time.strftime(format)
110
+ def datetime(format: "%Y-%m-%d %H:%M:%S.%3N", random: false, value: nil)
111
+ if value
112
+ Proc.new { value.sprintf(format) }
113
+ elsif random
114
+ Proc.new {
115
+ y = rand(1970..2037);
116
+ m = rand(1..12);
117
+ d = rand(1..27);
118
+ h = rand(0..23);
119
+ min = rand(0..59);
120
+ s = rand(0..59);
121
+ usec = rand(0..999999);
122
+ Time.local(y, m, d, h, min, s, usec)
123
+ }
124
+ else
125
+ Proc.new { Time.now }
126
+ end
94
127
  end
95
128
 
96
129
  def range(range)
@@ -0,0 +1,14 @@
1
+ module DummyLogGenerator
2
+ class Setting
3
+ attr_accessor :rate, :output, :labeled, :delimiter, :fields, :workers
4
+
5
+ def initialize
6
+ @rate = 500
7
+ @output = STDOUT
8
+ @labeled = true
9
+ @delimiter = "\t"
10
+ @fields = {}
11
+ @workers = 1
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,3 @@
1
1
  module DummyLogGenerator
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -7,9 +7,16 @@ module DummyLogGenerator
7
7
  end
8
8
 
9
9
  def reload
10
- @rate = config[:rate]
11
- @formatter = config[:formatter]
12
- @generator = config[:generator]
10
+ @generator = Generator.new(config[:setting])
11
+ @rate = config[:setting].rate
12
+
13
+ output = config[:setting].output
14
+ if output.respond_to?(:write) and output.respond_to?(:close)
15
+ @output = output
16
+ else
17
+ @output = open(output, (File::WRONLY | File::APPEND | File::CREAT))
18
+ @output.sync = true
19
+ end
13
20
  end
14
21
 
15
22
  # thanks! ref. https://github.com/tagomoris/fluent-plugin-dummydata-producer/blob/a550fd4424f71cd9227e138c3c89f600ba40a0d5/lib/fluent/plugin/in_dummydata_producer.rb#L63
@@ -25,7 +32,7 @@ module DummyLogGenerator
25
32
  # ToDo: what if generation is slower than I/O?
26
33
  # We may should generate data and output in parallel
27
34
  prev_data = @generator.generate(prev_data)
28
- STDOUT.puts @formatter.format(prev_data)
35
+ @output.write "#{@generator.format(prev_data)}\n"
29
36
  end
30
37
  rate_count += batch_num
31
38
  sleep 0.1
@@ -35,6 +42,8 @@ module DummyLogGenerator
35
42
  sleep 0.04
36
43
  end
37
44
  end
45
+ ensure
46
+ @output.close
38
47
  end
39
48
 
40
49
  def stop
@@ -0,0 +1,15 @@
1
+ class Hash
2
+ # Return a hash that includes everything but the given keys. This is useful for
3
+ # limiting a set of parameters to everything but a few known toggles:
4
+ #
5
+ # @person.update(params[:person].except(:admin))
6
+ def except(*keys)
7
+ dup.except!(*keys)
8
+ end
9
+
10
+ # Replaces the hash without the given keys.
11
+ def except!(*keys)
12
+ keys.each { |key| delete(key) }
13
+ self
14
+ end
15
+ end
@@ -0,0 +1,138 @@
1
+ class Hash
2
+ # Return a new hash with all keys converted using the block operation.
3
+ #
4
+ # hash = { name: 'Rob', age: '28' }
5
+ #
6
+ # hash.transform_keys{ |key| key.to_s.upcase }
7
+ # # => {"NAME"=>"Rob", "AGE"=>"28"}
8
+ def transform_keys
9
+ result = {}
10
+ each_key do |key|
11
+ result[yield(key)] = self[key]
12
+ end
13
+ result
14
+ end
15
+
16
+ # Destructively convert all keys using the block operations.
17
+ # Same as transform_keys but modifies +self+.
18
+ def transform_keys!
19
+ keys.each do |key|
20
+ self[yield(key)] = delete(key)
21
+ end
22
+ self
23
+ end
24
+
25
+ # Return a new hash with all keys converted to strings.
26
+ #
27
+ # hash = { name: 'Rob', age: '28' }
28
+ #
29
+ # hash.stringify_keys
30
+ # # => {"name"=>"Rob", "age"=>"28"}
31
+ def stringify_keys
32
+ transform_keys{ |key| key.to_s }
33
+ end
34
+
35
+ # Destructively convert all keys to strings. Same as
36
+ # +stringify_keys+, but modifies +self+.
37
+ def stringify_keys!
38
+ transform_keys!{ |key| key.to_s }
39
+ end
40
+
41
+ # Return a new hash with all keys converted to symbols, as long as
42
+ # they respond to +to_sym+.
43
+ #
44
+ # hash = { 'name' => 'Rob', 'age' => '28' }
45
+ #
46
+ # hash.symbolize_keys
47
+ # # => {"name"=>"Rob", "age"=>"28"}
48
+ def symbolize_keys
49
+ transform_keys{ |key| key.to_sym rescue key }
50
+ end
51
+ alias_method :to_options, :symbolize_keys
52
+
53
+ # Destructively convert all keys to symbols, as long as they respond
54
+ # to +to_sym+. Same as +symbolize_keys+, but modifies +self+.
55
+ def symbolize_keys!
56
+ transform_keys!{ |key| key.to_sym rescue key }
57
+ end
58
+ alias_method :to_options!, :symbolize_keys!
59
+
60
+ # Validate all keys in a hash match <tt>*valid_keys</tt>, raising ArgumentError
61
+ # on a mismatch. Note that keys are NOT treated indifferently, meaning if you
62
+ # use strings for keys but assert symbols as keys, this will fail.
63
+ #
64
+ # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: years"
65
+ # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: name"
66
+ # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing
67
+ def assert_valid_keys(*valid_keys)
68
+ valid_keys.flatten!
69
+ each_key do |k|
70
+ raise ArgumentError.new("Unknown key: #{k}") unless valid_keys.include?(k)
71
+ end
72
+ end
73
+
74
+ # Return a new hash with all keys converted by the block operation.
75
+ # This includes the keys from the root hash and from all
76
+ # nested hashes.
77
+ #
78
+ # hash = { person: { name: 'Rob', age: '28' } }
79
+ #
80
+ # hash.deep_transform_keys{ |key| key.to_s.upcase }
81
+ # # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
82
+ def deep_transform_keys(&block)
83
+ result = {}
84
+ each do |key, value|
85
+ result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
86
+ end
87
+ result
88
+ end
89
+
90
+ # Destructively convert all keys by using the block operation.
91
+ # This includes the keys from the root hash and from all
92
+ # nested hashes.
93
+ def deep_transform_keys!(&block)
94
+ keys.each do |key|
95
+ value = delete(key)
96
+ self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value
97
+ end
98
+ self
99
+ end
100
+
101
+ # Return a new hash with all keys converted to strings.
102
+ # This includes the keys from the root hash and from all
103
+ # nested hashes.
104
+ #
105
+ # hash = { person: { name: 'Rob', age: '28' } }
106
+ #
107
+ # hash.deep_stringify_keys
108
+ # # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
109
+ def deep_stringify_keys
110
+ deep_transform_keys{ |key| key.to_s }
111
+ end
112
+
113
+ # Destructively convert all keys to strings.
114
+ # This includes the keys from the root hash and from all
115
+ # nested hashes.
116
+ def deep_stringify_keys!
117
+ deep_transform_keys!{ |key| key.to_s }
118
+ end
119
+
120
+ # Return a new hash with all keys converted to symbols, as long as
121
+ # they respond to +to_sym+. This includes the keys from the root hash
122
+ # and from all nested hashes.
123
+ #
124
+ # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
125
+ #
126
+ # hash.deep_symbolize_keys
127
+ # # => {:person=>{:name=>"Rob", :age=>"28"}}
128
+ def deep_symbolize_keys
129
+ deep_transform_keys{ |key| key.to_sym rescue key }
130
+ end
131
+
132
+ # Destructively convert all keys to symbols, as long as they respond
133
+ # to +to_sym+. This includes the keys from the root hash and from all
134
+ # nested hashes.
135
+ def deep_symbolize_keys!
136
+ deep_transform_keys!{ |key| key.to_sym rescue key }
137
+ end
138
+ end
@@ -0,0 +1,42 @@
1
+ class Hash
2
+ # Slice a hash to include only the given keys. This is useful for
3
+ # limiting an options hash to valid keys before passing to a method:
4
+ #
5
+ # def search(criteria = {})
6
+ # criteria.assert_valid_keys(:mass, :velocity, :time)
7
+ # end
8
+ #
9
+ # search(options.slice(:mass, :velocity, :time))
10
+ #
11
+ # If you have an array of keys you want to limit to, you should splat them:
12
+ #
13
+ # valid_keys = [:mass, :velocity, :time]
14
+ # search(options.slice(*valid_keys))
15
+ def slice(*keys)
16
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
17
+ keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
18
+ end
19
+
20
+ # Replaces the hash with only the given keys.
21
+ # Returns a hash containing the removed key/value pairs.
22
+ #
23
+ # { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
24
+ # # => {:c=>3, :d=>4}
25
+ def slice!(*keys)
26
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
27
+ omit = slice(*self.keys - keys)
28
+ hash = slice(*keys)
29
+ hash.default = default
30
+ hash.default_proc = default_proc if default_proc
31
+ replace(hash)
32
+ omit
33
+ end
34
+
35
+ # Removes and returns the key/value pairs matching the given keys.
36
+ #
37
+ # { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2}
38
+ # { a: 1, b: 2 }.extract!(:a, :x) # => {:a=>1}
39
+ def extract!(*keys)
40
+ keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
41
+ end
42
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dummy_log_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sonots
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-18 00:00:00.000000000 Z
11
+ date: 2013-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -38,34 +38,6 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: active_support
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '>='
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: i18n
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - '>='
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
41
  - !ruby/object:Gem::Dependency
70
42
  name: bundler
71
43
  requirement: !ruby/object:Gem::Requirement
@@ -158,10 +130,13 @@ files:
158
130
  - lib/dummy_log_generator/cli.rb
159
131
  - lib/dummy_log_generator/dsl.rb
160
132
  - lib/dummy_log_generator/error.rb
161
- - lib/dummy_log_generator/formatter.rb
162
133
  - lib/dummy_log_generator/generator.rb
134
+ - lib/dummy_log_generator/setting.rb
163
135
  - lib/dummy_log_generator/version.rb
164
136
  - lib/dummy_log_generator/worker.rb
137
+ - lib/ext/hash/except.rb
138
+ - lib/ext/hash/keys.rb
139
+ - lib/ext/hash/slice.rb
165
140
  homepage: https://github.com/sonots/dummy_log_generator
166
141
  licenses:
167
142
  - MIT
@@ -1,18 +0,0 @@
1
- module DummyLogGenerator
2
- class Formatter
3
- attr_accessor :labeled, :delimiter
4
-
5
- def initialize
6
- @labeled = true
7
- @delimiter = "\t"
8
- end
9
-
10
- def format(fields)
11
- if labeled
12
- fields.map {|key, val| "#{key}:#{val}" }.join(delimiter)
13
- else
14
- fields.values.join(delimiter)
15
- end
16
- end
17
- end
18
- end