l2meter 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 99e89f47ef4f4e2a71ff7867df4e7fd25015c1b0
4
- data.tar.gz: 4ebb453038d24bb27de1aa5b2b1e9558a66760ba
3
+ metadata.gz: f503003e9477cf9593c912bbe56e0ec5732e5888
4
+ data.tar.gz: 5c0f2b7eeb06f8600b8a9204a397f46457dfea51
5
5
  SHA512:
6
- metadata.gz: 24e32b52f972db37ad2878521f340520ea9b7de85d57b0716081816f5c800461c60e2f89b5c79da9dcbedada0dc5dc114e62da22ae5afe5aac90949bbe61778e
7
- data.tar.gz: 587cc1f87cf361935a480c39f80f27d410bf0acd999e3b7f89f9f0b2c3f8bcedb458b7f30153f6ad7a562d35506508573d97585df17961bb6ac3c10af38b2770
6
+ metadata.gz: 70852339270abfbf8abcf19a5b287e92cb7244e496e5aad7a1bb64598feb9e12e4dc0e7bd888887eb3bf84ec7c1661f82ecf31602c472a4484f529259e87e8a1
7
+ data.tar.gz: cd3cb10da8ccb5c15a6576d81812689dc4c7d6a04781613caa9f2f647b13033f595e48b0639a1ff08dac37162d5e6b2d24c2acf5a7487a16ef9e12b618819fdf
@@ -6,10 +6,11 @@ module L2meter
6
6
  autoload :Configuration, "l2meter/configuration"
7
7
  autoload :Emitter, "l2meter/emitter"
8
8
  autoload :NullObject, "l2meter/null_object"
9
+ autoload :ThreadSafe, "l2meter/thread_safe"
9
10
 
10
- def build
11
- Emitter.new.tap do |emitter|
12
- yield emitter.configuration if block_given?
13
- end
11
+ def build(configuration: Configuration.new)
12
+ yield configuration if block_given?
13
+ emitter = Emitter.new(configuration: configuration.freeze)
14
+ ThreadSafe.new(emitter)
14
15
  end
15
16
  end
@@ -2,51 +2,52 @@ module L2meter
2
2
  class Configuration
3
3
  attr_writer :output
4
4
  attr_accessor :source, :prefix
5
- attr_reader :contexts
5
+ attr_reader :context, :key_formatter, :value_formatter, :output
6
6
 
7
- def initialize
8
- @contexts = []
7
+ DEFAULT_KEY_FORMATTER = ->(key) do
8
+ key.to_s.strip.downcase.gsub(/[^-a-z\d.#]+/, ?-)
9
9
  end
10
10
 
11
- def output
12
- @output ||= $stdout
11
+ DEFAULT_VALUE_FORMATTER = ->(value) do
12
+ value = value.to_s
13
+ value =~ /\s/ ? value.inspect : value
13
14
  end
14
15
 
15
- def key_formatter
16
- @key_formatter ||= ->(key) do
17
- key.to_s.strip.downcase.gsub(/[^-a-z\d.#]+/, ?-)
18
- end
16
+ private_constant :DEFAULT_KEY_FORMATTER, :DEFAULT_VALUE_FORMATTER
17
+
18
+ def initialize
19
+ @sort = false
20
+ @key_formatter = DEFAULT_KEY_FORMATTER
21
+ @value_formatter = DEFAULT_VALUE_FORMATTER
22
+ @output = $stdout
19
23
  end
20
24
 
21
25
  def format_keys(&block)
22
26
  @key_formatter = block
23
27
  end
24
28
 
25
- def value_formatter
26
- @value_formatter ||= ->(value) do
27
- value = value.to_s
28
- value =~ /\s/ ? value.inspect : value
29
- end
30
- end
31
-
32
29
  def format_values(&block)
33
30
  @value_formatter = block
34
31
  end
35
32
 
36
33
  def sort?
37
- defined?(@apply_sort) ? @apply_sort : false
34
+ @sort
38
35
  end
39
36
 
40
37
  def sort=(value)
41
- @apply_sort = !!value
38
+ @sort = !!value
42
39
  end
43
40
 
44
- def context(&block)
45
- @contexts = [block]
41
+ def context
42
+ if block_given?
43
+ @context = Proc.new
44
+ else
45
+ @context
46
+ end
46
47
  end
47
48
 
48
49
  def context=(block_or_value)
49
- @contexts = [block_or_value]
50
+ @context = block_or_value
50
51
  end
51
52
  end
52
53
  end
@@ -5,6 +5,8 @@ module L2meter
5
5
  def initialize(configuration: Configuration.new)
6
6
  @configuration = configuration
7
7
  @start_times = []
8
+ @contexts = []
9
+ @outputs = []
8
10
  end
9
11
 
10
12
  def log(*args)
@@ -26,11 +28,10 @@ module L2meter
26
28
  end
27
29
 
28
30
  def silence
29
- output = configuration.output
30
- configuration.output = NullObject.new
31
+ @outputs.push NullObject.new
31
32
  yield
32
33
  ensure
33
- configuration.output = output
34
+ @outputs.pop
34
35
  end
35
36
 
36
37
  def measure(metric, value, unit: nil)
@@ -50,10 +51,14 @@ module L2meter
50
51
  end
51
52
 
52
53
  def context(hash_or_proc)
53
- configuration_contexts.push hash_or_proc
54
+ @contexts.push hash_or_proc
54
55
  yield
55
56
  ensure
56
- configuration_contexts.pop
57
+ @contexts.pop
58
+ end
59
+
60
+ def clone
61
+ self.class.new(configuration: configuration)
57
62
  end
58
63
 
59
64
  private
@@ -81,12 +86,8 @@ module L2meter
81
86
  params.merge(elapsed: "%.4fs" % elapsed)
82
87
  end
83
88
 
84
- def configuration_contexts
85
- configuration.contexts
86
- end
87
-
88
89
  def current_context
89
- configuration_contexts.inject({}) do |result, c|
90
+ contexts_queue.inject({}) do |result, c|
90
91
  current = c.respond_to?(:call) ? c.call.to_h : c.clone
91
92
  result.merge(current)
92
93
  end.to_a.reverse.to_h
@@ -113,7 +114,7 @@ module L2meter
113
114
 
114
115
  tokens.sort! if configuration.sort?
115
116
 
116
- configuration.output.print tokens.join(" ") + "\n"
117
+ output_queue.last.print tokens.join(" ") + "\n"
117
118
  end
118
119
 
119
120
  def log_with_prefix(method, key, value, unit: nil)
@@ -150,5 +151,13 @@ module L2meter
150
151
  ensure
151
152
  return [ result, caught_exception, Time.now - time_at_start ]
152
153
  end
154
+
155
+ def contexts_queue
156
+ [ configuration.context, *@contexts ].compact
157
+ end
158
+
159
+ def output_queue
160
+ [ configuration.output, *@outputs ].compact
161
+ end
153
162
  end
154
163
  end
@@ -0,0 +1,41 @@
1
+ module L2meter
2
+ # This class is a wrapper around Emitter that makes sure that we have a
3
+ # completely separate clone of Emitter per thread running. It doesn't truly
4
+ # make Emitter thread-safe, it makes sure that you don't access the same
5
+ # instance of emitter from different threads.
6
+ class ThreadSafe
7
+ extend Forwardable
8
+
9
+ EMITTER_METHODS = %i[
10
+ configuration
11
+ context
12
+ count
13
+ log
14
+ measure
15
+ sample
16
+ silence
17
+ unique
18
+ with_elapsed
19
+ ]
20
+
21
+ private_constant :EMITTER_METHODS
22
+
23
+ def initialize(emitter)
24
+ @emitter = emitter.freeze
25
+ end
26
+
27
+ def_delegators :current_emitter, *EMITTER_METHODS
28
+
29
+ private
30
+
31
+ attr_reader :emitter
32
+
33
+ def current_emitter
34
+ Thread.current[thread_key] ||= emitter.clone
35
+ end
36
+
37
+ def thread_key
38
+ @thread_key ||= "_l2meter_emitter_#{emitter.object_id}".freeze
39
+ end
40
+ end
41
+ end
@@ -1,3 +1,3 @@
1
1
  module L2meter
2
- VERSION = "0.0.9".freeze
2
+ VERSION = "0.1.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.0.9
4
+ version: 0.1.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: 2015-09-23 00:00:00.000000000 Z
11
+ date: 2015-10-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -23,6 +23,7 @@ files:
23
23
  - lib/l2meter/configuration.rb
24
24
  - lib/l2meter/emitter.rb
25
25
  - lib/l2meter/null_object.rb
26
+ - lib/l2meter/thread_safe.rb
26
27
  - lib/l2meter/version.rb
27
28
  homepage: https://github.com/heroku/l2meter
28
29
  licenses:
@@ -44,7 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
44
45
  version: '0'
45
46
  requirements: []
46
47
  rubyforge_project:
47
- rubygems_version: 2.4.8
48
+ rubygems_version: 2.4.5.1
48
49
  signing_key:
49
50
  specification_version: 4
50
51
  summary: L2met friendly log formatter