l2meter 0.13.0 → 0.14.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 +4 -4
- data/.gitignore +19 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +24 -0
- data/Gemfile +3 -0
- data/README.md +5 -5
- data/Rakefile +6 -0
- data/l2meter.gemspec +35 -0
- data/lib/l2meter.rb +3 -3
- data/lib/l2meter/configuration.rb +4 -5
- data/lib/l2meter/emitter.rb +40 -41
- data/lib/l2meter/null_output.rb +2 -1
- data/lib/l2meter/version.rb +1 -1
- metadata +17 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dda89323ab92c0d321524755d2d657e4c9d3cec349e9e6f0efd4ed2877fb0633
|
4
|
+
data.tar.gz: 0d94a52a832e1bea9aad522a67be4df1dddb76aea50ea6b6c52013aa7f056c99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be3e77657abea69b5e11f322b587de92d5b5ce07d047125ab7d24155c8113e745aae79e8078e1218905fbebacb241f67ae32c7eb67a1133c38c45b881bd1e348
|
7
|
+
data.tar.gz: 0755fa82b1f7caaa2b33a485b59973f9d35ac9164a7a2603e353c8661e7cdcf975779ce614f6a74d61bdbbe730d2e5e2650eccbf03872c50d354d08ece21c4f7
|
data/.gitignore
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Ignore all logfiles and tempfiles
|
2
|
+
/log/
|
3
|
+
/tmp/
|
4
|
+
/tags
|
5
|
+
|
6
|
+
# Package and dependency caches
|
7
|
+
/.bundle
|
8
|
+
/Gemfile.lock
|
9
|
+
/pkg/
|
10
|
+
|
11
|
+
# Generated documentation
|
12
|
+
/doc/
|
13
|
+
/.yardoc
|
14
|
+
/_yardoc/
|
15
|
+
|
16
|
+
# Spec reports and failure tracking
|
17
|
+
/coverage/
|
18
|
+
/spec/rspec-status.txt
|
19
|
+
/spec/reports/
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
5
|
+
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## [Unreleased]
|
8
|
+
|
9
|
+
## [0.14.0] 2020-04-16
|
10
|
+
|
11
|
+
### Added
|
12
|
+
- CHANGELOG.md
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
- Officially only support Ruby 2.5+; all older Rubies are EoL'd.
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
- Fix Ruby 2.7 proc warning
|
19
|
+
- Fix Ruby 2.7 last argument as keyword params warning
|
20
|
+
|
21
|
+
## [0.13.0] 2019-05-11
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
- Total re-write to fix memory leaks in `L2meter::ThreadSafe` proxy object. See: https://github.com/heroku/l2meter/issues/6
|
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -36,8 +36,8 @@ logger.log :doing_work do # => doing-work at=start
|
|
36
36
|
end # => doing-work at=finish elapsed=1.2345
|
37
37
|
```
|
38
38
|
|
39
|
-
In case of
|
40
|
-
and then exception is re-raised.
|
39
|
+
In case of an exception inside the block, all relevant information is logged
|
40
|
+
and then the exception is re-raised.
|
41
41
|
|
42
42
|
```ruby
|
43
43
|
logger.log :doing_work do # => doing-work at=start
|
@@ -86,7 +86,7 @@ def do_work_with_retries
|
|
86
86
|
end
|
87
87
|
```
|
88
88
|
|
89
|
-
It's
|
89
|
+
It's possible to create a dedicated copy of the logger with some specific
|
90
90
|
context attached to it.
|
91
91
|
|
92
92
|
```ruby
|
@@ -154,7 +154,7 @@ Here's the full list of available settings.
|
|
154
154
|
|
155
155
|
### Global context
|
156
156
|
|
157
|
-
Global context works
|
157
|
+
Global context works similarly to context method, but globally:
|
158
158
|
|
159
159
|
```ruby
|
160
160
|
config.context = { app_name: "my-app-name" }
|
@@ -237,7 +237,7 @@ Note that returning nil value will make l2meter omit the field completely.
|
|
237
237
|
|
238
238
|
## Silence
|
239
239
|
|
240
|
-
There's a way to temporary silence the log emitter. This might be
|
240
|
+
There's a way to temporary silence the log emitter. This might be useful for
|
241
241
|
tests for example.
|
242
242
|
|
243
243
|
```ruby
|
data/Rakefile
ADDED
data/l2meter.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path("../lib/l2meter/version", __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "l2meter"
|
5
|
+
spec.version = L2meter::VERSION
|
6
|
+
spec.authors = ["Pavel Pravosud"]
|
7
|
+
spec.email = ["pavel@pravosud.com"]
|
8
|
+
|
9
|
+
spec.summary = "L2met friendly log formatter"
|
10
|
+
spec.description = "L2meter is a tool for building logfmt-compatiable loggers."
|
11
|
+
spec.homepage = "https://github.com/heroku/l2meter"
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
14
|
+
spec.metadata = {
|
15
|
+
"homepage_uri" => spec.homepage,
|
16
|
+
"source_code_uri" => spec.homepage,
|
17
|
+
"bug_tracker_uri" => "#{spec.homepage}/issues",
|
18
|
+
"changelog_uri" => "#{spec.homepage}/blob/master/CHANGELOG.md"
|
19
|
+
}
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
end
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = []
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
spec.add_development_dependency "bundler"
|
31
|
+
spec.add_development_dependency "pry-byebug"
|
32
|
+
spec.add_development_dependency "rake"
|
33
|
+
spec.add_development_dependency "rspec", "~> 3.8.0"
|
34
|
+
spec.add_development_dependency "timecop"
|
35
|
+
end
|
data/lib/l2meter.rb
CHANGED
@@ -4,11 +4,11 @@ module L2meter
|
|
4
4
|
extend self
|
5
5
|
|
6
6
|
autoload :Configuration, "l2meter/configuration"
|
7
|
-
autoload :Emitter,
|
8
|
-
autoload :NullOutput,
|
7
|
+
autoload :Emitter, "l2meter/emitter"
|
8
|
+
autoload :NullOutput, "l2meter/null_output"
|
9
9
|
|
10
10
|
def build(configuration: Configuration.new)
|
11
|
-
yield
|
11
|
+
yield(configuration) if block_given?
|
12
12
|
Emitter.new(configuration: configuration.freeze)
|
13
13
|
end
|
14
14
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module L2meter
|
2
2
|
class Configuration
|
3
|
-
attr_writer :output
|
3
|
+
attr_writer :context, :output
|
4
4
|
attr_accessor :source, :prefix, :float_precision, :scrubber
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :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
11
|
private_constant :DEFAULT_KEY_FORMATTER
|
@@ -15,6 +15,7 @@ module L2meter
|
|
15
15
|
@key_formatter = DEFAULT_KEY_FORMATTER
|
16
16
|
@output = $stdout
|
17
17
|
@float_precision = 4
|
18
|
+
@context = nil
|
18
19
|
end
|
19
20
|
|
20
21
|
def format_keys(&block)
|
@@ -36,7 +37,5 @@ module L2meter
|
|
36
37
|
@context
|
37
38
|
end
|
38
39
|
end
|
39
|
-
|
40
|
-
attr_writer :context
|
41
40
|
end
|
42
41
|
end
|
data/lib/l2meter/emitter.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require "time"
|
2
|
-
require "thread"
|
3
2
|
|
4
3
|
module L2meter
|
5
4
|
class Emitter
|
@@ -9,19 +8,19 @@ module L2meter
|
|
9
8
|
@configuration = configuration
|
10
9
|
end
|
11
10
|
|
12
|
-
def log(*args)
|
13
|
-
merge!
|
11
|
+
def log(*args, &block)
|
12
|
+
merge!(current_context, *args)
|
14
13
|
|
15
|
-
if
|
16
|
-
wrap
|
14
|
+
if block
|
15
|
+
wrap(&block)
|
17
16
|
else
|
18
17
|
write
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
22
|
-
def context(*context_data)
|
23
|
-
if
|
24
|
-
wrap_context(context_data, &
|
21
|
+
def context(*context_data, &block)
|
22
|
+
if block
|
23
|
+
wrap_context(context_data, &block)
|
25
24
|
else
|
26
25
|
contexted(context_data)
|
27
26
|
end
|
@@ -33,24 +32,24 @@ module L2meter
|
|
33
32
|
end
|
34
33
|
end
|
35
34
|
|
36
|
-
def silence
|
37
|
-
with_output(NullOutput.new, &
|
35
|
+
def silence(&block)
|
36
|
+
with_output(NullOutput.new, &block)
|
38
37
|
end
|
39
38
|
|
40
39
|
def silence!
|
41
|
-
set_output
|
40
|
+
set_output(NullOutput.new)
|
42
41
|
end
|
43
42
|
|
44
43
|
def unsilence!
|
45
|
-
set_output
|
44
|
+
set_output(nil)
|
46
45
|
end
|
47
46
|
|
48
47
|
def with_output(new_output)
|
49
48
|
old_output = output
|
50
|
-
set_output
|
49
|
+
set_output(new_output)
|
51
50
|
yield
|
52
51
|
ensure
|
53
|
-
set_output
|
52
|
+
set_output(old_output)
|
54
53
|
end
|
55
54
|
|
56
55
|
def batch
|
@@ -58,24 +57,24 @@ module L2meter
|
|
58
57
|
in_batch!
|
59
58
|
yield
|
60
59
|
ensure
|
61
|
-
reset_in_batch
|
60
|
+
reset_in_batch(old_state)
|
62
61
|
write
|
63
62
|
end
|
64
63
|
|
65
|
-
def measure(
|
66
|
-
log_with_prefix
|
64
|
+
def measure(metric, value, **args)
|
65
|
+
log_with_prefix(:measure, metric, value, **args)
|
67
66
|
end
|
68
67
|
|
69
|
-
def sample(
|
70
|
-
log_with_prefix
|
68
|
+
def sample(metric, value, **args)
|
69
|
+
log_with_prefix(:sample, metric, value, **args)
|
71
70
|
end
|
72
71
|
|
73
72
|
def count(metric, value = 1)
|
74
|
-
log_with_prefix
|
73
|
+
log_with_prefix(:count, metric, value)
|
75
74
|
end
|
76
75
|
|
77
76
|
def unique(metric, value)
|
78
|
-
log_with_prefix
|
77
|
+
log_with_prefix(:unique, metric, value)
|
79
78
|
end
|
80
79
|
|
81
80
|
def clone
|
@@ -83,7 +82,7 @@ module L2meter
|
|
83
82
|
original_output = output
|
84
83
|
self.class.new(configuration: configuration).tap do |clone|
|
85
84
|
clone.instance_eval do
|
86
|
-
dynamic_contexts.concat
|
85
|
+
dynamic_contexts.concat(original_contexts)
|
87
86
|
set_output original_output
|
88
87
|
end
|
89
88
|
end
|
@@ -92,8 +91,8 @@ module L2meter
|
|
92
91
|
private
|
93
92
|
|
94
93
|
def log_with_prefix(method, key, value, unit: nil)
|
95
|
-
key = [configuration.prefix, key, unit].compact.join(
|
96
|
-
log
|
94
|
+
key = [configuration.prefix, key, unit].compact.join(".")
|
95
|
+
log(Hash["#{method}##{key}", value])
|
97
96
|
end
|
98
97
|
|
99
98
|
def elapse(since = Time.now)
|
@@ -101,21 +100,21 @@ module L2meter
|
|
101
100
|
end
|
102
101
|
|
103
102
|
def write(*args)
|
104
|
-
merge!
|
103
|
+
merge!(*args)
|
105
104
|
fire! unless in_batch?
|
106
105
|
end
|
107
106
|
|
108
|
-
def wrap
|
107
|
+
def wrap(&block)
|
109
108
|
elapsed = elapse
|
110
109
|
cloned_buffer = buffer.clone
|
111
|
-
write
|
112
|
-
result, exception = capture(&
|
113
|
-
merge!
|
110
|
+
write(at: :start)
|
111
|
+
result, exception = capture(&block)
|
112
|
+
merge!(cloned_buffer)
|
114
113
|
if exception
|
115
|
-
write
|
116
|
-
raise
|
114
|
+
write(unwrap_exception(exception), elapsed: elapsed)
|
115
|
+
raise(exception)
|
117
116
|
else
|
118
|
-
write
|
117
|
+
write(at: :finish, elapsed: elapsed)
|
119
118
|
result
|
120
119
|
end
|
121
120
|
end
|
@@ -127,7 +126,7 @@ module L2meter
|
|
127
126
|
end
|
128
127
|
|
129
128
|
def wrap_context(context_data)
|
130
|
-
dynamic_contexts.concat
|
129
|
+
dynamic_contexts.concat(context_data)
|
131
130
|
yield
|
132
131
|
ensure
|
133
132
|
context_data.each { dynamic_contexts.pop }
|
@@ -135,7 +134,7 @@ module L2meter
|
|
135
134
|
|
136
135
|
def contexted(context_data)
|
137
136
|
clone.instance_eval do
|
138
|
-
dynamic_contexts.concat
|
137
|
+
dynamic_contexts.concat(context_data)
|
139
138
|
self
|
140
139
|
end
|
141
140
|
end
|
@@ -161,7 +160,7 @@ module L2meter
|
|
161
160
|
end
|
162
161
|
|
163
162
|
def source_context
|
164
|
-
{
|
163
|
+
{source: configuration.source}
|
165
164
|
end
|
166
165
|
|
167
166
|
def resolved_contexts
|
@@ -172,13 +171,13 @@ module L2meter
|
|
172
171
|
tokens = buffer.map { |k, v| build_token(k, v) }.compact
|
173
172
|
tokens.sort! if configuration.sort?
|
174
173
|
return if tokens.empty?
|
175
|
-
output.print
|
174
|
+
output.print(tokens.join(SPACE) << NL)
|
176
175
|
ensure
|
177
176
|
buffer.clear
|
178
177
|
end
|
179
178
|
|
180
179
|
SPACE = " ".freeze
|
181
|
-
NL
|
180
|
+
NL = "\n".freeze
|
182
181
|
|
183
182
|
private_constant :SPACE, :NL
|
184
183
|
|
@@ -218,7 +217,7 @@ module L2meter
|
|
218
217
|
when Time
|
219
218
|
format_time_value(value)
|
220
219
|
when Array
|
221
|
-
value.map(&method(:format_value)).join(
|
220
|
+
value.map(&method(:format_value)).join(",")
|
222
221
|
else
|
223
222
|
format_value(value.to_s)
|
224
223
|
end
|
@@ -234,7 +233,7 @@ module L2meter
|
|
234
233
|
end
|
235
234
|
|
236
235
|
def format_string_value(value)
|
237
|
-
|
236
|
+
/[^\w,.:@\-\]\[]/.match?(value) ?
|
238
237
|
value.strip.gsub(/\s+/, " ").inspect :
|
239
238
|
value.to_s
|
240
239
|
end
|
@@ -251,7 +250,7 @@ module L2meter
|
|
251
250
|
end
|
252
251
|
|
253
252
|
def unwrap(args)
|
254
|
-
|
253
|
+
{}.tap do |result|
|
255
254
|
args.each do |arg|
|
256
255
|
next if arg.nil?
|
257
256
|
arg = Hash[arg, true] unless Hash === arg
|
@@ -295,7 +294,7 @@ module L2meter
|
|
295
294
|
end
|
296
295
|
|
297
296
|
def in_batch!
|
298
|
-
reset_in_batch
|
297
|
+
reset_in_batch(true)
|
299
298
|
end
|
300
299
|
|
301
300
|
def reset_in_batch(new_value)
|
data/lib/l2meter/null_output.rb
CHANGED
data/lib/l2meter/version.rb
CHANGED
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.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pavel Pravosud
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,15 +80,22 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
-
description:
|
83
|
+
description: L2meter is a tool for building logfmt-compatiable loggers.
|
84
84
|
email:
|
85
85
|
- pavel@pravosud.com
|
86
86
|
executables: []
|
87
87
|
extensions: []
|
88
88
|
extra_rdoc_files: []
|
89
89
|
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- ".travis.yml"
|
93
|
+
- CHANGELOG.md
|
94
|
+
- Gemfile
|
90
95
|
- LICENSE.txt
|
91
96
|
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- l2meter.gemspec
|
92
99
|
- lib/l2meter.rb
|
93
100
|
- lib/l2meter/configuration.rb
|
94
101
|
- lib/l2meter/emitter.rb
|
@@ -97,7 +104,11 @@ files:
|
|
97
104
|
homepage: https://github.com/heroku/l2meter
|
98
105
|
licenses:
|
99
106
|
- MIT
|
100
|
-
metadata:
|
107
|
+
metadata:
|
108
|
+
homepage_uri: https://github.com/heroku/l2meter
|
109
|
+
source_code_uri: https://github.com/heroku/l2meter
|
110
|
+
bug_tracker_uri: https://github.com/heroku/l2meter/issues
|
111
|
+
changelog_uri: https://github.com/heroku/l2meter/blob/master/CHANGELOG.md
|
101
112
|
post_install_message:
|
102
113
|
rdoc_options: []
|
103
114
|
require_paths:
|
@@ -113,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
124
|
- !ruby/object:Gem::Version
|
114
125
|
version: '0'
|
115
126
|
requirements: []
|
116
|
-
rubygems_version: 3.
|
127
|
+
rubygems_version: 3.1.2
|
117
128
|
signing_key:
|
118
129
|
specification_version: 4
|
119
130
|
summary: L2met friendly log formatter
|