cogger 2.3.0 → 2.5.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
- checksums.yaml.gz.sig +0 -0
- data/README.adoc +92 -21
- data/cogger.gemspec +1 -1
- data/lib/cogger/entry.rb +1 -1
- data/lib/cogger/formatters/color.rb +1 -1
- data/lib/cogger/formatters/crash.rb +1 -1
- data/lib/cogger/formatters/json.rb +3 -2
- data/lib/cogger/formatters/property.rb +3 -2
- data/lib/cogger/formatters/sanitizers/escape.rb +1 -1
- data/lib/cogger/formatters/simple.rb +1 -1
- data/lib/cogger/hub.rb +30 -21
- data/lib/cogger/registry.rb +3 -3
- data/lib/cogger/tag.rb +7 -3
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 394c25bd5359cd226784df811d32eca048dbef8aac78e886009259c3ceb5ab7c
|
|
4
|
+
data.tar.gz: 6f803583d161c300ac94ab8ca9b2d8187d17b2e389c23a9883cf3fe827cd5bbc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cab259078b7c9e07de8091cbe94a1f890a704dda85dedda0201293b9e2c3d50c357ceafb6d1d6723aae56e1923088fc1be7ae81ae5304f13d6723c6ffb5a8420
|
|
7
|
+
data.tar.gz: 1ecb68b40b4daa2e56ed50b43f1952cdcb5b4d99ffc7b3990809be0e86321baffb7cc30119afef60bcc373c9df086fc71e035a9bbeba598d0feb864d98c620ce
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/README.adoc
CHANGED
|
@@ -142,6 +142,34 @@ logger = Cogger.new id: :demo,
|
|
|
142
142
|
suffix: "%Y"
|
|
143
143
|
----
|
|
144
144
|
|
|
145
|
+
=== Identity
|
|
146
|
+
|
|
147
|
+
Your logger's identity defaults to `$PROGRAM_NAME` -- as mentioned earlier -- but can be customized during initialization. Example:
|
|
148
|
+
|
|
149
|
+
[source,ruby]
|
|
150
|
+
----
|
|
151
|
+
logger = Cogger.new id: :demo
|
|
152
|
+
logger.info "A demonstration."
|
|
153
|
+
|
|
154
|
+
# 🟢 [demo] A demonstration.
|
|
155
|
+
----
|
|
156
|
+
|
|
157
|
+
You can also customize the identity by passing in an ID per log entry. Example:
|
|
158
|
+
|
|
159
|
+
[source,ruby]
|
|
160
|
+
----
|
|
161
|
+
logger = Cogger.new
|
|
162
|
+
|
|
163
|
+
logger.info "A demonstration.", id: :other
|
|
164
|
+
# 🟢 [other] A demonstration.
|
|
165
|
+
|
|
166
|
+
logger.info(id: :other) { "A demonstration." }
|
|
167
|
+
# 🟢 [other] A demonstration.
|
|
168
|
+
|
|
169
|
+
logger.info { {id: :other, message: "A demonstration."} }
|
|
170
|
+
# 🟢 [other] A demonstration.
|
|
171
|
+
----
|
|
172
|
+
|
|
145
173
|
=== Levels
|
|
146
174
|
|
|
147
175
|
Supported levels can be obtained via `Cogger::LEVELS`. Example:
|
|
@@ -165,7 +193,26 @@ The above adheres to {rfc_3339_link} and can be customized -- as mentioned earli
|
|
|
165
193
|
|
|
166
194
|
[source,ruby]
|
|
167
195
|
----
|
|
168
|
-
Cogger.new datetime_format: "%Y-%m-%d"
|
|
196
|
+
logger = Cogger.new formatter: :json, datetime_format: "%Y-%m-%d"
|
|
197
|
+
logger.info "A demonstration."
|
|
198
|
+
|
|
199
|
+
# {"id":"console","level":"INFO","at":"2026-06-28","message":"A demonstration."}
|
|
200
|
+
----
|
|
201
|
+
|
|
202
|
+
You can also customize the date/time format by passing in an date/time format per log entry. Example:
|
|
203
|
+
|
|
204
|
+
[source,ruby]
|
|
205
|
+
----
|
|
206
|
+
logger = Cogger.new formatter: :json
|
|
207
|
+
|
|
208
|
+
logger.info "A demonstration.", datetime_format: "%Y-%m-%d"
|
|
209
|
+
# {"id":"console","level":"INFO","at":"2026-06-28","message":"A demonstration."}
|
|
210
|
+
|
|
211
|
+
logger.info(datetime_format: "%Y-%m-%d") { "A demonstration." }
|
|
212
|
+
# {"id":"console","level":"INFO","at":"2026-06-28","message":"A demonstration."}
|
|
213
|
+
|
|
214
|
+
logger.info { {datetime_format: "%Y-%m-%d", message: "A demonstration."} }
|
|
215
|
+
# {"id":"console","level":"INFO","at":"2026-06-28","message":"A demonstration."}
|
|
169
216
|
----
|
|
170
217
|
|
|
171
218
|
=== Environment
|
|
@@ -192,18 +239,25 @@ Each instance can be mutated using the following messages:
|
|
|
192
239
|
----
|
|
193
240
|
logger = Cogger.new io: StringIO.new
|
|
194
241
|
|
|
195
|
-
logger.close
|
|
196
|
-
logger.reopen
|
|
197
|
-
logger.debug!
|
|
198
|
-
logger.info!
|
|
199
|
-
logger.warn!
|
|
200
|
-
logger.error!
|
|
201
|
-
logger.fatal!
|
|
202
|
-
logger.formatter =
|
|
203
|
-
logger.level = Logger::WARN
|
|
242
|
+
logger.close # nil
|
|
243
|
+
logger.reopen # Logger
|
|
244
|
+
logger.debug! # 0
|
|
245
|
+
logger.info! # 1
|
|
246
|
+
logger.warn! # 2
|
|
247
|
+
logger.error! # 3
|
|
248
|
+
logger.fatal! # 4
|
|
249
|
+
logger.formatter = :simple # :simple
|
|
250
|
+
logger.level = Logger::WARN # 2
|
|
204
251
|
----
|
|
205
252
|
|
|
206
|
-
|
|
253
|
+
When setting the formatter, you can use a string, symbol, or instance. For example, the following are identical:
|
|
254
|
+
|
|
255
|
+
[source,ruby]
|
|
256
|
+
----
|
|
257
|
+
logger.formatter = "simple"
|
|
258
|
+
logger.formatter = :simple
|
|
259
|
+
logger.formatter = Cogger::Formatters::Simple.new
|
|
260
|
+
----
|
|
207
261
|
|
|
208
262
|
=== Emojis
|
|
209
263
|
|
|
@@ -876,7 +930,7 @@ Tags allow you to tag your messages at both a global and local (i.e. per message
|
|
|
876
930
|
logger = Cogger.new tags: %w[WEB]
|
|
877
931
|
logger.info "Demo"
|
|
878
932
|
|
|
879
|
-
# 🟢 [console] [WEB] Demo
|
|
933
|
+
# 🟢 [console] ["WEB"] Demo
|
|
880
934
|
----
|
|
881
935
|
|
|
882
936
|
You can use multiple tags as well:
|
|
@@ -886,7 +940,7 @@ You can use multiple tags as well:
|
|
|
886
940
|
logger = Cogger.new tags: %w[WEB EXAMPLE]
|
|
887
941
|
logger.info "Demo"
|
|
888
942
|
|
|
889
|
-
# 🟢 [console] [WEB] [EXAMPLE] Demo
|
|
943
|
+
# 🟢 [console] ["WEB"] ["EXAMPLE"] Demo
|
|
890
944
|
----
|
|
891
945
|
|
|
892
946
|
You are not limited to string-based tags. Any object will work:
|
|
@@ -896,7 +950,7 @@ You are not limited to string-based tags. Any object will work:
|
|
|
896
950
|
logger = Cogger.new tags: ["ONE", :two, 3, {four: "FOUR"}, proc { "FIVE" }]
|
|
897
951
|
logger.info "Demo"
|
|
898
952
|
|
|
899
|
-
# 🟢 [console] [ONE] [two] [3] [FIVE] [four=FOUR] Demo
|
|
953
|
+
# 🟢 [console] ["ONE"] [:two] [3] ["FIVE"] [four="FOUR"] Demo
|
|
900
954
|
----
|
|
901
955
|
|
|
902
956
|
With the above, we have string, symbol, integer, hash, and proc tags. With hashes, you'll always get a the key/value pair formatted as: `key=value`. Procs/lambdas allow you to lazy evaluate your tag at time of logging which provides a powerful way to acquire the current process ID, thread ID, and so forth.
|
|
@@ -908,7 +962,7 @@ In addition to global tags, you can use local tags per log message. Example:
|
|
|
908
962
|
logger = Cogger.new
|
|
909
963
|
logger.info "Demo", tags: ["ONE", :two, 3, {four: "FOUR"}, proc { "FIVE" }]
|
|
910
964
|
|
|
911
|
-
# 🟢 [console] [ONE] [two] [3] [FIVE] [four=FOUR] Demo
|
|
965
|
+
# 🟢 [console] ["ONE"] [:two] [3] ["FIVE"] [four="FOUR"] Demo
|
|
912
966
|
----
|
|
913
967
|
|
|
914
968
|
You can also combine global and local tags:
|
|
@@ -918,16 +972,33 @@ You can also combine global and local tags:
|
|
|
918
972
|
logger = Cogger.new tags: ["ONE", :two]
|
|
919
973
|
logger.info "Demo", tags: [3, proc { "FOUR" }]
|
|
920
974
|
|
|
921
|
-
# 🟢 [console] [ONE] [two] [3] [FOUR] Demo
|
|
975
|
+
# 🟢 [console] ["ONE"] [:two] [3] ["FOUR"] Demo
|
|
922
976
|
----
|
|
923
977
|
|
|
978
|
+
When using blocks, use a hash inside the block instead of supplying the tags before using the block. Example:
|
|
979
|
+
|
|
980
|
+
[source,ruby]
|
|
981
|
+
----
|
|
982
|
+
logger = Cogger.new level: :debug
|
|
983
|
+
|
|
984
|
+
# No
|
|
985
|
+
logger.debug(tags: ["ONE", :TWO]) { "Demo" }
|
|
986
|
+
🔎 [console] ["ONE"] [:TWO] Demo
|
|
987
|
+
|
|
988
|
+
# Yes
|
|
989
|
+
logger.debug { {tags: ["ONE", :TWO], message: "Demo"} }
|
|
990
|
+
🔎 [console] ["ONE"] [:TWO] Demo
|
|
991
|
+
----
|
|
992
|
+
|
|
993
|
+
This ensures your tags and associated message are only evaluated when the correct log level is accepted. This is especially important when dealing with tags that need additional evaluation like procs because you'll improve performance when the debug log level, in this example, isn't set.
|
|
994
|
+
|
|
924
995
|
As you can see, tags are highly versatile. That said, the following guidelines are worth consideration when using them:
|
|
925
996
|
|
|
926
|
-
* Prefer uppercase
|
|
927
|
-
* Prefer short
|
|
928
|
-
* Prefer consistent
|
|
929
|
-
* Prefer
|
|
930
|
-
* Prefer the JSON formatter for structured metadata instead of tags. Logging JSON formatted messages with tags will work but sticking with a traditional hash, instead of tags, will
|
|
997
|
+
* Prefer uppercase tags to make them visually stand out.
|
|
998
|
+
* Prefer short tags, ideally 1-4 characters since long tags defeat the purpose of brevity.
|
|
999
|
+
* Prefer consistent tags by using tags that are not synonymous or ambiguous.
|
|
1000
|
+
* Prefer feature tags instead of environment tags. Examples: API, DB, MAILER.
|
|
1001
|
+
* Prefer the JSON formatter for structured metadata instead of tags. Logging JSON formatted messages with tags will work but sticking with a traditional hash, instead of tags, will serve you better.
|
|
931
1002
|
* Avoid using `id`, `level`, `at`, and/or `message` as hash keys since those are reserved keys and will be rejected if supplied.
|
|
932
1003
|
|
|
933
1004
|
=== Filters
|
data/cogger.gemspec
CHANGED
data/lib/cogger/entry.rb
CHANGED
|
@@ -15,9 +15,10 @@ module Cogger
|
|
|
15
15
|
@parser = parser
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def call
|
|
18
|
+
def call *input
|
|
19
19
|
*, entry = input
|
|
20
|
-
attributes = sanitize
|
|
20
|
+
attributes = sanitize entry, :tagged_attributes
|
|
21
|
+
attributes.delete :message unless attributes[:message]
|
|
21
22
|
|
|
22
23
|
parser.call(template, attributes).to_json << NEW_LINE
|
|
23
24
|
end
|
|
@@ -14,9 +14,10 @@ module Cogger
|
|
|
14
14
|
@parser = parser
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def call
|
|
17
|
+
def call *input
|
|
18
18
|
*, entry = input
|
|
19
|
-
attributes = sanitize
|
|
19
|
+
attributes = sanitize entry, :tagged_attributes
|
|
20
|
+
attributes.delete :message unless attributes[:message]
|
|
20
21
|
|
|
21
22
|
concat(attributes).chop! << NEW_LINE
|
|
22
23
|
end
|
data/lib/cogger/hub.rb
CHANGED
|
@@ -6,7 +6,6 @@ require "refinements/hash"
|
|
|
6
6
|
|
|
7
7
|
module Cogger
|
|
8
8
|
# Loads configuration and simultaneously sends messages to multiple streams.
|
|
9
|
-
# :reek:TooManyMethods
|
|
10
9
|
class Hub
|
|
11
10
|
extend Forwardable
|
|
12
11
|
|
|
@@ -27,23 +26,22 @@ module Cogger
|
|
|
27
26
|
fatal!
|
|
28
27
|
fatal?
|
|
29
28
|
formatter
|
|
30
|
-
formatter=
|
|
31
29
|
level
|
|
32
30
|
level=
|
|
33
31
|
] => :primary
|
|
34
32
|
|
|
35
33
|
delegate %i[id io tags mode age size suffix] => :configuration
|
|
36
34
|
|
|
37
|
-
def initialize
|
|
35
|
+
def initialize registry: Cogger, model: Configuration, **attributes
|
|
38
36
|
@registry = registry
|
|
39
|
-
@configuration = model[**
|
|
37
|
+
@configuration = model[**resolve_formatter(attributes)]
|
|
40
38
|
@primary = configuration.to_logger
|
|
41
39
|
@streams = [@primary]
|
|
42
40
|
end
|
|
43
41
|
|
|
44
42
|
def add_stream **attributes
|
|
45
43
|
attributes[:id] = configuration.id
|
|
46
|
-
streams.append configuration.with(**
|
|
44
|
+
streams.append configuration.with(**resolve_formatter(attributes)).to_logger
|
|
47
45
|
self
|
|
48
46
|
end
|
|
49
47
|
|
|
@@ -59,16 +57,20 @@ module Cogger
|
|
|
59
57
|
|
|
60
58
|
def any(message = nil, **, &) = log(__method__, message, **, &)
|
|
61
59
|
|
|
62
|
-
def abort
|
|
60
|
+
def abort message = nil, **payload, &block
|
|
63
61
|
error(message, **payload, &block) if message || !payload.empty? || block
|
|
64
62
|
exit false
|
|
65
63
|
end
|
|
66
64
|
|
|
67
|
-
def panic
|
|
65
|
+
def panic message = nil, **payload, &block
|
|
68
66
|
fatal(message, **payload, &block) if message || !payload.empty? || block
|
|
69
67
|
exit false
|
|
70
68
|
end
|
|
71
69
|
|
|
70
|
+
def formatter= value
|
|
71
|
+
primary.formatter = find_or_use_formatter value
|
|
72
|
+
end
|
|
73
|
+
|
|
72
74
|
def add(level, message = nil, **, &)
|
|
73
75
|
log(Logger::SEV_LABEL.fetch(level, "ANY").downcase, message, **, &)
|
|
74
76
|
end
|
|
@@ -85,13 +87,19 @@ module Cogger
|
|
|
85
87
|
|
|
86
88
|
attr_reader :registry, :configuration, :primary, :streams
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
next value unless value.is_a?(Symbol) || value.is_a?(String)
|
|
90
|
+
def resolve_formatter attributes
|
|
91
|
+
attributes.transform_value!(:formatter) { |value| find_or_use_formatter value }
|
|
92
|
+
end
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
def find_or_use_formatter value
|
|
95
|
+
case value
|
|
96
|
+
when String, Symbol
|
|
97
|
+
formatter, template = registry.get_formatter value
|
|
98
|
+
template ? formatter.new(template) : formatter.new
|
|
99
|
+
when Formatters::Abstract then value
|
|
100
|
+
else fail TypeError,
|
|
101
|
+
"Invalid formatter. Must be a string, symbol, or " \
|
|
102
|
+
"subclass of Cogger::Formatters::Abstract."
|
|
95
103
|
end
|
|
96
104
|
end
|
|
97
105
|
|
|
@@ -101,22 +109,23 @@ module Cogger
|
|
|
101
109
|
crash message, error
|
|
102
110
|
end
|
|
103
111
|
|
|
104
|
-
# rubocop:todo Metrics/MethodLength
|
|
105
112
|
def dispatch(level, message, **payload, &)
|
|
106
|
-
entry =
|
|
113
|
+
entry = build_entry(level, message, payload, &)
|
|
114
|
+
configuration.mutex.synchronize { streams.each { |logger| logger.public_send level, entry } }
|
|
115
|
+
true
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def build_entry(level, message, payload, &)
|
|
119
|
+
configuration.entry.for(
|
|
107
120
|
message,
|
|
108
121
|
id: configuration.id,
|
|
109
122
|
level:,
|
|
110
|
-
tags: configuration.entag(payload
|
|
123
|
+
tags: configuration.entag(payload[:tags]),
|
|
111
124
|
datetime_format: configuration.datetime_format,
|
|
112
|
-
**payload,
|
|
125
|
+
**payload.except(:level, :at, :tags),
|
|
113
126
|
&
|
|
114
127
|
)
|
|
115
|
-
|
|
116
|
-
configuration.mutex.synchronize { streams.each { |logger| logger.public_send level, entry } }
|
|
117
|
-
true
|
|
118
128
|
end
|
|
119
|
-
# rubocop:enable Metrics/MethodLength
|
|
120
129
|
|
|
121
130
|
def crash message, error
|
|
122
131
|
configuration.with(id: :cogger, io: $stdout, formatter: Formatters::Crash.new)
|
data/lib/cogger/registry.rb
CHANGED
|
@@ -39,14 +39,14 @@ module Cogger
|
|
|
39
39
|
"%<duration>s %<ip>s %<path>s %<length>s %<params>s"
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
def add_alias
|
|
42
|
+
def add_alias key, *styles
|
|
43
43
|
color.add_alias(key, *styles)
|
|
44
44
|
self
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def aliases = color.aliases
|
|
48
48
|
|
|
49
|
-
def add_emojis
|
|
49
|
+
def add_emojis **attributes
|
|
50
50
|
emojis.merge! attributes.symbolize_keys!
|
|
51
51
|
self
|
|
52
52
|
end
|
|
@@ -57,7 +57,7 @@ module Cogger
|
|
|
57
57
|
|
|
58
58
|
def emojis = @emojis ||= {}
|
|
59
59
|
|
|
60
|
-
def add_filters
|
|
60
|
+
def add_filters *keys
|
|
61
61
|
filters.merge(keys.map(&:to_sym))
|
|
62
62
|
self
|
|
63
63
|
end
|
data/lib/cogger/tag.rb
CHANGED
|
@@ -27,19 +27,23 @@ module Cogger
|
|
|
27
27
|
|
|
28
28
|
def empty? = singles.empty? && pairs.empty?
|
|
29
29
|
|
|
30
|
-
def to_h
|
|
30
|
+
def to_h
|
|
31
|
+
return Core::EMPTY_HASH if empty?
|
|
32
|
+
|
|
33
|
+
singles.empty? ? pairs : {tags: singles.to_a, **pairs}
|
|
34
|
+
end
|
|
31
35
|
|
|
32
36
|
def to_s = empty? ? Core::EMPTY_STRING : "#{format_singles} #{format_pairs}".tap(&:strip!)
|
|
33
37
|
|
|
34
38
|
private
|
|
35
39
|
|
|
36
40
|
def format_singles
|
|
37
|
-
singles.map { |value| "[#{value}]" }
|
|
41
|
+
singles.map { |value| "[#{value.inspect}]" }
|
|
38
42
|
.join " "
|
|
39
43
|
end
|
|
40
44
|
|
|
41
45
|
def format_pairs
|
|
42
|
-
pairs.map { |key, value| "[#{key}=#{value}]" }
|
|
46
|
+
pairs.map { |key, value| "[#{key}=#{value.inspect}]" }
|
|
43
47
|
.join(" ")
|
|
44
48
|
end
|
|
45
49
|
end
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cogger
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brooke Kuhlmann
|
|
@@ -175,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
175
175
|
- !ruby/object:Gem::Version
|
|
176
176
|
version: '0'
|
|
177
177
|
requirements: []
|
|
178
|
-
rubygems_version: 4.0.
|
|
178
|
+
rubygems_version: 4.0.15
|
|
179
179
|
specification_version: 4
|
|
180
180
|
summary: A customizable and feature rich logger.
|
|
181
181
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|