markdown_logging_proxy 1.0.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ede32c7a00afa640bd44e6ec610034cc8a968e369a214d80bc3071c5b902516
4
- data.tar.gz: c2032172bb4e05c3ebf6ac0ba30984c08623d4948b371f1afb77199ed4effae3
3
+ metadata.gz: 338dd4aa3a43c7cda534f2b694a44b1347e1ad7434f417aa479dc8bb4daf7f95
4
+ data.tar.gz: 0bcd6c0fd97df22c18495e5f68a9181a45cd4dc2997c3d2754ba99e4b9678104
5
5
  SHA512:
6
- metadata.gz: a60b3241307b03bd0ef86b4cec3ca1fc149e3cb552dfea7eecffadf9e831f014f367cd714b4e3a3897d3f08b6258ece8e22111500989707e216f909726e45ab1
7
- data.tar.gz: 2dadcbef2a63e99aa6187751ee8cbf2c1318add028e0d6443f6f2331895dbadc27c4a20cdf740468df83937183a94f88bd28e6a8d46dee6fe21b5a3572f18bbe
6
+ metadata.gz: 689b425d69ab942947a53913d1ea6b2405d334d76e31bdb25050ed89fe3eb1bc5250f95801a6da1dd7b290b700c6ae62914f3d01d17d7f21ea782135920b6f8e
7
+ data.tar.gz: 3c67856e0afc5c95b08a1606e0d6d1338e96ee41542e6608deca25c77fe1ea1e758f8ce479c075de5f1de769277716285c56cb0f527c4d1fc2139c2fc8115611
data/CHANGELOG.md CHANGED
@@ -3,3 +3,14 @@
3
3
  ## [0.1.0] - 2022-08-22
4
4
 
5
5
  - Initial release
6
+
7
+ ## [1.0.0]
8
+
9
+ - Release of gem to rubygems
10
+ - Proxy now defines zero methods besides `method_missing`
11
+ - Addition of `bin/example` script
12
+
13
+ ## [1.0.1]
14
+
15
+ - Add missing CHANGELOG updates
16
+ - Commit updates to compiled `dist/` version of library
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_logging_proxy (0.1.0)
4
+ markdown_logging_proxy (1.0.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,3 +1,78 @@
1
+ module MarkdownLoggingProxy
2
+ class MarkdownLogger
3
+ def self.inspect_object(object)
4
+ ['```ruby', object.pretty_inspect.chomp, '```'].join("\n")
5
+ end
6
+
7
+ def self.id_object(object)
8
+ # #<Object:0x00007f5a0919e140>
9
+ "##{object.class}:0x#{object.object_id.to_s(16)}>"
10
+ end
11
+
12
+ def self.build(location, **options)
13
+ return location if location.is_a?(MarkdownLogger)
14
+ new(location, **options)
15
+ end
16
+
17
+ attr_reader :std_logger, :backtrace, :heading_level
18
+
19
+ def initialize(location, backtrace: true)
20
+ @std_logger = create_logger(location)
21
+ @heading_level = 1
22
+ @backtrace = backtrace
23
+ end
24
+
25
+ def log(level, heading = 3, msg)
26
+ @heading_level = heading
27
+ std_logger.send(level, msg)
28
+ end
29
+
30
+ def inspect_backtrace(ignore = 4)
31
+ return unless backtrace
32
+ lines =
33
+ case backtrace
34
+ when true then caller(ignore)
35
+ when Regexp then caller(ignore).grep(backtrace)
36
+ else
37
+ []
38
+ end
39
+ <<~MSG.chomp
40
+
41
+ Backtrace:
42
+
43
+ #{lines.map { |l| "* #{l.chop}`" }.join("\n")}
44
+ MSG
45
+ end
46
+
47
+ private
48
+
49
+ def logger_instance(location)
50
+ case location
51
+ when Logger then location
52
+ else
53
+ Logger.new(location)
54
+ end
55
+ end
56
+
57
+ def create_logger(location)
58
+ logger_instance(location).tap do |logger|
59
+ logger.formatter = markdown_formatter
60
+ end
61
+ end
62
+
63
+ def markdown_formatter
64
+ proc do |severity, time, __exec, msg|
65
+ "#{'#' * heading_level} #{severity} in #{Process.pid} at #{time.iso8601} -- #{msg}\n\n"
66
+ end
67
+ end
68
+ end
69
+ end
70
+ module MarkdownLoggingProxy
71
+ # just a shortcut for Proxy.new
72
+ def self.new(*args, **options)
73
+ Proxy.new(*args, **options)
74
+ end
75
+ end
1
76
  module MarkdownLoggingProxy
2
77
  # frozen_string_literal: true
3
78
 
@@ -9,141 +84,151 @@ module MarkdownLoggingProxy
9
84
  class Proxy
10
85
 
11
86
  def initialize(
12
- target:,
13
- logger: nil,
87
+ to_proxy = nil,
88
+ target: nil,
14
89
  location: STDOUT,
15
- backtrace: /projects/, # regex/true/false backtrace control
16
- ignore: [], # methods we shouldn't proxy
90
+ backtrace: true, # regex/true/false backtrace control
91
+ ignore: [], # methods we shouldn't log/proxy
17
92
  proxy_response: [], # methods we should return a proxy for
18
93
  overwrite: [] # methods defined on Object we should overwrite
19
94
  )
20
- @ignore = (ignore + proxy_response).uniq
21
- @proxy_response = proxy_response
22
- @target = target
23
- @logger =
24
- if logger
25
- Utils.format_logger(logger)
26
- else
27
- Utils.create_logger(location)
28
- end
29
- @backtrace = backtrace
95
+ @target = to_proxy || target
96
+ raise ArgumentError, "Missing required proxy target" unless @target
97
+ @logger = MarkdownLogger.build(location, backtrace: backtrace)
98
+ @tracer = Tracer.new(
99
+ target: @target,
100
+ proxy: self,
101
+ logger: @logger,
102
+ ignore: ignore,
103
+ proxy_response: proxy_response,
104
+ proxy_options: {
105
+ overwrite: overwrite,
106
+ backtrace: backtrace,
107
+ }
108
+ )
30
109
  overwrite.each do |meth|
31
110
  define_method(meth) do |*args, &blk|
32
- __trace_method(meth, args, &blk)
111
+ @traceer.trace(meth, args, &blk)
33
112
  end
34
113
  end
35
114
  end
36
115
 
37
116
  def method_missing(meth, *args, &blk)
38
- __trace_method(meth, args, &blk)
117
+ @tracer.trace(meth, args, &blk)
118
+ end
119
+ end
120
+ end
121
+ module MarkdownLoggingProxy
122
+ class Tracer
123
+ attr_reader :target, :logger, :ignore, :proxy
124
+
125
+ def initialize(
126
+ target:,
127
+ proxy:,
128
+ logger: nil,
129
+ ignore: [],
130
+ proxy_response: [],
131
+ proxy_options: {}
132
+ )
133
+ @target = target
134
+ @logger = logger
135
+ @ignore = (ignore + proxy_response)
136
+ @proxy_response = proxy_response
137
+ @proxy_options = proxy_options
39
138
  end
40
139
 
41
- private
42
-
43
- def __trace_method(meth, args, &blk)
44
- __log :info, meth, 2, <<~MSG
45
- Calling `#{meth}`
140
+ def trace(meth, args, &blk)
141
+ log_call_signature(meth, args, &blk) unless ignore?(meth)
142
+ log_and_proxy_response(meth, args, &blk)
143
+ rescue StandardError => e
144
+ log_and_reraise_error(meth, e)
145
+ end
46
146
 
47
- Arguments:
147
+ def proxy_response?(meth)
148
+ case @proxy_response
149
+ when true, false then @proxy_response
150
+ else
151
+ @proxy_response.member?(meth)
152
+ end
153
+ end
48
154
 
49
- #{__inspect_object(args)}
155
+ def ignore?(meth)
156
+ @ignore.member?(meth)
157
+ end
50
158
 
51
- Block? #{block_given? ? 'Yes' : 'No'}
52
- #{__display_backtrace}
53
- MSG
159
+ private
54
160
 
55
- __proxy_response(meth, @target.public_send(meth, *args, &__proxy_block(meth, blk))).tap do |response|
56
- __log :info, meth, <<~MSG
57
- `#{meth}` Response
161
+ def log_call_signature(meth, args, &blk)
162
+ return if ignore.member?(meth)
163
+ logger.log :info, 1, <<~MSG.chomp
164
+ Calling `#{meth}` on #{MarkdownLogger.id_object(target)}
58
165
 
59
- #{__inspect_object(response)}
60
- MSG
61
- end
62
- rescue StandardError => e
63
- __log :error, meth, <<~MSG
64
- Error in `#{meth}`
166
+ Arguments:
65
167
 
66
- Type: #{e.class}
168
+ #{MarkdownLogger.inspect_object(args)}
67
169
 
68
- #{__inspect_object(e)}
170
+ Block? #{block_given? ? 'Yes' : 'No'}
171
+ #{logger.inspect_backtrace}
69
172
  MSG
70
- raise e
71
- end
72
-
73
- def __display_backtrace(ignore = 3)
74
- displayed_trace =
75
- case @backtrace
76
- when true then caller(ignore)
77
- when Regexp then caller(ignore).grep(@backtrace)
78
- end
79
- displayed_trace.map { |l| "* #{l.chop}`" }.join("\n") if displayed_trace
80
173
  end
81
174
 
82
- def __log(level, meth, heading = 3, msg)
83
- return if @ignore.member?(meth)
84
- @heading_level = heading
85
- @logger.send(level, msg)
86
- end
87
-
88
- def __proxy_response(meth, response)
89
- return response unless @proxy_response.member?(meth)
90
- __log :info, nil, <<~MSG
91
- Using proxied response for `#{meth}`
92
-
93
- Object to proxy:
94
-
95
- #{__inspect_object(response)}
175
+ def log_and_proxy_response(meth, args, &blk)
176
+ response = target.public_send(meth, *args, &log_and_proxy_block(meth, blk))
177
+ log_response(meth, response) unless ignore?(meth)
178
+ return response unless proxy_response?(meth)
179
+ logger.log :info, 3, <<~MSG
180
+ Returning proxied response to `#{meth}`
181
+
182
+ Proxy from `#{meth}` on #{MarkdownLogger.id_object(target)}
183
+
184
+ Proxy for: #{MarkdownLogger.id_object(response)}
96
185
  MSG
97
- self.class.new(target: response, logger: @logger)
186
+ Proxy.new(**@proxy_options.merge(
187
+ target: response,
188
+ location: logger,
189
+ proxy_response: @proxy_response,
190
+ ignore: @ignore,
191
+ ))
98
192
  end
99
193
 
100
- def __proxy_block(meth, block)
101
- return if block.nil?
102
- logger = @logger
194
+ def log_and_proxy_block(meth, blk)
195
+ return if blk.nil?
103
196
  proc do |*args|
104
- logger.info <<~MSG
105
- Yield to block in `#{meth}`
197
+ logger.log :info, 3, <<~MSG
198
+ Yield to block in `#{meth}` on #{MarkdownLogger.id_object(target)}
106
199
 
107
200
  Arguments:
108
201
 
109
- #{__inspect_object(args)}
202
+ #{MarkdownLogger.inspect_object(args)}
110
203
  MSG
111
- block.call(*args).tap do |response|
112
- logger.info <<~MSG
204
+ blk.call(*args).tap do |response|
205
+ logger.log :info, 4, <<~MSG
113
206
  Response from block in `#{meth}`
114
207
 
115
- #{__inspect_object(response)}
208
+ #{MarkdownLogger.inspect_object(response)}
116
209
  MSG
117
210
  end
118
211
  end
119
212
  end
120
213
 
121
- def __inspect_object(obj)
122
- ['```ruby', obj.pretty_inspect.chomp, '```'].join("\n")
123
- end
124
- end
214
+ def log_and_reraise_error(meth, error)
215
+ logger.log :error, 2, <<~MSG
216
+ Error in `#{meth}`
125
217
 
126
- end
127
- module MarkdownLoggingProxy
128
- module Utils
129
- def self.heading_level
130
- @heading_level || 1
131
- end
218
+ Type: #{error.class}
132
219
 
133
- def self.heading_level=(level)
134
- @heading_level = level
220
+ #{MarkdownLogger.inspect_object(error)}
221
+ MSG
222
+ raise error
135
223
  end
136
224
 
137
- def self.create_logger(location)
138
- logger = location.kind_of?(Logger) ? location : Logger.new(location)
139
- format_logger logger
140
- end
225
+ def log_response(meth, response)
226
+ return if ignore?(meth)
227
+ logger.log :info, 2, <<~MSG.chomp
228
+ `#{meth}` response
141
229
 
142
- def self.format_logger(logger)
143
- logger.formatter = proc do |severity, time, _, msg|
144
- "#{'#' * heading_level} #{severity} in #{Process.pid} at #{time.iso8601} -- #{msg}\n\n"
145
- end
146
- logger
230
+ #{MarkdownLogger.inspect_object(response)}
231
+ MSG
147
232
  end
148
233
  end
149
- end
234
+ end
@@ -0,0 +1,33 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "markdown_logging_proxy"
3
+ spec.version = "1.0.1"
4
+ spec.authors = ["Carl Zulauf"]
5
+ spec.email = ["carl@linkleaf.com"]
6
+
7
+ spec.summary = "Proxy object for debugging"
8
+ spec.description = "Wrap your ruby objects in a proxy to find out what happens to them"
9
+ spec.homepage = "https://github.com/carlzulauf/markdown_logging_proxy"
10
+ spec.license = "MIT"
11
+ spec.required_ruby_version = ">= 2.6.0"
12
+
13
+ spec.metadata["homepage_uri"] = spec.homepage
14
+ spec.metadata["source_code_uri"] = "https://github.com/carlzulauf/markdown_logging_proxy"
15
+ spec.metadata["changelog_uri"] = "https://github.com/carlzulauf/markdown_logging_proxy/blob/main/CHANGELOG.md"
16
+
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = Dir.chdir(__dir__) do
20
+ `git ls-files -z`.split("\x0").reject do |f|
21
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
22
+ end
23
+ end
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
26
+ spec.require_paths = ["lib"]
27
+
28
+ # Uncomment to register a new dependency of your gem
29
+ # spec.add_dependency "example-gem", "~> 1.0"
30
+
31
+ # For more information and examples about making a new gem, check out our
32
+ # guide at: https://bundler.io/guides/creating_gem.html
33
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdown_logging_proxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carl Zulauf
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-28 00:00:00.000000000 Z
11
+ date: 2022-08-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Wrap your ruby objects in a proxy to find out what happens to them
14
14
  email:
@@ -31,6 +31,7 @@ files:
31
31
  - lib/markdown_logging_proxy/module_methods.rb
32
32
  - lib/markdown_logging_proxy/proxy.rb
33
33
  - lib/markdown_logging_proxy/tracer.rb
34
+ - markdown_logging_proxy.gemspec
34
35
  homepage: https://github.com/carlzulauf/markdown_logging_proxy
35
36
  licenses:
36
37
  - MIT