lumberjack_rails 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9e2d5624bd1b1c1c67487fde54b2ebd11def32b5e715e4d8ff7c7e7ece1d3253
4
+ data.tar.gz: d3bf91601bf2380602e887d71c863cf631968b910655db9020aee66377882fc7
5
+ SHA512:
6
+ metadata.gz: '08425991455694b32dbccf992ad8448b003a94a09b5a2971f27aa2d056c186d70fa5793715a28b83d43b22696ae0401833c84af8ec83a098832a3950811014db'
7
+ data.tar.gz: 6c17517e84a4e0520a50da6199632403f1e4b4899c203a1688d4f1ae5d92361030d535375f6add1f4ab663fe37c5708b16343b54d61d8f36660053b5a52e1ace
@@ -0,0 +1,12 @@
1
+ # Dependabot update strategy
2
+ version: 2
3
+ updates:
4
+ - package-ecosystem: bundler
5
+ directory: "/"
6
+ schedule:
7
+ interval: weekly
8
+ allow:
9
+ # Automatically keep all runtime dependencies updated
10
+ - dependency-name: "*"
11
+ dependency-type: "production"
12
+ versioning-strategy: lockfile-only
@@ -0,0 +1,70 @@
1
+ name: Continuous Integration
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - actions-*
8
+ pull_request:
9
+ branches-ignore:
10
+ - actions-*
11
+ workflow_dispatch:
12
+
13
+ env:
14
+ BUNDLE_CLEAN: "true"
15
+ BUNDLE_PATH: vendor/bundle
16
+ BUNDLE_JOBS: 3
17
+ BUNDLE_RETRY: 3
18
+
19
+ jobs:
20
+ build:
21
+ name: build ruby-${{ matrix.ruby }} ${{ matrix.appraisal }}
22
+ runs-on: ubuntu-latest
23
+ strategy:
24
+ fail-fast: false
25
+ matrix:
26
+ include:
27
+ - ruby: "ruby"
28
+ standardrb: true
29
+ yard: true
30
+ - ruby: "3.4"
31
+ appraisal: rails_8
32
+ - ruby: "3.3"
33
+ appraisal: rails_8.0
34
+ - ruby: "3.1"
35
+ appraisal: rails_7
36
+ - ruby: "3.0"
37
+ appraisal: rails_7.1
38
+ - ruby: "ruby"
39
+ appraisal: no_rails
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+ - name: Set up Ruby ${{ matrix.ruby }}
43
+ uses: ruby/setup-ruby@v1
44
+ with:
45
+ ruby-version: "${{ matrix.ruby }}"
46
+ - name: Install packages
47
+ run: |
48
+ sudo apt-get update
49
+ sudo apt-get install libsqlite3-dev
50
+ - name: Setup bundler
51
+ if: matrix.bundler != ''
52
+ run: |
53
+ gem uninstall bundler --all
54
+ gem install bundler --no-document --version ${{ matrix.bundler }}
55
+ - name: Set Appraisal bundle
56
+ if: matrix.appraisal != ''
57
+ run: |
58
+ echo "using gemfile gemfiles/${{ matrix.appraisal }}.gemfile"
59
+ bundle config set gemfile "gemfiles/${{ matrix.appraisal }}.gemfile"
60
+ - name: Install gems
61
+ run: |
62
+ bundle update
63
+ - name: Run Tests
64
+ run: bundle exec rake
65
+ - name: standardrb
66
+ if: matrix.standardrb == true
67
+ run: bundle exec standardrb
68
+ - name: yard
69
+ if: matrix.yard == true
70
+ run: bundle exec yard --fail-on-warning
data/.standard.yml ADDED
@@ -0,0 +1,9 @@
1
+ ruby_version: 3.0
2
+
3
+ format: progress
4
+
5
+ ignore:
6
+ - 'spec/**/*':
7
+ - Lint/UselessAssignment
8
+ - Lint/Void
9
+ - 'test_app/**/*'
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --exclude lib/lumberjack/rails/apply_patches.rb
data/CHANGE_LOG.md ADDED
@@ -0,0 +1,11 @@
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
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## 1.0.0
8
+
9
+ ### Added
10
+
11
+ - Initial release
data/MIT_LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2025 Brian Durand
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,329 @@
1
+ # Lumberjack Rails
2
+
3
+ [![Continuous Integration](https://github.com/bdurand/lumberjack_rails/actions/workflows/continuous_integration.yml/badge.svg)](https://github.com/bdurand/lumberjack_rails/actions/workflows/continuous_integration.yml)
4
+ [![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
5
+ [![Gem Version](https://badge.fury.io/rb/lumberjack_rails.svg)](https://badge.fury.io/rb/lumberjack_rails)
6
+
7
+ The `lumberjack_rails` gem provides support for using the [lumberjack](https://github.com/bdurand/lumberjack) logging library in Rails applications.
8
+
9
+ Rails has some of its own extensions to the Ruby standard library logger, and this gem bridges the gap between the two logging systems to add Lumberjack features to the `Rails.logger` and Rails features to Lumberjack loggers.
10
+
11
+ ## Usage
12
+
13
+ With this gem installed, your main application logger will be a Lumberjack logger. The logger that gets initialized is defined by your application's configuration.
14
+
15
+ ### Configuration Options
16
+
17
+ #### `config.lumberjack.enabled`
18
+
19
+ Enables or disables the Lumberjack logger. If this is set to `false`, then Lumberjack will not be used.
20
+
21
+ #### `config.lumberjack.level`
22
+
23
+ Sets the log level for the Lumberjack logger. This can be set to any valid log level supported by Lumberjack. This will defer to the standard Rails `config.log_level` setting or default to `:debug` if neither is set.
24
+
25
+ #### `config.lumberjack.device`
26
+
27
+ The device to write logs to (file path, IO object, etc.). Defaults to the Rails log file.
28
+
29
+ #### `config.lumberjack.attributes`
30
+
31
+ Hash of attributes to apply to all log messages. These attributes will be included in every log entry.
32
+
33
+ #### `config.lumberjack.shift_age`
34
+
35
+ The age (in seconds) of log files before they are rotated, or a shift name (`daily`, `weekly`, `monthly`). The default is no log rotation. See the [logger](https://github.com/ruby/logger) gem documentation for details.
36
+
37
+ #### `config.lumberjack.shift_size`
38
+
39
+ The size (in bytes) of log files before they are rotated if `shift_age` is set to an integer. Defaults to `1048576` (1MB). See the [logger](https://github.com/ruby/logger) gem documentation for details.
40
+
41
+ #### `config.lumberjack.log_rake_tasks`
42
+
43
+ Whether to redirect `$stdout` and `$stderr` to `Rails.logger` for rake tasks that depend on the `:environment` task when using a Lumberjack::Logger. Defaults to `false`.
44
+
45
+ > [!TIP]
46
+ > This is useful for getting output from `db:migrate` and other rake tasks run in production into your logs. It can often be difficult to track down issues in these tasks without proper logging.
47
+
48
+ > [!NOTE]
49
+ > This setting is ignored when running in an interactive terminal session.
50
+
51
+ #### `config.lumberjack.middleware`
52
+
53
+ Whether to install Rack middleware that adds a Lumberjack context to each request. Defaults to `true`.
54
+
55
+ #### `config.lumberjack.silence_rack_request_started`
56
+
57
+ When set to `true`, the "Started ..." log lines generated by `Rails::Rack::Logger` will be suppressed. This can help reduce log noise in applications where these lines are not needed. Defaults to `false`.
58
+
59
+ #### `config.lumberjack.request_attributes_proc`
60
+
61
+ A proc to add to log entries for each Rack request. The proc will be called with the request object.
62
+
63
+ > [!TIP]
64
+ > You can use this feature to add both static attributes and dynamic attributes (using a proc) to all log entries within a request context.
65
+
66
+ ```ruby
67
+ config.lumberjack.request_attributes_proc = ->(request) {
68
+ {
69
+ host: request.host,
70
+ method: request.request_method,
71
+ path: request.path,
72
+ request_id: request.request_id
73
+ }
74
+ }
75
+ ```
76
+
77
+ #### Additional Options
78
+
79
+ > [!TIP]
80
+ > For more readable logs in development or test environments, you can set `config.lumberjack.template` to `:local` to use the built-in template intended for human readability.
81
+ >
82
+ > If you have attributes that are logged on every entry but don't want them cluttering up your development logs (i.e. `host`, `version`, etc.), you can set `config.lumberjack.exclude_attributes` to the attribute names to exclude.
83
+
84
+ You can include `Lumberjack::Rails.active_record_entry_formatter` in your logger formatter to format ActiveRecord models in log attributes with just the model name and id.
85
+
86
+ ```ruby
87
+ config.lumberjack.formatter = Lumberjack.build_formatter do |formatter|
88
+ formatter.include(Lumberjack::Rails.active_record_entry_formatter)
89
+ end
90
+ ```
91
+
92
+ #### Example Configuration
93
+
94
+ Here's an example of how you might configure Lumberjack in your `config/application.rb`:
95
+
96
+ ```ruby
97
+ config.log_level = :info
98
+
99
+ # Set the program name on the logger
100
+ config.lumberjack.progname = Rails.application.railtie_name
101
+
102
+ # Add values we want on all log entries
103
+ config.lumberjack.attributes = {
104
+ host: Lumberjack::Utils.hostname, # Ensures hostname is UTF-8 encoded
105
+ pid: Lumberjack::Utils.global_pid # Returns a global PID value across all hosts
106
+ }
107
+
108
+ config.lumberjack.device = STDOUT
109
+
110
+ # Build the log entry formatter
111
+ config.lumberjack.formatter = Lumberjack.build_formatter do |formatter|
112
+ formatter.add(ActiveRecord::Base, :id)
113
+
114
+ # Format the :tags attribute as tags (e.g. [tag1] [tag2])
115
+ formatter.add_attribute("tags", :tags)
116
+
117
+ formatter.add_attribute("cost", :round, 2)
118
+ formatter.add_attribute_class("User") { |user| {id: user.id, username: user.username} }
119
+ end
120
+
121
+ # Use a custom template that adds the request id on all log entry lines.
122
+ config.lumberjack.template = "[{{time}} {{severity}} {{progname}} {{request_id}}] {{tags}} {{message}} -- {{attributes}}"
123
+ config.lumberjack.additional_lines = "> :request_id :message"
124
+
125
+ # Format log attributes as "[name=value]" (default is [name:value])
126
+ config.lumberjack.attribute_format = "[name=value]"
127
+
128
+ # Convert db:migrate and other rails task output to log entries
129
+ config.lumberjack.log_rake_tasks = true
130
+ ```
131
+
132
+ > [!TIP]
133
+ > If you are using a logging pipeline in production that supports [JSONL](https://jsonlines.org/) logs, then check out the [lumberjack_json_device](https://github.com/bdurand/lumberjack_json_device). The gem provides a mechanism for defining the JSON schema for your logs and outputting them to JSONL.
134
+
135
+ > [!TIP]
136
+ > If you want more easily readable log output in development or test environments, you can set the `config.lumberjack.template` to `:local`.
137
+ >
138
+ > If you have attributes that are logged on every entry but don't want them cluttering up your development logs, you can set `config.lumberjack.exclude_attributes` to the attribute names to exclude.
139
+ >
140
+ > You can also colorize the logs by setting `config.lumberjack.colorize` to `true` and set the format of the severity with `config.lumberjack.severity_format`.
141
+
142
+ ```ruby
143
+ config.lumberjack.template = :local
144
+ config.lumberjack.exclude_progname = true
145
+ config.lumberjack.exclude_attributes = [:host, :request_id]
146
+ config.lumberjack.colorize = true
147
+ config.lumberjack.severity_format = :emoji
148
+ ```
149
+
150
+ ### TaggedLogger
151
+
152
+ Rails has its own solution for logging metadata in the `tagged` method added to logger which can add an array of tags to log entries.
153
+
154
+ Lumberjack supports the `tagged` method and will put the tags into the `tags` attribute. You can format these similar to how Rails formats them in the logger template with the `{{tags}}` formatter.
155
+
156
+ ```ruby
157
+ # The :tags placeholder will be replaced with the tags attribute. This is the default template.
158
+ config.lumberjack.template = "[{{time}} {{severity}} {{progname}} ({{pid}})] {{tags}} {{message}} -- {{attributes}}"
159
+
160
+ # Add the :tags formatter. If you don't do this, then the tags will be formatted as an inspected array.
161
+ config.lumberjack.formatter = Lumberjack.build_formatter do |formatter|
162
+ formatter.add_attribute(:tags, :tags)
163
+ end
164
+ ```
165
+
166
+ ### Broadcast Logger
167
+
168
+ Rails provides a built-in mechanism for broadcasting log messages to multiple destinations. `Rails.logger` is actually an `ActiveSupport::BroadcastLogger` object wrapping one or more underlying loggers. When you call a method on `Rails.logger`, it will call that method on all underlying loggers. This can create some problems for methods that take a block since that block could get called once for each logger being broadcast to. Only one Lumberjack logger should be added `Rails.logger`. If more than one is added, method like `tag` or `context` that take a block will only be called on one of the loggers.
169
+
170
+ If you want to send your logs to multiple devices with Lumberjack, you can use the Multi device instead.
171
+
172
+ The one place that Rails uses multiple loggers out of the box is in development mode where logs are also sent to the console in addition to the log file. This functionality is supported.
173
+
174
+ ### Lumberjack Contexts
175
+
176
+ Contexts are used in Lumberjack to provide isolation for changes to your logger. Within a context block, you can change the log level, progname, or attributes and they will only apply within that block execution.
177
+
178
+ Contexts will be added via `around` callbacks to the following frameworks if they are installed:
179
+
180
+ - ActionController
181
+ - ActiveJob
182
+ - ActionCable
183
+ - ActionMailer
184
+ - ActionMailbox
185
+
186
+ In addition, a Rack middleware will be added to ensure a context is set on Rails.logger for each request.
187
+
188
+ This allows you to change the log level or tag attributes on `Rails.logger` within your application code in these frameworks without affecting the global logger or the settings in any concurrent requests.
189
+
190
+ ### Log Subscribers
191
+
192
+ Rails comes with several built-in log subscribers that are extended with Lumberjack. These include:
193
+
194
+ - `ActiveRecord::LogSubscriber`
195
+ - `ActionController::LogSubscriber`
196
+ - `ActionDispatch::LogSubscriber`
197
+ - `ActionView::LogSubscriber`
198
+ - `ActiveJob::LogSubscriber`
199
+ - `ActionMailer::LogSubscriber`
200
+ - `ActiveStorage::LogSubscriber`
201
+
202
+ These log subscribers will all use fork loggers. This these forked loggers are isolated from the main logger allowing you to change the log level and add attributes that is isolated to that log subscriber.
203
+
204
+ ```ruby
205
+ # Set up log subscribers in an initializer
206
+
207
+ ActiveSupport.on_load(:action_controller) do
208
+ ActionController::LogSubscriber.logger.tag!(user_id: Current.user_id) # Tag all log entries with the user ID
209
+ end
210
+
211
+ ActiveSupport.on_load(:action_view) do
212
+ unless Rails.env.local?
213
+ ActionView::LogSubscriber.logger.level = :warn # Silence view rendering logs in non-local environments
214
+ end
215
+ end
216
+ ```
217
+
218
+ You can also silence individual log subscriber events if you don't want to see them in your logs.
219
+
220
+ ```ruby
221
+ ActiveSupport.on_load(:action_controller) do
222
+ ActionController::LogSubscriber.silence_event!!(:start_processing) # Silence the "Started ..." log lines
223
+ end
224
+ ```
225
+
226
+ You can also silence the logs that Rack adds when a request starts processing. This subscriber is implemented a bit differently by Rails, so there is a different method to silence it.
227
+
228
+ ```ruby
229
+ Lumberjack::Rails.silence_rack_request_started = true
230
+ ```
231
+
232
+ You can also silence the Rack logger in your application's configuration.
233
+
234
+ ```ruby
235
+ config.lumberjack.silence_rack_request_started = true
236
+ ```
237
+
238
+ #### Enhanced ActionController Logging
239
+
240
+ The `ActionController::LogSubscriber` has been enhanced to allow you to specify additional attributes to be logged in the log entry when each request is finished processing. This log entry can be extremely useful as a canonical log entry for the request and Rails already supports adding some metadata onto the message. This extension allows you to add more metadata and add it as attributes for better structured logging.
241
+
242
+ ```ruby
243
+ # Setup the additional attributes in an initializer.
244
+
245
+ ActiveSupport.on_load(:action_controller) do
246
+ # Add the IP address from the request to the canonical log entry for the request.
247
+ # The notification event is passed to the block.
248
+ ActionController::LogSubscriber.add_process_log_attribute(:ip_address) { |event| event.payload[:request].remote_ip }
249
+
250
+ # You can also add multiple attributes with with a block that returns a hash.
251
+ ActionController::LogSubscriber.process_log_attributes do |event|
252
+ request = event.payload[:request]
253
+
254
+ # Get the HTTP status code from the event payload.
255
+ status = event.payload[:status]
256
+ if status.nil? && (exception_class_name = event.payload[:exception]&.first)
257
+ status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
258
+ end
259
+
260
+ {
261
+ http: {
262
+ status: status,
263
+ method: request.method,
264
+ url: request.base_url + request.filtered_path,
265
+ useragent: request.user_agent,
266
+ }
267
+ }
268
+ end
269
+ end
270
+ ```
271
+
272
+ ### Log Formatter
273
+
274
+ ActiveRecord models logged in attributes will automatically be logged with a formatter that will only log the class name and id for the model. You can add additional formatters for `ApplicationRecord` or for your models to override this behavior.
275
+
276
+ ### Testing
277
+
278
+ Lumberjack comes with built-in support for testing that critical log messages are generated. See the [lumberjack documentation](https://github.com/bdurand/lumberjack#testing-utilities) for more information.
279
+
280
+ If you are using RSpec, then you can use the [lumberjack_rails_rspec](https://github.com/bdurand/lumberjack_capture_device) gem for to add RSpec matchers for testing log messages to your test suite.
281
+
282
+ ```ruby
283
+ # In spec/rails_helper.rb
284
+
285
+ require "lumberjack/capture_device/rspec"
286
+
287
+ RSpec.configure do |config|
288
+ config.around do |example|
289
+ capture_logger_around_example(Rails.logger, example)
290
+ end
291
+ end
292
+
293
+ RSpec.describe MyModel do
294
+ it "logs a message when doing something" do
295
+ MyModel.do_something_important
296
+ expect(Rails.logger).to include_log_entry(:info, /did something important/)
297
+ end
298
+ end
299
+ ```
300
+
301
+ ## Installation
302
+
303
+ Add this line to your application's Gemfile:
304
+
305
+ ```ruby
306
+ gem 'lumberjack_rails'
307
+ ```
308
+
309
+ And then execute:
310
+
311
+ ```bash
312
+ $ bundle
313
+ ```
314
+
315
+ Or install it yourself as:
316
+
317
+ ```bash
318
+ $ gem install lumberjack_rails
319
+ ```
320
+
321
+ ## Contributing
322
+
323
+ Open a pull request on GitHub.
324
+
325
+ Please use the [standardrb](https://github.com/testdouble/standard) syntax and lint your code with `standardrb --fix` before submitting.
326
+
327
+ ## License
328
+
329
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lumberjack
4
+ module Rails
5
+ # Extension for ActionCable::Connection::Base to wrap command processing with Lumberjack context.
6
+ #
7
+ # This module ensures that all logging within ActionCable command processing is wrapped
8
+ # with the appropriate Lumberjack logger context, maintaining log consistency
9
+ # and enabling tagged logging features.
10
+ module ActionCableExtension
11
+ # Override the command method to wrap it with Lumberjack logger context.
12
+ #
13
+ # @return [Object] the result of the original command method
14
+ def command(...)
15
+ Lumberjack::Rails.logger_context(logger) { super }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lumberjack
4
+ module Rails
5
+ # Extension for ActionController::Base to wrap request processing with Lumberjack context.
6
+ #
7
+ # This module ensures that all logging within a controller action is wrapped
8
+ # with the appropriate Lumberjack logger context, maintaining log consistency
9
+ # and enabling tagged logging features.
10
+ module ActionControllerExtension
11
+ # Override the process method to wrap it with Lumberjack logger context.
12
+ #
13
+ # @return [Object] the result of the original process method
14
+ def process(...)
15
+ Lumberjack::Rails.logger_context(logger) { super }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lumberjack::Rails
4
+ # This extension to the ActionController::LogSubscriber class allows specifying log attributes that
5
+ # will only be applied on the process_action event. This log entry already serves as the canonical
6
+ # log entry for requests and includes metadata such as duration, allocations, etc. With this extension
7
+ # you can add whatever additonal attributes you want to summarize what happened during the request
8
+ # as log attributes. This gives you more flexibility to add context to your request logs.
9
+ #
10
+ # You can add dynamically evaluated attributes by providing a block that takes the event as an argument.
11
+ #
12
+ # @example
13
+ # ActionController::LogSubscriber.add_process_log_attribute(:ip_address) do |event|
14
+ # event.payload.request.remote_ip
15
+ # end
16
+ #
17
+ # ActionController::LogSubscriber.add_process_log_attribute(:duration) do |event|
18
+ # event.duration
19
+ # end
20
+ module ActionControllerLogSubscriberExtension
21
+ extend ActiveSupport::Concern
22
+
23
+ prepended do
24
+ @lumberjack_process_log_attributes = {}
25
+ @lumberjack_process_log_blocks = []
26
+ end
27
+
28
+ class_methods do
29
+ # Add a log attribute to be included in the process_action log entry. You must provide
30
+ # either a static value or a block that takes the event as an argument to dynamically
31
+ # evaluate the value at log time.
32
+ #
33
+ # @param name [String, Symbol] the name of the log attribute
34
+ # @param value [Object] the static value of the log attribute (optional if block is provided)
35
+ # @yield [event] a block that takes the event as an argument to dynamically evaluate the value (optional if value is provided)
36
+ # @raise [ArgumentError] if neither a value nor a block is provided, or if both are provided
37
+ # @return [void]
38
+ def add_process_log_attribute(name, value = nil, &block)
39
+ raise ArgumentError.new("Must provide a value or a block") if value.nil? && block.nil?
40
+ raise ArgumentError.new("Cannot provide both a value and a block") if value && block
41
+
42
+ @lumberjack_process_log_attributes[name.to_s] = value || block
43
+ end
44
+
45
+ # Add log attributes to be included in the process_action log entry. The block must
46
+ # take an ActiveSupport::Notifications::Event as an argument and return a hash.
47
+ #
48
+ # @yieldparam event [ActiveSupport::Notifications::Event] the event being processed
49
+ # @yieldreturn [Hash] a hash of log attributes to be merged into the log entry attributes.
50
+ # @return [void]
51
+ def process_log_attributes(&block)
52
+ @lumberjack_process_log_blocks << block
53
+ end
54
+
55
+ # Get the log attributes to be included in the process_action log entry.
56
+ #
57
+ # @param event [ActiveSupport::Notifications::Event] the event being processed
58
+ # @return [Hash{String => Object}] a hash of log attributes
59
+ # @api private
60
+ def eval_process_log_attributes(event)
61
+ attributes = @lumberjack_process_log_attributes.each_with_object({}) do |(name, value_or_block), attrs|
62
+ attrs[name] = if value_or_block.respond_to?(:call)
63
+ value_or_block.call(event)
64
+ else
65
+ value_or_block
66
+ end
67
+ end
68
+
69
+ @lumberjack_process_log_blocks.each do |block|
70
+ attrs = block.call(event)
71
+ attributes.merge!(Lumberjack::Utils.flatten_attributes(attrs)) if attrs.is_a?(Hash)
72
+ end
73
+
74
+ attributes
75
+ end
76
+
77
+ private
78
+
79
+ # Used for testing.
80
+ def clear_process_log_attributes
81
+ @lumberjack_process_log_attributes = {}
82
+ @lumberjack_process_log_blocks = []
83
+ end
84
+ end
85
+
86
+ def process_action(event) # :nodoc:
87
+ with_process_logger_attributes(event) do
88
+ super
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ def with_process_logger_attributes(event, &block)
95
+ attributes = self.class.eval_process_log_attributes(event) if logger
96
+ if attributes && !attributes.empty?
97
+ logger.tag(attributes, &block)
98
+ else
99
+ block.call
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lumberjack
4
+ module Rails
5
+ # Extension for ActionMailbox::Base to wrap mailbox processing with Lumberjack context.
6
+ #
7
+ # This module ensures that all logging within mailbox processing is wrapped
8
+ # with the appropriate Lumberjack logger context, maintaining log consistency
9
+ # and enabling tagged logging features.
10
+ module ActionMailboxExtension
11
+ # Override the perform_processing method to wrap it with Lumberjack logger context.
12
+ #
13
+ # @return [Object] the result of the original perform_processing method
14
+ def perform_processing(...)
15
+ Lumberjack::Rails.logger_context(logger) { super }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lumberjack
4
+ module Rails
5
+ # Extension for ActionMailer::Base to wrap mail processing with Lumberjack context.
6
+ #
7
+ # This module ensures that all logging within mailer processing is wrapped
8
+ # with the appropriate Lumberjack logger context, maintaining log consistency
9
+ # and enabling tagged logging features.
10
+ module ActionMailerExtension
11
+ # Override the process method to wrap it with Lumberjack logger context.
12
+ #
13
+ # @return [Object] the result of the original process method
14
+ def process(...)
15
+ Lumberjack::Rails.logger_context(logger) { super }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lumberjack
4
+ module Rails
5
+ # Extension for ActiveJob::Base to wrap job execution with Lumberjack context.
6
+ #
7
+ # This module ensures that all logging within job execution is wrapped
8
+ # with the appropriate Lumberjack logger context, maintaining log consistency
9
+ # and enabling tagged logging features.
10
+ module ActiveJobExtension
11
+ # Override the perform_now method to wrap it with Lumberjack logger context.
12
+ #
13
+ # @return [Object] the result of the original perform_now method
14
+ def perform_now(...)
15
+ Lumberjack::Rails.logger_context(logger) { super }
16
+ end
17
+ end
18
+ end
19
+ end