l2meter 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|