l2meter 0.7.0 → 0.8.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: 0f840ff86f170320c7b8800247ff31827ea8ebba
4
- data.tar.gz: 048da3851b32cf7f79fe481c9f62882fec540004
3
+ metadata.gz: 4f4adb53ff781efc36f715a3cace441b9020719f
4
+ data.tar.gz: fd0e1932d11244637a20f3d63430ea176cf69441
5
5
  SHA512:
6
- metadata.gz: 96f55fe64f2ea359780693faa6ed160d340fa83528fadf1200e4bb5972ea9692f4ee994cb6e4fc51f53e1f0c6e80fd467e962e046e05b7dee55fbf6b6301c040
7
- data.tar.gz: 7dc8a4cd1fbf39654320f1cc96d18a90322ac8046fed7b55cfd49b1857c92bca1aff18a7b072b060cd37ef21ab3f039513a726d34621cd6299fadd95a51c7401
6
+ metadata.gz: 8aeeb27f3afa5ddcb71db8dce17ee624e339cae4fccc7ba064cbdf65372e51609da4849e93d575297332e40851d11d618d0c40266ba2ac198cf485bfb07b8033
7
+ data.tar.gz: 8a8a6555a573d7743f2a94939c1a7e8b51cbff0c226e8fb9de3f1f660dc748857ed32e4d18fc901545764a99223d59b074520661744fdea23d4a31fe7ba4cea1
@@ -1,35 +1,26 @@
1
1
  module L2meter
2
2
  class Configuration
3
3
  attr_writer :output
4
- attr_accessor :source, :prefix
5
- attr_reader :context, :key_formatter, :value_formatter, :output
4
+ attr_accessor :source, :prefix, :float_precision
5
+ attr_reader :context, :key_formatter, :output
6
6
 
7
7
  DEFAULT_KEY_FORMATTER = ->(key) do
8
- key.to_s.strip.downcase.gsub(/[^-a-z\d.#]+/, ?_)
8
+ key.to_s.strip.downcase.gsub(/[^-a-z\d.#]+/, ?-)
9
9
  end
10
10
 
11
- DEFAULT_VALUE_FORMATTER = ->(value) do
12
- value = value.to_s.strip
13
- value =~ /\s/ ? value.gsub(/\s+/, " ").inspect : value
14
- end
15
-
16
- private_constant :DEFAULT_KEY_FORMATTER, :DEFAULT_VALUE_FORMATTER
11
+ private_constant :DEFAULT_KEY_FORMATTER
17
12
 
18
13
  def initialize
19
14
  @sort = false
20
15
  @key_formatter = DEFAULT_KEY_FORMATTER
21
- @value_formatter = DEFAULT_VALUE_FORMATTER
22
16
  @output = $stdout
17
+ @float_precision = 4
23
18
  end
24
19
 
25
20
  def format_keys(&block)
26
21
  @key_formatter = block
27
22
  end
28
23
 
29
- def format_values(&block)
30
- @value_formatter = block
31
- end
32
-
33
24
  def sort?
34
25
  @sort
35
26
  end
@@ -1,3 +1,5 @@
1
+ require "time"
2
+
1
3
  module L2meter
2
4
  class Emitter
3
5
  attr_reader :configuration
@@ -12,13 +14,15 @@ module L2meter
12
14
  end
13
15
 
14
16
  def log(*args)
15
- params = unwrap(*args)
16
- params = merge_contexts(params)
17
+ merge! source: configuration.source
18
+ merge! *current_contexts
19
+ merge! *args
20
+ elapse!
17
21
 
18
22
  if block_given?
19
- wrap params, &proc
23
+ wrap &proc
20
24
  else
21
- write params
25
+ write
22
26
  end
23
27
  end
24
28
 
@@ -85,67 +89,90 @@ module L2meter
85
89
  yield
86
90
  ensure
87
91
  @autoflush = true
88
- flush_buffer
92
+ fire!
89
93
  end
90
94
 
91
- protected
92
-
93
- def push_context(context_data)
94
- @contexts.concat context_data.reverse
95
+ def merge!(*args)
96
+ @buffer.merge! format_keys(unwrap(args))
95
97
  end
96
98
 
97
- private
99
+ def fire!
100
+ tokens = @buffer.map do |key, value|
101
+ next if value.nil?
102
+ key = format_key(key)
103
+ value == true ? key : "#{key}=#{format_value(value)}"
104
+ end.compact
98
105
 
99
- def clone_with_context(context)
100
- clone.tap do |emitter|
101
- emitter.push_context context
102
- end
103
- end
106
+ tokens.sort! if configuration.sort?
104
107
 
105
- def unwrap(*args)
106
- params = Hash === args.last ? args.pop : {}
107
- args.compact.map { |key| [key, true] }.to_h.merge(params)
108
+ output_queue.last.print [*tokens].join(" ") + "\n" if tokens.any?
109
+ ensure
110
+ @buffer.clear
108
111
  end
109
112
 
110
- def stringify_keys(hash)
111
- hash.each_with_object({}) { |(k, v), a| a[k.to_s] = v }
113
+ protected
114
+
115
+ def push_context(context_data)
116
+ @contexts.concat context_data
112
117
  end
113
118
 
114
- def merge_contexts(params)
115
- params = current_context.merge(params)
116
- source = configuration.source
117
- params = { source: source }.merge(params) if source
119
+ private
118
120
 
119
- if start_time = @start_times.last
120
- elapsed = Time.now - start_time
121
- params = merge_elapsed(elapsed, params)
121
+ def unwrap(args)
122
+ args.each_with_object({}) do |context, result|
123
+ next if context.nil?
124
+ context = Hash[context, true] unless Hash === context
125
+ result.merge! context
122
126
  end
127
+ end
123
128
 
124
- params
129
+ def format_float(value, unit: nil)
130
+ "%.#{configuration.float_precision}f#{unit}" % value
125
131
  end
126
132
 
127
- def merge_elapsed(elapsed, params)
128
- params.merge(elapsed: "%.4fs" % elapsed)
133
+ def clone_with_context(context)
134
+ clone.tap do |emitter|
135
+ emitter.push_context context
136
+ end
129
137
  end
130
138
 
131
- def current_context
132
- contexts_queue.inject({}) do |result, context|
139
+ def current_contexts
140
+ contexts_queue.map do |context|
133
141
  context = context.call if context.respond_to?(:call)
134
- result.merge(unwrap(context))
135
- end.to_a.reverse.to_h
142
+ context
143
+ end
136
144
  end
137
145
 
138
146
  def format_value(value)
139
- configuration.value_formatter.call(value)
147
+ case value
148
+ when /[^\w,.:@-]/
149
+ value.strip.gsub(/\s+/, " ").inspect
150
+ when String
151
+ value.to_s
152
+ when Float
153
+ format_float(value)
154
+ when Time
155
+ value.iso8601
156
+ when Hash
157
+ format_value(value.inspect)
158
+ when Array
159
+ value.map(&method(:format_value)).join(?,)
160
+ else
161
+ format_value(value.to_s)
162
+ end
140
163
  end
141
164
 
142
165
  def format_key(key)
143
166
  configuration.key_formatter.call(key)
144
167
  end
145
168
 
146
- def write(params)
147
- @buffer.merge! stringify_keys(params)
148
- flush_buffer if @autoflush
169
+ def format_keys(hash)
170
+ hash.each_with_object({}) { |(k, v), a| a[format_key(k)] = v }
171
+ end
172
+
173
+ def write(params = nil)
174
+ merge! params
175
+ fire! if @autoflush
149
176
  end
150
177
 
151
178
  def log_with_prefix(method, key, value, unit: nil)
@@ -153,31 +180,27 @@ module L2meter
153
180
  log Hash["#{method}##{key}", value]
154
181
  end
155
182
 
156
- def wrap(params)
157
- write params.merge(at: :start)
183
+ def wrap
184
+ start_time = Time.now
185
+ params = @buffer.clone
186
+ write at: :start
187
+ result = exception = nil
158
188
 
159
- result, error, elapsed = execute_with_elapsed(&proc)
160
-
161
- status = if error
162
- { at: :exception, exception: error.class, message: error.message.strip }
163
- else
164
- { at: :finish }
189
+ begin
190
+ result = yield
191
+ merge! params, at: :finish
192
+ rescue Object => exception
193
+ merge! params, at: :exception, exception: exception.class, message: exception.message
165
194
  end
166
195
 
167
- write params.merge(merge_elapsed(elapsed, status))
196
+ elapse! start_time
197
+ write
168
198
 
169
- raise error if error
199
+ raise exception if exception
170
200
 
171
201
  result
172
202
  end
173
203
 
174
- def execute_with_elapsed
175
- time_at_start = Time.now
176
- [yield, nil, Time.now - time_at_start]
177
- rescue Object => exception
178
- [nil, exception, Time.now - time_at_start]
179
- end
180
-
181
204
  def contexts_queue
182
205
  [configuration.context, *@contexts].compact
183
206
  end
@@ -186,18 +209,9 @@ module L2meter
186
209
  [configuration.output, *@outputs].compact
187
210
  end
188
211
 
189
- def flush_buffer
190
- tokens = @buffer.map do |key, value|
191
- next if value.nil?
192
- key = format_key(key)
193
- value == true ? key : "#{key}=#{format_value(value)}"
194
- end.compact
195
-
196
- tokens.sort! if configuration.sort?
197
-
198
- output_queue.last.print [*tokens].join(" ") + "\n" if tokens.any?
199
- ensure
200
- @buffer.clear
212
+ def elapse!(since = @start_times.last)
213
+ return unless since
214
+ merge! elapsed: format_float(Time.now - since, unit: ?s)
201
215
  end
202
216
  end
203
217
  end
@@ -1,5 +1,10 @@
1
1
  module L2meter
2
2
  class NullObject
3
+ # Silence forwardable stdlib warnings about forwarding private metods.
4
+ def log(*)
5
+ super
6
+ end
7
+
3
8
  def method_missing(*)
4
9
  yield if block_given?
5
10
  end
@@ -12,8 +12,10 @@ module L2meter
12
12
  batch
13
13
  configuration
14
14
  count
15
+ fire!
15
16
  log
16
17
  measure
18
+ merge!
17
19
  push_context
18
20
  sample
19
21
  silence
@@ -1,3 +1,3 @@
1
1
  module L2meter
2
- VERSION = "0.7.0".freeze
2
+ VERSION = "0.8.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: l2meter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Pravosud
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-02 00:00:00.000000000 Z
11
+ date: 2017-01-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -45,7 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
45
  version: '0'
46
46
  requirements: []
47
47
  rubyforge_project:
48
- rubygems_version: 2.6.7
48
+ rubygems_version: 2.6.8
49
49
  signing_key:
50
50
  specification_version: 4
51
51
  summary: L2met friendly log formatter