markdown_logging_proxy 1.0.0 → 1.0.1

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