nrser 0.2.2 → 0.3.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/lib/nrser/char/alpha_numeric_sub.rb +1 -2
- data/lib/nrser/char.rb +0 -6
- data/lib/nrser/core_ext/array.rb +120 -0
- data/lib/nrser/core_ext/binding.rb +44 -0
- data/lib/nrser/{functions → core_ext}/enumerable/find_map.rb +18 -15
- data/lib/nrser/{ext → core_ext}/enumerable.rb +10 -24
- data/lib/nrser/core_ext/exception.rb +30 -0
- data/lib/nrser/core_ext/hash/extract_values_at.rb +49 -0
- data/lib/nrser/core_ext/hash/transform_values_with_keys.rb +24 -0
- data/lib/nrser/core_ext/hash.rb +50 -0
- data/lib/nrser/core_ext/module/method_objects.rb +96 -0
- data/lib/nrser/core_ext/module/names.rb +69 -0
- data/lib/nrser/core_ext/module/source_locations.rb +214 -0
- data/lib/nrser/core_ext/module.rb +2 -0
- data/lib/nrser/core_ext/object/lazy_var.rb +31 -0
- data/lib/nrser/core_ext/object.rb +46 -0
- data/lib/nrser/core_ext/open_struct.rb +6 -0
- data/lib/nrser/{ext → core_ext}/pathname.rb +8 -5
- data/lib/nrser/{ext → core_ext}/string.rb +6 -12
- data/lib/nrser/core_ext/symbol.rb +13 -0
- data/lib/nrser/core_ext/time.rb +46 -0
- data/lib/nrser/core_ext.rb +13 -0
- data/lib/nrser/errors/abstract_method_error.rb +150 -0
- data/lib/nrser/errors/argument_error.rb +42 -0
- data/lib/nrser/errors/nicer_error.rb +298 -72
- data/lib/nrser/errors/type_error.rb +46 -0
- data/lib/nrser/errors.rb +4 -53
- data/lib/nrser/ext/tree.rb +3 -0
- data/lib/nrser/functions/enumerable/associate.rb +6 -9
- data/lib/nrser/functions/enumerable/include_slice.rb +2 -3
- data/lib/nrser/functions/enumerable.rb +1 -3
- data/lib/nrser/functions/exception.rb +1 -1
- data/lib/nrser/functions/hash.rb +0 -6
- data/lib/nrser/functions/merge_by.rb +2 -2
- data/lib/nrser/functions/module/method_objects.rb +77 -0
- data/lib/nrser/functions/module.rb +1 -2
- data/lib/nrser/functions/open_struct.rb +25 -35
- data/lib/nrser/functions/proc.rb +1 -6
- data/lib/nrser/functions/string/looks_like.rb +32 -1
- data/lib/nrser/functions/string.rb +1 -40
- data/lib/nrser/functions/text/lines.rb +2 -1
- data/lib/nrser/functions.rb +0 -1
- data/lib/nrser/graph/tsorter.rb +41 -0
- data/lib/nrser/labs/core_ext/binding.rb +37 -0
- data/lib/nrser/labs/stash.rb +372 -0
- data/lib/nrser/{logging → log}/appender/sync.rb +3 -3
- data/lib/nrser/log/appender.rb +3 -0
- data/lib/nrser/{logging → log}/formatters/color.rb +47 -20
- data/lib/nrser/log/formatters/mixin.rb +270 -0
- data/lib/nrser/{logging → log}/formatters.rb +0 -0
- data/lib/nrser/log/logger.rb +229 -0
- data/lib/nrser/log/mixin.rb +56 -0
- data/lib/nrser/log.rb +723 -0
- data/lib/nrser/message.rb +24 -3
- data/lib/nrser/meta/source/location.rb +158 -0
- data/lib/nrser/meta.rb +1 -1
- data/lib/nrser/props/class_methods.rb +118 -0
- data/lib/nrser/props/immutable/hash.rb +111 -0
- data/lib/nrser/props/immutable/hash_variable.rb +82 -0
- data/lib/nrser/props/immutable/instance_variables.rb +48 -0
- data/lib/nrser/props/immutable/vector.rb +107 -0
- data/lib/nrser/props/instance_methods.rb +184 -0
- data/lib/nrser/props/metadata.rb +359 -0
- data/lib/nrser/props/mutable/instance_variables.rb +60 -0
- data/lib/nrser/props/mutable/stash.rb +199 -0
- data/lib/nrser/{meta/props → props}/prop.rb +217 -112
- data/lib/nrser/props/storage/instance_variable.rb +85 -0
- data/lib/nrser/props/storage/instance_variables.rb +67 -0
- data/lib/nrser/props/storage/key.rb +88 -0
- data/lib/nrser/props.rb +9 -0
- data/lib/nrser/refinements/sugar.rb +41 -0
- data/lib/nrser/refinements/types.rb +2 -2
- data/lib/nrser/refinements.rb +14 -16
- data/lib/nrser/rspex/example_group/describe_attribute.rb +24 -0
- data/lib/nrser/rspex/example_group/describe_called_with.rb +1 -6
- data/lib/nrser/rspex/example_group/{describe_use_case.rb → describe_case.rb} +6 -3
- data/lib/nrser/rspex/example_group/describe_class.rb +1 -0
- data/lib/nrser/rspex/example_group/describe_group.rb +29 -0
- data/lib/nrser/rspex/example_group/describe_instance_method.rb +2 -2
- data/lib/nrser/rspex/example_group/describe_message.rb +35 -0
- data/lib/nrser/rspex/example_group/describe_method.rb +23 -2
- data/lib/nrser/rspex/example_group/describe_module.rb +19 -0
- data/lib/nrser/rspex/example_group/describe_response_to.rb +32 -0
- data/lib/nrser/rspex/example_group/describe_section.rb +38 -0
- data/lib/nrser/rspex/example_group/describe_sent_to.rb +52 -0
- data/lib/nrser/rspex/example_group/describe_source_file.rb +49 -0
- data/lib/nrser/rspex/example_group/describe_spec_file.rb +41 -108
- data/lib/nrser/rspex/example_group/describe_when.rb +14 -7
- data/lib/nrser/rspex/example_group/describe_x.rb +39 -12
- data/lib/nrser/rspex/example_group/overrides.rb +66 -0
- data/lib/nrser/rspex/example_group.rb +20 -252
- data/lib/nrser/rspex/format.rb +83 -17
- data/lib/nrser/rspex.rb +4 -34
- data/lib/nrser/sugar/method_missing_forwarder.rb +50 -0
- data/lib/nrser/{env → sys/env}/path.rb +1 -2
- data/lib/nrser/{env.rb → sys/env.rb} +2 -1
- data/lib/nrser/sys.rb +5 -0
- data/lib/nrser/types/any.rb +36 -7
- data/lib/nrser/types/{array.rb → arrays.rb} +32 -81
- data/lib/nrser/types/attrs.rb +68 -15
- data/lib/nrser/types/booleans.rb +95 -34
- data/lib/nrser/types/bounded.rb +12 -10
- data/lib/nrser/types/combinators.rb +74 -37
- data/lib/nrser/types/errors/check_error.rb +86 -0
- data/lib/nrser/types/errors/from_string_error.rb +82 -0
- data/lib/nrser/types/factory.rb +91 -0
- data/lib/nrser/types/hashes.rb +171 -26
- data/lib/nrser/types/in.rb +25 -12
- data/lib/nrser/types/is.rb +50 -18
- data/lib/nrser/types/is_a.rb +52 -33
- data/lib/nrser/types/labels.rb +6 -33
- data/lib/nrser/types/maybe.rb +12 -4
- data/lib/nrser/types/nil.rb +24 -4
- data/lib/nrser/types/not.rb +6 -16
- data/lib/nrser/types/numbers.rb +94 -57
- data/lib/nrser/types/pairs.rb +57 -57
- data/lib/nrser/types/paths.rb +112 -133
- data/lib/nrser/types/responds.rb +64 -74
- data/lib/nrser/types/shape.rb +29 -24
- data/lib/nrser/types/strings.rb +25 -17
- data/lib/nrser/types/symbols.rb +19 -17
- data/lib/nrser/types/trees.rb +18 -70
- data/lib/nrser/types/tuples.rb +36 -40
- data/lib/nrser/types/type.rb +342 -91
- data/lib/nrser/types/when.rb +40 -18
- data/lib/nrser/types/where.rb +94 -9
- data/lib/nrser/types.rb +72 -63
- data/lib/nrser/version.rb +1 -1
- data/lib/nrser.rb +18 -18
- data/spec/lib/nrser/{functions/binding/template_spec.rb → core_ext/binding/erb_spec.rb} +5 -5
- data/spec/lib/nrser/{functions → core_ext}/enumerable/find_map_spec.rb +8 -6
- data/spec/lib/nrser/{refinements → core_ext}/hash_spec.rb +9 -22
- data/spec/lib/nrser/errors/abstract_method_error_spec.rb +12 -5
- data/spec/lib/nrser/functions/enumerable/{to_h_by_spec.rb → associate_spec.rb} +1 -1
- data/spec/lib/nrser/functions/merge_by_spec.rb +1 -1
- data/spec/lib/nrser/functions/tree/each_branch_spec.rb +3 -3
- data/spec/lib/nrser/functions/tree/transform_spec.rb +14 -15
- data/spec/lib/nrser/gem_ext/hamster/json_spec.rb +4 -0
- data/spec/lib/nrser/meta/source/location_spec.rb +86 -0
- data/spec/lib/nrser/props/immutable/hash_spec.rb +297 -0
- data/spec/lib/nrser/props/immutable/vector_spec.rb +296 -0
- data/spec/lib/nrser/{meta/props_spec.rb → props/original_props_spec.rb} +11 -16
- data/spec/lib/nrser/{meta/props → props}/to_and_from_data_spec.rb +10 -8
- data/spec/lib/nrser/refinements/array_spec.rb +2 -15
- data/spec/lib/nrser/refinements/erb_spec.rb +5 -7
- data/spec/lib/nrser/refinements/set_spec.rb +2 -15
- data/spec/lib/nrser/{env → sys/env}/path/insert_spec.rb +4 -2
- data/spec/lib/nrser/{env → sys/env}/path_spec.rb +4 -2
- data/spec/lib/nrser/types/array_spec.rb +8 -8
- data/spec/lib/nrser/types/paths_spec.rb +15 -18
- data/spec/spec_helper.rb +4 -0
- metadata +109 -69
- data/lib/nrser/ext/binding.rb +0 -36
- data/lib/nrser/ext/module.rb +0 -62
- data/lib/nrser/ext.rb +0 -8
- data/lib/nrser/functions/binding.rb +0 -76
- data/lib/nrser/functions/enumerable/map_keys.rb +0 -0
- data/lib/nrser/functions/enumerable/map_values.rb +0 -94
- data/lib/nrser/functions/hash/deep_merge.rb +0 -57
- data/lib/nrser/functions/hash/except_keys.rb +0 -44
- data/lib/nrser/functions/hash/slice_keys.rb +0 -43
- data/lib/nrser/functions/hash/stringify_keys.rb +0 -55
- data/lib/nrser/functions/hash/symbolize_keys.rb +0 -57
- data/lib/nrser/functions/hash/transform_keys.rb +0 -140
- data/lib/nrser/functions/module/methods.rb +0 -206
- data/lib/nrser/functions/module/source_locations.rb +0 -213
- data/lib/nrser/logging/appender.rb +0 -3
- data/lib/nrser/logging.rb +0 -353
- data/lib/nrser/meta/props/base.rb +0 -31
- data/lib/nrser/meta/props.rb +0 -357
- data/lib/nrser/refinements/array.rb +0 -133
- data/lib/nrser/refinements/binding.rb +0 -6
- data/lib/nrser/refinements/enumerator.rb +0 -5
- data/lib/nrser/refinements/exception.rb +0 -35
- data/lib/nrser/refinements/hash.rb +0 -150
- data/lib/nrser/refinements/module.rb +0 -5
- data/lib/nrser/refinements/object.rb +0 -42
- data/lib/nrser/refinements/open_struct.rb +0 -28
- data/lib/nrser/refinements/pathname.rb +0 -5
- data/lib/nrser/refinements/set.rb +0 -5
- data/lib/nrser/refinements/string.rb +0 -5
- data/lib/nrser/refinements/symbol.rb +0 -20
- data/lib/nrser/rspex/described.rb +0 -99
- data/spec/design/mapping_spec.rb +0 -42
- data/spec/lib/nrser/functions/hash_spec.rb +0 -41
- data/spec/lib/nrser/functions/string/truncate_spec.rb +0 -11
- data/spec/lib/nrser/refinements/truncate_spec.rb +0 -10
@@ -0,0 +1,270 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Stdlib
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
# Deps
|
11
|
+
# -----------------------------------------------------------------------
|
12
|
+
|
13
|
+
# Project / Package
|
14
|
+
# -----------------------------------------------------------------------
|
15
|
+
|
16
|
+
|
17
|
+
# Refinements
|
18
|
+
# =======================================================================
|
19
|
+
|
20
|
+
|
21
|
+
# Declarations
|
22
|
+
# =======================================================================
|
23
|
+
|
24
|
+
module NRSER::Log; end
|
25
|
+
module NRSER::Log::Formatters; end
|
26
|
+
|
27
|
+
|
28
|
+
# Definitions
|
29
|
+
# =======================================================================
|
30
|
+
|
31
|
+
# A mix-in to include in {SemanticLogger::Formatter::Default} and subclasses
|
32
|
+
# to improve configurability.
|
33
|
+
#
|
34
|
+
module NRSER::Log::Formatters::Mixin
|
35
|
+
|
36
|
+
# Inner Classes
|
37
|
+
# ==========================================================================
|
38
|
+
#
|
39
|
+
# Small helper classes only created via the mix-in.
|
40
|
+
#
|
41
|
+
|
42
|
+
# Abstract base class for {HeaderTokens} and {BodyTokens}, instances of which are used
|
43
|
+
# by formatters that include {NRSER::Log::Formatters::Mixin} to
|
44
|
+
# configure what pieces of information make up the header and body sections
|
45
|
+
# of log messages that it formats.
|
46
|
+
#
|
47
|
+
# Entries are {SemanticLogger::Formatter::Default} method names, which I've
|
48
|
+
# called "tokens", and the order of the "tokens" dictates the order the
|
49
|
+
# results of those method calls will be joined to form the formatted
|
50
|
+
# message section.
|
51
|
+
#
|
52
|
+
# Adding, removing and reordering tokens is used to control what elements
|
53
|
+
# appear and where in the formatted result.
|
54
|
+
#
|
55
|
+
# Token arrays are mutable and meant to changed in place via {Array#delete}
|
56
|
+
# and friends.
|
57
|
+
#
|
58
|
+
class Tokens < ::Array
|
59
|
+
# Create a new token array.
|
60
|
+
#
|
61
|
+
# @param [Array<#to_sym>] tokens
|
62
|
+
# The token symbols to initialize the array with. Must be covetable
|
63
|
+
# to symbols (really, just pass symbols in the first place).
|
64
|
+
#
|
65
|
+
def initialize tokens = self.class::ALL
|
66
|
+
super tokens.map( &:to_sym )
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
# Reset the array to be all the available tokens for the section in
|
71
|
+
# their original order.
|
72
|
+
#
|
73
|
+
# **Mutates the array in place.**
|
74
|
+
#
|
75
|
+
# @return [Tokens]
|
76
|
+
# `self`.
|
77
|
+
#
|
78
|
+
def reset!
|
79
|
+
clear
|
80
|
+
self.class::ALL.each { |token| self << token }
|
81
|
+
self
|
82
|
+
end
|
83
|
+
end # class Tokens
|
84
|
+
|
85
|
+
|
86
|
+
# {Tokens} subclass for log message headers.
|
87
|
+
#
|
88
|
+
# @see #header
|
89
|
+
# @see #header=
|
90
|
+
#
|
91
|
+
class HeaderTokens < Tokens
|
92
|
+
# All header tokens in a default order.
|
93
|
+
#
|
94
|
+
# @return [Array<Symbol>]
|
95
|
+
#
|
96
|
+
ALL = [
|
97
|
+
:time,
|
98
|
+
:level,
|
99
|
+
:process_info,
|
100
|
+
:tags,
|
101
|
+
:named_tags,
|
102
|
+
:duration,
|
103
|
+
:name,
|
104
|
+
].freeze
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
# {Tokens} subclass for log message bodies.
|
109
|
+
#
|
110
|
+
# @see #body
|
111
|
+
# @see #body=
|
112
|
+
#
|
113
|
+
class BodyTokens < Tokens
|
114
|
+
# All body tokens in a default order.
|
115
|
+
#
|
116
|
+
# @return [Array<Symbol>]
|
117
|
+
#
|
118
|
+
ALL = [
|
119
|
+
:message,
|
120
|
+
:payload,
|
121
|
+
:exception,
|
122
|
+
]
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
# Instance Methods
|
127
|
+
# ========================================================================
|
128
|
+
|
129
|
+
# Get or set the header "tokens" - {SemanticLogger::Formatters::Default}
|
130
|
+
# method names in the order their responses should be joined to form the
|
131
|
+
# header section of formatted log messages (time, level, name, etc.).
|
132
|
+
#
|
133
|
+
# @example Getting the {HeaderTokens}
|
134
|
+
# # You won't see much unless logging is setup
|
135
|
+
# NRSER::Log.setup! dest: $stdout, level: :info
|
136
|
+
#
|
137
|
+
# # Full object path to HeaderTokens - there's also a {NRSER::Log.header}
|
138
|
+
# # shortcut
|
139
|
+
# NRSER::Log.appender.formatter.header
|
140
|
+
# # => [:time, :level, :process_info, :tags, :named_tags, :duration, :name]
|
141
|
+
#
|
142
|
+
# NRSER.logger.info "Hey yo!"
|
143
|
+
# # > 2018-04-12 23:43:24.982040 INFO [19301:main] NRSER
|
144
|
+
# # > -- Hey yo!
|
145
|
+
# # >
|
146
|
+
# # => true
|
147
|
+
#
|
148
|
+
# @example Setting the {HeaderTokens}
|
149
|
+
# # You won't see much unless logging is setup
|
150
|
+
# NRSER::Log.setup! dest: $stdout, level: :info
|
151
|
+
#
|
152
|
+
# # Set a very simple header
|
153
|
+
# NRSER::Log.header :level, :name
|
154
|
+
# # => [:level, :name]
|
155
|
+
#
|
156
|
+
# # And notice the reduced log header
|
157
|
+
# NRSER.logger.info "Hey yo!"
|
158
|
+
# # > INFO NRSER
|
159
|
+
# # > -- Hey yo!
|
160
|
+
# # >
|
161
|
+
# # => true
|
162
|
+
#
|
163
|
+
# @param [Array<Symbol>] *tokens
|
164
|
+
# Optional list of token symbols to set as the header format.
|
165
|
+
#
|
166
|
+
# When empty, the method works as a getter, returning the current header
|
167
|
+
# format tokens.
|
168
|
+
#
|
169
|
+
# @return [HeaderTokens]
|
170
|
+
# The current header tokens.
|
171
|
+
#
|
172
|
+
def header *tokens
|
173
|
+
if tokens.empty?
|
174
|
+
@header ||= HeaderTokens.new
|
175
|
+
else
|
176
|
+
@header = HeaderTokens.new tokens
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
# Set the header section format tokens.
|
182
|
+
#
|
183
|
+
# See {#header} for details and examples of how the header works.
|
184
|
+
#
|
185
|
+
# @see #header
|
186
|
+
#
|
187
|
+
# @param [Array<Symbol>] *tokens
|
188
|
+
# Token symbols to set as the header format.
|
189
|
+
#
|
190
|
+
# @return [HeaderTokens]
|
191
|
+
# The new header format.
|
192
|
+
#
|
193
|
+
def header= tokens
|
194
|
+
@header = HeaderTokens.new tokens
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
# Get or set the body section tokens.
|
199
|
+
#
|
200
|
+
# Just like {#header}, which has details and examples, but for the "body"
|
201
|
+
# section of log messages (message, payload, exception).
|
202
|
+
#
|
203
|
+
# @see #header
|
204
|
+
#
|
205
|
+
# @param [Array<Symbol>] *tokens
|
206
|
+
# When not empty, sets the body to those tokens in that order.
|
207
|
+
#
|
208
|
+
# When empty, the current body is returned.
|
209
|
+
#
|
210
|
+
# @return [BodyTokens]
|
211
|
+
# The new and/or current body.
|
212
|
+
#
|
213
|
+
def body *tokens
|
214
|
+
if tokens.empty?
|
215
|
+
@body ||= BodyTokens.new
|
216
|
+
else
|
217
|
+
@body = BodyTokens.new tokens
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
|
222
|
+
# Set the body section format tokens.
|
223
|
+
#
|
224
|
+
# See {#header} for details and examples of how the header works.
|
225
|
+
#
|
226
|
+
# @see #header
|
227
|
+
#
|
228
|
+
# @param [Array<Symbol>] *tokens
|
229
|
+
# Token symbols to set as the body format.
|
230
|
+
#
|
231
|
+
# @return [HeaderTokens]
|
232
|
+
# The new body format.
|
233
|
+
#
|
234
|
+
def body= tokens
|
235
|
+
@body = BodyTokens.new tokens
|
236
|
+
end
|
237
|
+
|
238
|
+
|
239
|
+
protected
|
240
|
+
# ========================================================================
|
241
|
+
|
242
|
+
# Use {#header} to render the header string for the current log.
|
243
|
+
#
|
244
|
+
# @return [String]
|
245
|
+
#
|
246
|
+
def render_header
|
247
|
+
header.map( &method( :send ) ).compact.join ' '
|
248
|
+
end # #header
|
249
|
+
|
250
|
+
|
251
|
+
# Use {#body} to render the header string for the current log.
|
252
|
+
#
|
253
|
+
# @return [String]
|
254
|
+
#
|
255
|
+
def render_body
|
256
|
+
body.map( &method( :send ) ).compact.join ' '
|
257
|
+
end
|
258
|
+
|
259
|
+
|
260
|
+
# Render the current log message using {#render_header} and {#render_body}.
|
261
|
+
#
|
262
|
+
# @return [String]
|
263
|
+
#
|
264
|
+
def render_log
|
265
|
+
render_header + "\n" + render_body + "\n"
|
266
|
+
end
|
267
|
+
|
268
|
+
public # end protected ***************************************************
|
269
|
+
|
270
|
+
end # module NRSER::Log::Formatter::Mixin
|
File without changes
|
@@ -0,0 +1,229 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Deps
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
require 'semantic_logger'
|
11
|
+
|
12
|
+
|
13
|
+
# Definitions
|
14
|
+
# =======================================================================
|
15
|
+
|
16
|
+
# Extension of {SemanticLogger::Logger} to add and customize behavior.
|
17
|
+
#
|
18
|
+
class NRSER::Log::Logger < SemanticLogger::Logger
|
19
|
+
|
20
|
+
# Classes
|
21
|
+
# ========================================================================
|
22
|
+
|
23
|
+
# Class that points to a {NRSER::Log::Logger} and provides the log methods
|
24
|
+
# (`#error`, `#warn`, ... `#trace`) with an additional `&block` parameter.
|
25
|
+
#
|
26
|
+
# Each of those methods calls the block in a `begin` / `rescue`, and if it
|
27
|
+
# raises, the log message will be dispatched with the raised error added.
|
28
|
+
#
|
29
|
+
# @see NRSER::Log::Logger#catch
|
30
|
+
#
|
31
|
+
class Catcher
|
32
|
+
|
33
|
+
# Construction
|
34
|
+
# ========================================================================
|
35
|
+
|
36
|
+
# Instantiate a new `Catcher`.
|
37
|
+
#
|
38
|
+
# @param [NRSER::Log::Logger] logger
|
39
|
+
# The logger to use if the block raises.
|
40
|
+
#
|
41
|
+
# @param [*] on_fail:
|
42
|
+
# Value to return when `&block` raises.
|
43
|
+
#
|
44
|
+
def initialize logger, on_fail: nil
|
45
|
+
@logger = logger
|
46
|
+
@on_fail = on_fail
|
47
|
+
end # #initialize
|
48
|
+
|
49
|
+
|
50
|
+
# Instance Methods
|
51
|
+
# ========================================================================
|
52
|
+
|
53
|
+
SemanticLogger::LEVELS.each do |level|
|
54
|
+
define_method level do |message = nil, payload = nil, &block|
|
55
|
+
begin
|
56
|
+
block.call
|
57
|
+
rescue Exception => error
|
58
|
+
@logger.send level, message, payload, error
|
59
|
+
@on_fail
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end # class Catcher
|
65
|
+
|
66
|
+
|
67
|
+
# Attributes
|
68
|
+
# ========================================================================
|
69
|
+
|
70
|
+
# TODO document `awesome_name` attribute.
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
#
|
74
|
+
attr_reader :awesome_name
|
75
|
+
|
76
|
+
|
77
|
+
# Constructor
|
78
|
+
# ========================================================================
|
79
|
+
|
80
|
+
# Overrides {SemanticLogger::Logger#initialize}¹ to extend "subject" support
|
81
|
+
# to instances (as well as modules/classes and strings).
|
82
|
+
#
|
83
|
+
# > ¹ {SemanticLogger::Logger#initialize} is just a proxy to
|
84
|
+
# > {SemanticLogger::Base#initialize}, which is what this implementation
|
85
|
+
# > is based off.
|
86
|
+
#
|
87
|
+
# @param [Module | String | INSTANCE] subject
|
88
|
+
# Name of the class, module, or other identifier for which the log messages
|
89
|
+
# are being logged
|
90
|
+
#
|
91
|
+
# @param [nil | Symbol] level:
|
92
|
+
# Only allow log entries of this level or higher to be written to this
|
93
|
+
# appender For example if set to :warn, this appender would only log
|
94
|
+
# `:warn` and `:fatal` log messages when other appenders could be logging
|
95
|
+
# `:info` and lower.
|
96
|
+
#
|
97
|
+
# @param [nil | Regexp | Proc<(SemanticLogger::Log) => Boolean>] filter:
|
98
|
+
# 1. {RegExp}: Only include log messages where the class name matches
|
99
|
+
# the supplied regular expression. All other messages will be
|
100
|
+
# ignored.
|
101
|
+
#
|
102
|
+
# 2. {Proc}: Only include log messages where the supplied Proc returns
|
103
|
+
# `true`.
|
104
|
+
#
|
105
|
+
# @raise [NRSER::TypeError]
|
106
|
+
# If `filter:` is not an acceptable type.
|
107
|
+
#
|
108
|
+
def initialize subject, level: nil, filter: nil
|
109
|
+
# Support filtering all messages to this logger using a Regular Expression
|
110
|
+
# or Proc
|
111
|
+
unless filter.nil? || filter.is_a?( Regexp ) || filter.is_a?( Proc )
|
112
|
+
raise NRSER::TypeError,
|
113
|
+
":filter must be a Regexp or Proc",
|
114
|
+
filter: filter,
|
115
|
+
subject: subject,
|
116
|
+
level: level
|
117
|
+
end
|
118
|
+
|
119
|
+
@filter = filter.is_a?(Regexp) ? filter.freeze : filter
|
120
|
+
|
121
|
+
# @name = klass.is_a?(String) ? klass : klass.name
|
122
|
+
case subject
|
123
|
+
when String
|
124
|
+
@name = subject
|
125
|
+
@awesome_name = subject
|
126
|
+
@type = :string
|
127
|
+
|
128
|
+
when Module
|
129
|
+
@name = subject.safe_name
|
130
|
+
@awesome_name = subject.ai multiline: true, raw: true
|
131
|
+
@type = subject.is_a?( Class ) ? :class : :module
|
132
|
+
|
133
|
+
else
|
134
|
+
@name = subject.to_s
|
135
|
+
@awesome_name = subject.ai multiline: true, raw: true
|
136
|
+
@type = :instance
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
if level.nil?
|
141
|
+
# Allow the global default level to determine this loggers log level
|
142
|
+
@level_index = nil
|
143
|
+
@level = nil
|
144
|
+
else
|
145
|
+
self.level = level
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
# Instance Methods
|
151
|
+
# ========================================================================
|
152
|
+
|
153
|
+
# A sweet way to try something and just log any {Exception}.
|
154
|
+
#
|
155
|
+
# Useful for situations where the operation is question is not necessary
|
156
|
+
# or can not be allowed to propagate errors, but you would like to record
|
157
|
+
# and/or let the user know that it failed.
|
158
|
+
#
|
159
|
+
# Create a new {Catcher} for this logger that defines the log methods
|
160
|
+
# (`#error`, `warn`, ... `:trace`) to also accept blocks that will be
|
161
|
+
# executed in a `begin`/`rescue`.
|
162
|
+
#
|
163
|
+
# If the block raises, the catcher will call the log method, adding the
|
164
|
+
# caught {Exception}.
|
165
|
+
#
|
166
|
+
# @example Log any error as a warning
|
167
|
+
# logger.catch.warn do
|
168
|
+
# something_that_may_raise
|
169
|
+
# end
|
170
|
+
#
|
171
|
+
# # We should "always" get to here
|
172
|
+
#
|
173
|
+
# @example Log any error as warning with message and payload
|
174
|
+
# logger.catch.warn(
|
175
|
+
# "This thing failed!",
|
176
|
+
# some_detail: some_value,
|
177
|
+
# ) do
|
178
|
+
# something_that_may_raise
|
179
|
+
# end
|
180
|
+
#
|
181
|
+
# # We should "always" get to here
|
182
|
+
#
|
183
|
+
# @example Return a custom value on error
|
184
|
+
# result = logger.catch( on_fail: :blue ).debug do
|
185
|
+
# what_is_your_favorite_color?
|
186
|
+
# end
|
187
|
+
#
|
188
|
+
# @param **options
|
189
|
+
# Passed to {Catcher#initialize}.
|
190
|
+
#
|
191
|
+
# @return [Catcher]
|
192
|
+
#
|
193
|
+
def catch **options
|
194
|
+
Catcher.new self, **options
|
195
|
+
end # #catch
|
196
|
+
|
197
|
+
|
198
|
+
# Set the level for the execution of `&block`, restoring it to it's previous
|
199
|
+
# level afterwards.
|
200
|
+
#
|
201
|
+
# Like what {SemanticLogger::Logger#silence} does (which just forwards to
|
202
|
+
# {SemanticLogger.silence}), but applies only to *this* logger (where as
|
203
|
+
# {SemanticLogger::Logger#silence} applies on to the global default level).
|
204
|
+
#
|
205
|
+
# Useful for quickly turning down the log level to see trace/debug output
|
206
|
+
# from a specific section.
|
207
|
+
#
|
208
|
+
# @param [Symbol?] level
|
209
|
+
# One of {SemanticLogger::LEVELS} or `nil` to use the global default level.
|
210
|
+
#
|
211
|
+
# @param [Proc<() => RESULT] &block
|
212
|
+
# Block to execute with the `level`.
|
213
|
+
#
|
214
|
+
# @return [RESULT]
|
215
|
+
# Whatever `&block` returns.
|
216
|
+
#
|
217
|
+
def with_level level, &block
|
218
|
+
prior_level = @level
|
219
|
+
self.level = level
|
220
|
+
|
221
|
+
begin
|
222
|
+
block.call
|
223
|
+
ensure
|
224
|
+
self.level = prior_level
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
end # class NRSER::Log::Logger
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Definitions
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Adaptation of {SemanticLogger::Loggable} mixin to use {NRSER::Log::Logger}
|
8
|
+
# instances from {NRSER::Log.[]}.
|
9
|
+
#
|
10
|
+
# Like {SemanticLogger::Loggable} adds class and instance `logger` and
|
11
|
+
# `logger=` methods that create loggers on demand and store them in the
|
12
|
+
# `@semantic_logger` instance variables.
|
13
|
+
#
|
14
|
+
module NRSER::Log::Mixin
|
15
|
+
|
16
|
+
# Methods to mix into the including class.
|
17
|
+
#
|
18
|
+
module ClassMethods
|
19
|
+
# Returns [SemanticLogger::Logger] class level logger
|
20
|
+
def logger
|
21
|
+
@semantic_logger ||= NRSER::Log[ self ]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Replace instance class level logger
|
25
|
+
def logger= logger
|
26
|
+
@semantic_logger = logger
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# Class Methods
|
32
|
+
# ========================================================================
|
33
|
+
|
34
|
+
def self.included base
|
35
|
+
base.extend ClassMethods
|
36
|
+
|
37
|
+
# Adds `.logger_measure_method`
|
38
|
+
base.extend SemanticLogger::Loggable::ClassMethods
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# Instance Methods
|
43
|
+
# ========================================================================
|
44
|
+
|
45
|
+
# Returns [SemanticLogger::Logger] instance level logger
|
46
|
+
def logger
|
47
|
+
@semantic_logger ||= self.class.logger
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
# Replace instance level logger
|
52
|
+
def logger= logger
|
53
|
+
@semantic_logger = logger
|
54
|
+
end
|
55
|
+
|
56
|
+
end # module NRSER::Log::Mixin
|