action_reporter 1.5.2 → 2.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 +4 -4
- data/CHANGELOG.md +91 -42
- data/README.md +110 -35
- data/action_reporter.gemspec +11 -5
- data/lib/action_reporter/base.rb +12 -12
- data/lib/action_reporter/current.rb +59 -0
- data/lib/action_reporter/error.rb +6 -0
- data/lib/action_reporter/plugin_discovery.rb +143 -0
- data/lib/action_reporter/sentry_reporter.rb +10 -0
- data/lib/action_reporter/version.rb +3 -0
- data/lib/action_reporter.rb +179 -25
- metadata +67 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 60e2a8fa1070b5e5c83b3437da921488a850e8e7e753d35a0fee191c5f6b3134
|
|
4
|
+
data.tar.gz: dd157cad1416a343ac6231ab0af51a90861acb840471651642991e395009a7f4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2b649899b117fc77b1ced1f5fa2979e88091fb9b3896ecdc1fccc87c8be59277727fc63c5a3da97d85b4066d09dc14bff91ae85f7a9ce77797caf9151174cff9
|
|
7
|
+
data.tar.gz: 4591b286098f6090e00484bbe1afe0145711d0d3a641a51ac6b80b335ccb29cd316537ac0ee7db3409352e1abbe6b942b8073d0aa96afb953f58d7112512ad8d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,77 +1,126 @@
|
|
|
1
|
-
#
|
|
1
|
+
# CHANGELOG
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 2.0.1 (2025-11-14)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- Fix false positives in gem version validation for git-based gems
|
|
6
|
+
- Remove strict version requirement check that caused `ConfigurationError` for valid git-based gem installations
|
|
7
|
+
- Class existence check is sufficient to ensure gem is loaded
|
|
8
|
+
- Fixes issue where `sentry-ruby` and other git-based gems were incorrectly flagged as not loaded
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
## 2.0.0 (2025-11-05)
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
- Add performance benchmarks to measure CPU, memory, and response-time impact
|
|
13
|
+
- Benchmarks wall-time overhead for context + notify + reset operations
|
|
14
|
+
- Tests with 0 to 10 reporters to show scaling behavior
|
|
15
|
+
- Shows overhead per reporter (~1.5ms per reporter on average)
|
|
16
|
+
- Helps estimate response-time impact based on number of enabled reporters
|
|
17
|
+
- BREAKING: Complete rewrite of plugin discovery system
|
|
18
|
+
- New lazy-loaded plugin discovery that auto-discovers reporters from filesystem
|
|
19
|
+
- Introduced `ActionReporter::PluginDiscovery` module for managing reporter discovery
|
|
20
|
+
- `AVAILABLE_REPORTERS` constant maintained for backward compatibility but `available_reporters` method is now preferred
|
|
21
|
+
- Plugin discovery does not block application boot - all discovery is lazy-loaded
|
|
22
|
+
- BREAKING: Thread safety changes - context attributes are now thread-safe
|
|
23
|
+
- Replace module-level instance variables with thread-local storage using `ActionReporter::Current`
|
|
24
|
+
- Context attributes (`current_user`, `current_request_uuid`, `current_remote_addr`) are now thread-safe
|
|
25
|
+
- Prevents data leakage and race conditions in multi-threaded environments
|
|
26
|
+
- Maintains API compatibility but behavior is now thread-safe
|
|
27
|
+
- Add custom reporter registration support
|
|
28
|
+
- New `ActionReporter.register_reporter(name, class_name:, require_path:)` method
|
|
29
|
+
- Allows third-party gems and applications to register custom reporters (e.g., Datadog, New Relic)
|
|
30
|
+
- Registered reporters automatically appear in `available_reporters`
|
|
31
|
+
- Supports both file-based and inline-defined reporters
|
|
32
|
+
- Add `ActionReporter.available_reporters` method to get all available reporters (discovered + registered)
|
|
33
|
+
- Add thread-safe plugin discovery with Mutex-based caching
|
|
34
|
+
- Add comprehensive error handling to all reporter methods
|
|
35
|
+
- Reporter failures no longer break the entire reporting chain
|
|
36
|
+
- Errors are logged but don't prevent other reporters from executing
|
|
37
|
+
- Added `ActionReporter.logger` for configurable error logging (defaults to `Rails.logger` if available)
|
|
38
|
+
- Added `ActionReporter.error_handler` for custom error handling callbacks
|
|
39
|
+
- Fix `reset_context` method to properly reset instance attributes (`@current_user`, `@current_request_uuid`, `@current_remote_addr`)
|
|
40
|
+
- Improve error handling in plugin discovery - gracefully handles missing files, invalid classes, and load errors
|
|
41
|
+
- Add `ActionReporter::PluginDiscovery.reset!` method for testing purposes
|
|
42
|
+
- Add thread safety tests
|
|
43
|
+
- Add error handling tests with fault isolation verification
|
|
44
|
+
- Add comprehensive plugin discovery tests
|
|
45
|
+
- Add custom reporter registration tests
|
|
46
|
+
- Achieve 100% test coverage (297/297 lines)
|
|
10
47
|
|
|
11
|
-
|
|
12
|
-
* Add `current_request_uuid` and `current_remote_addr` getters and setters
|
|
13
|
-
* Memoize `current_user`, `current_request_uuid`, and `current_remote_addr`
|
|
48
|
+
## 1.5.2 (2024-12-13)
|
|
14
49
|
|
|
15
|
-
|
|
50
|
+
- Add Audited context support
|
|
16
51
|
|
|
17
|
-
|
|
52
|
+
## 1.5.1 (2024-10-29)
|
|
18
53
|
|
|
19
|
-
|
|
54
|
+
- Fix Audited current user setter to use `audited_user`
|
|
20
55
|
|
|
21
|
-
|
|
56
|
+
## 1.5.0 (2024-10-29)
|
|
22
57
|
|
|
23
|
-
|
|
58
|
+
- BREAKING: Rename `audited_user` to `current_user`
|
|
59
|
+
- Add `current_request_uuid` and `current_remote_addr` getters and setters
|
|
60
|
+
- Memoize `current_user`, `current_request_uuid`, and `current_remote_addr`
|
|
24
61
|
|
|
25
|
-
|
|
62
|
+
## 1.4.1 (2024-02-02)
|
|
26
63
|
|
|
27
|
-
|
|
64
|
+
- Add paper_trail support
|
|
28
65
|
|
|
29
|
-
|
|
30
|
-
* Update dependencies to latest
|
|
66
|
+
## 1.4.0 (2023-08-30)
|
|
31
67
|
|
|
32
|
-
|
|
68
|
+
- Set minimum ruby version requirement to 2.5.0
|
|
33
69
|
|
|
34
|
-
|
|
35
|
-
* Implemented ActionReporter::Error class
|
|
36
|
-
* Improved test coverage
|
|
70
|
+
## 1.3.2 (2023-08-29)
|
|
37
71
|
|
|
38
|
-
|
|
72
|
+
## 1.3.1 (2023-08-29)
|
|
39
73
|
|
|
40
|
-
|
|
74
|
+
- Update gem configuration
|
|
41
75
|
|
|
42
|
-
|
|
76
|
+
## 1.3.0 (2023-08-15)
|
|
43
77
|
|
|
44
|
-
|
|
78
|
+
- Update ruby version to 3.2.2
|
|
79
|
+
- Update dependencies to latest
|
|
45
80
|
|
|
46
|
-
|
|
81
|
+
## 1.2.0 (2023-04-20)
|
|
47
82
|
|
|
48
|
-
|
|
83
|
+
- Major fixes for class resolvers
|
|
84
|
+
- Implemented ActionReporter::Error class
|
|
85
|
+
- Improved test coverage
|
|
49
86
|
|
|
50
|
-
|
|
87
|
+
## 1.1.1 (2023-04-18)
|
|
51
88
|
|
|
52
|
-
|
|
89
|
+
- Update check-in logic
|
|
53
90
|
|
|
54
|
-
|
|
91
|
+
## 1.1.0 (2023-04-18)
|
|
55
92
|
|
|
56
|
-
|
|
93
|
+
- Add reporter check-in method
|
|
57
94
|
|
|
58
|
-
|
|
95
|
+
## 1.0.7 (2023-04-18)
|
|
59
96
|
|
|
60
|
-
|
|
97
|
+
- Moving Sentry context under `context` key
|
|
61
98
|
|
|
62
|
-
|
|
99
|
+
## 1.0.6 (2023-04-18)
|
|
63
100
|
|
|
64
|
-
|
|
101
|
+
- Possible fix for Sentry context setting
|
|
65
102
|
|
|
66
|
-
|
|
103
|
+
## 1.0.5 (2023-04-18)
|
|
67
104
|
|
|
68
|
-
|
|
105
|
+
- Fix Sentry reporting and context setting
|
|
69
106
|
|
|
70
|
-
|
|
107
|
+
## 1.0.4 (2023-04-18)
|
|
71
108
|
|
|
72
|
-
|
|
73
|
-
* Update README notes
|
|
109
|
+
- Move `transform_context` to individual reporter classes
|
|
74
110
|
|
|
75
|
-
|
|
111
|
+
## 1.0.3 (2023-04-18)
|
|
76
112
|
|
|
77
|
-
|
|
113
|
+
- Fix scoutapm notice method
|
|
114
|
+
|
|
115
|
+
## 1.0.2 (2023-04-18)
|
|
116
|
+
|
|
117
|
+
- Add ruby version support for versions lower than 3.2.0
|
|
118
|
+
|
|
119
|
+
## 1.0.1 (2023-04-18)
|
|
120
|
+
|
|
121
|
+
- Fix scoutapm reset_context method
|
|
122
|
+
- Update README notes
|
|
123
|
+
|
|
124
|
+
## 1.0.0 (2023-04-18)
|
|
125
|
+
|
|
126
|
+
- Initial version
|
data/README.md
CHANGED
|
@@ -2,89 +2,163 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/action_reporter) [](https://github.com/amkisko/action_reporter.rb/actions/workflows/test.yml) [](https://codecov.io/gh/amkisko/action_reporter.rb)
|
|
4
4
|
|
|
5
|
-
[](https://app.codacy.com/gh/amkisko/action_reporter.rb/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [](https://app.codacy.com/gh/amkisko/action_reporter.rb/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage)
|
|
6
|
-
|
|
7
5
|
Ruby wrapper for multiple reporting services.
|
|
8
6
|
|
|
9
|
-
Supported services:
|
|
10
|
-
- Rails logger
|
|
11
|
-
- Audited
|
|
12
|
-
- PaperTrail
|
|
13
|
-
- Sentry
|
|
14
|
-
- Honeybadger
|
|
15
|
-
- scoutapm
|
|
7
|
+
Supported services: Rails logger, gem audited, gem PaperTrail, Sentry, Honeybadger, scoutapm.
|
|
16
8
|
|
|
17
9
|
Sponsored by [Kisko Labs](https://www.kiskolabs.com).
|
|
18
10
|
|
|
19
|
-
|
|
11
|
+
<a href="https://www.kiskolabs.com">
|
|
12
|
+
<img src="kisko.svg" width="200" alt="Sponsored by Kisko Labs" />
|
|
13
|
+
</a>
|
|
20
14
|
|
|
21
|
-
Using Bundler:
|
|
22
|
-
```sh
|
|
23
|
-
bundle add action_reporter
|
|
24
|
-
```
|
|
25
15
|
|
|
26
|
-
|
|
27
|
-
```sh
|
|
28
|
-
gem install action_reporter
|
|
29
|
-
```
|
|
16
|
+
## Installation
|
|
30
17
|
|
|
31
|
-
|
|
18
|
+
Add to your Gemfile:
|
|
32
19
|
|
|
33
20
|
```ruby
|
|
34
|
-
gem
|
|
21
|
+
gem "action_reporter"
|
|
35
22
|
```
|
|
36
23
|
|
|
24
|
+
Run `bundle install` or `gem install action_reporter`.
|
|
25
|
+
|
|
26
|
+
|
|
37
27
|
## Usage
|
|
38
28
|
|
|
39
|
-
|
|
29
|
+
Create `config/initializers/action_reporter.rb`:
|
|
40
30
|
|
|
41
31
|
```ruby
|
|
42
32
|
ActionReporter.enabled_reporters = [
|
|
43
|
-
ActionReporter::RailsReporter.new,
|
|
33
|
+
(ActionReporter::RailsReporter.new if Rails.env.development?),
|
|
44
34
|
# ActionReporter::AuditedReporter.new,
|
|
45
35
|
# ActionReporter::PaperTrailReporter.new,
|
|
46
36
|
# ActionReporter::SentryReporter.new,
|
|
47
37
|
# ActionReporter::HoneybadgerReporter.new,
|
|
48
38
|
# ActionReporter::ScoutApmReporter.new
|
|
49
|
-
]
|
|
39
|
+
].compact
|
|
50
40
|
```
|
|
51
41
|
|
|
52
|
-
|
|
42
|
+
Set context and report errors:
|
|
53
43
|
|
|
54
44
|
```ruby
|
|
55
45
|
ActionReporter.current_user = current_user
|
|
56
|
-
ActionReporter.current_request_uuid = request.env[
|
|
57
|
-
ActionReporter.current_remote_addr = request.
|
|
46
|
+
ActionReporter.current_request_uuid = request.env["action_dispatch.request_id"]
|
|
47
|
+
ActionReporter.current_remote_addr = request.remote_ip
|
|
48
|
+
|
|
58
49
|
ActionReporter.context(entry_id: entry.id)
|
|
59
|
-
ActionReporter.notify(
|
|
50
|
+
ActionReporter.notify("Something went wrong", context: { record: record })
|
|
51
|
+
ActionReporter.reset_context
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Transaction support
|
|
55
|
+
|
|
56
|
+
ActionReporter supports transaction tracking with automatic context preservation:
|
|
57
|
+
|
|
58
|
+
```ruby
|
|
59
|
+
# Attribute-style setters
|
|
60
|
+
ActionReporter.transaction_id = "txn-123"
|
|
61
|
+
ActionReporter.transaction_name = "GET /api/users"
|
|
62
|
+
|
|
63
|
+
# Block-based (preserves previous values)
|
|
64
|
+
ActionReporter.transaction(name: "GET /api/users", id: "txn-123") do
|
|
65
|
+
# Your code here
|
|
66
|
+
end
|
|
60
67
|
```
|
|
61
68
|
|
|
62
|
-
##
|
|
69
|
+
## Custom Reporters
|
|
63
70
|
|
|
64
|
-
|
|
71
|
+
Create custom reporters by inheriting from `ActionReporter::Base`:
|
|
65
72
|
|
|
66
73
|
```ruby
|
|
67
74
|
module ActionReporter
|
|
68
|
-
class
|
|
75
|
+
class CustomReporter < Base
|
|
69
76
|
def notify(error, context: {})
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
new_context = transform_context(context)
|
|
78
|
+
# Send to your service
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def context(args)
|
|
82
|
+
new_context = transform_context(args)
|
|
83
|
+
# Set context in your service
|
|
72
84
|
end
|
|
73
85
|
end
|
|
74
86
|
end
|
|
87
|
+
|
|
88
|
+
ActionReporter.enabled_reporters = [ActionReporter::CustomReporter.new]
|
|
75
89
|
```
|
|
76
90
|
|
|
91
|
+
See `doc/CUSTOM_REPORTERS.md` for detailed documentation.
|
|
92
|
+
|
|
93
|
+
## Advanced Integration
|
|
94
|
+
|
|
95
|
+
ActionReporter can be extended with custom methods and integrated with `ActiveSupport::CurrentAttributes` for automatic context propagation:
|
|
96
|
+
|
|
97
|
+
```ruby
|
|
98
|
+
module ActionReporter
|
|
99
|
+
def self.set_transaction_id(transaction_id)
|
|
100
|
+
context(transaction_id: transaction_id)
|
|
101
|
+
Sentry.set_tags(transactionId: transaction_id) if defined?(Sentry)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
class Current < ActiveSupport::CurrentAttributes
|
|
106
|
+
attribute :user, :reporter_transaction_id
|
|
107
|
+
|
|
108
|
+
def user=(user)
|
|
109
|
+
super
|
|
110
|
+
ActionReporter.current_user = user
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def reporter_transaction_id=(transaction_id)
|
|
114
|
+
super
|
|
115
|
+
ActionReporter.transaction_id = transaction_id
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## API
|
|
121
|
+
|
|
122
|
+
- `ActionReporter.enabled_reporters = [...]` - Configure enabled reporters
|
|
123
|
+
- `ActionReporter.current_user = user` - Set current user (thread-safe)
|
|
124
|
+
- `ActionReporter.current_request_uuid = uuid` - Set request UUID
|
|
125
|
+
- `ActionReporter.current_remote_addr = addr` - Set remote address
|
|
126
|
+
- `ActionReporter.context(**args)` - Set context for all reporters
|
|
127
|
+
- `ActionReporter.notify(error, context: {})` - Report errors/messages
|
|
128
|
+
- `ActionReporter.reset_context` - Reset all context
|
|
129
|
+
- `ActionReporter.transaction_id = id` - Set transaction ID
|
|
130
|
+
- `ActionReporter.transaction_name = name` - Set transaction name
|
|
131
|
+
- `ActionReporter.transaction(name:, id:, **context, &block)` - Block-based transaction with context preservation
|
|
132
|
+
- `ActionReporter.check_in(identifier)` - Heartbeat/check-in
|
|
133
|
+
- `ActionReporter.logger = logger` - Configure error logger
|
|
134
|
+
- `ActionReporter.error_handler = proc` - Configure error handler callback
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
## Development
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
bundle install
|
|
141
|
+
bundle exec appraisal generate
|
|
142
|
+
bundle exec rspec
|
|
143
|
+
bin/appraisals
|
|
144
|
+
bundle exec standardrb --fix
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
|
|
77
148
|
## Contributing
|
|
78
149
|
|
|
79
150
|
Bug reports and pull requests are welcome on GitHub at https://github.com/amkisko/action_reporter.rb
|
|
80
151
|
|
|
81
152
|
Contribution policy:
|
|
153
|
+
- New features are not necessarily added to the gem
|
|
154
|
+
- Pull request should have test coverage for affected parts
|
|
155
|
+
- Pull request should have changelog entry
|
|
156
|
+
|
|
157
|
+
Review policy:
|
|
82
158
|
- It might take up to 2 calendar weeks to review and merge critical fixes
|
|
83
159
|
- It might take up to 6 calendar months to review and merge pull request
|
|
84
160
|
- It might take up to 1 calendar year to review an issue
|
|
85
|
-
|
|
86
|
-
- Pull request should have test coverage for affected parts
|
|
87
|
-
- Pull request should have changelog entry
|
|
161
|
+
|
|
88
162
|
|
|
89
163
|
## Publishing
|
|
90
164
|
|
|
@@ -94,6 +168,7 @@ gem build action_reporter.gemspec
|
|
|
94
168
|
gem push action_reporter-*.gem
|
|
95
169
|
```
|
|
96
170
|
|
|
171
|
+
|
|
97
172
|
## License
|
|
98
173
|
|
|
99
174
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/action_reporter.gemspec
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
require_relative "lib/action_reporter/version"
|
|
2
|
+
|
|
1
3
|
Gem::Specification.new do |gem|
|
|
2
4
|
gem.name = "action_reporter"
|
|
3
|
-
gem.version =
|
|
5
|
+
gem.version = ActionReporter::VERSION
|
|
4
6
|
|
|
5
7
|
gem.license = "MIT"
|
|
6
8
|
|
|
@@ -9,7 +11,7 @@ Gem::Specification.new do |gem|
|
|
|
9
11
|
repository_url = "https://github.com/amkisko/action_reporter.rb"
|
|
10
12
|
|
|
11
13
|
gem.authors = ["Andrei Makarov"]
|
|
12
|
-
gem.email = ["
|
|
14
|
+
gem.email = ["contact@kiskolabs.com"]
|
|
13
15
|
gem.homepage = repository_url
|
|
14
16
|
gem.description = "Ruby wrapper for multiple reporting services"
|
|
15
17
|
gem.summary = "See description"
|
|
@@ -37,10 +39,14 @@ Gem::Specification.new do |gem|
|
|
|
37
39
|
gem.add_development_dependency "scout_apm", "~> 5"
|
|
38
40
|
gem.add_development_dependency "paper_trail", "~> 15"
|
|
39
41
|
|
|
42
|
+
gem.add_development_dependency "bundler", "~> 2"
|
|
40
43
|
gem.add_development_dependency "rspec", "~> 3"
|
|
41
44
|
gem.add_development_dependency "rspec_junit_formatter", "~> 0.6"
|
|
42
45
|
gem.add_development_dependency "webmock", "~> 3"
|
|
43
|
-
gem.add_development_dependency "pry", "~> 0.
|
|
44
|
-
gem.add_development_dependency "simplecov", "~> 0.
|
|
45
|
-
gem.add_development_dependency "simplecov-cobertura", "~>
|
|
46
|
+
gem.add_development_dependency "pry", "~> 0.15"
|
|
47
|
+
gem.add_development_dependency "simplecov", "~> 0.22"
|
|
48
|
+
gem.add_development_dependency "simplecov-cobertura", "~> 3"
|
|
49
|
+
gem.add_development_dependency "standard", "~> 1"
|
|
50
|
+
gem.add_development_dependency "appraisal", "~> 2"
|
|
51
|
+
gem.add_development_dependency "rbs", "~> 3"
|
|
46
52
|
end
|
data/lib/action_reporter/base.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require_relative
|
|
1
|
+
require_relative "error"
|
|
2
2
|
|
|
3
3
|
module ActionReporter
|
|
4
4
|
class Base
|
|
@@ -7,16 +7,10 @@ module ActionReporter
|
|
|
7
7
|
define_method(method_name) do
|
|
8
8
|
raise ActionReporter::Error.new("#{class_name} is not defined") unless Object.const_defined?(class_name)
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
latest_spec = Gem.loaded_specs[gem_name]
|
|
15
|
-
version_satisfied = latest_spec && Gem::Requirement.new(version).satisfied_by?(latest_spec.version)
|
|
16
|
-
raise ActionReporter::Error.new("#{gem_spec} is not loaded") if !version_satisfied
|
|
17
|
-
end
|
|
18
|
-
Object.const_get(class_name)
|
|
19
|
-
end
|
|
10
|
+
# Use instance variable instead of class variable for thread safety
|
|
11
|
+
# Each class gets its own cache, avoiding cross-class contamination
|
|
12
|
+
@class_cache ||= {}
|
|
13
|
+
@class_cache[class_name] ||= Object.const_get(class_name)
|
|
20
14
|
end
|
|
21
15
|
end
|
|
22
16
|
|
|
@@ -36,7 +30,7 @@ module ActionReporter
|
|
|
36
30
|
elsif identifier.respond_to?(:to_s)
|
|
37
31
|
identifier.to_s
|
|
38
32
|
else
|
|
39
|
-
raise
|
|
33
|
+
raise ActionReporter::Error.new("Unknown check-in identifier: #{identifier.inspect}")
|
|
40
34
|
end
|
|
41
35
|
end
|
|
42
36
|
|
|
@@ -48,5 +42,11 @@ module ActionReporter
|
|
|
48
42
|
|
|
49
43
|
def reset_context
|
|
50
44
|
end
|
|
45
|
+
|
|
46
|
+
def transaction_id=(transaction_id)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def transaction_name=(transaction_name)
|
|
50
|
+
end
|
|
51
51
|
end
|
|
52
52
|
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require_relative "error"
|
|
2
|
+
|
|
3
|
+
module ActionReporter
|
|
4
|
+
# Thread-safe storage for ActionReporter context attributes
|
|
5
|
+
# Uses Thread.current for maximum compatibility and thread safety
|
|
6
|
+
# Note: ActiveSupport::CurrentAttributes is request-scoped (not thread-scoped),
|
|
7
|
+
# so we use Thread.current for proper thread isolation
|
|
8
|
+
class Current
|
|
9
|
+
class << self
|
|
10
|
+
def current_user
|
|
11
|
+
Thread.current[:action_reporter_current_user]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def current_user=(user)
|
|
15
|
+
Thread.current[:action_reporter_current_user] = user
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def current_request_uuid
|
|
19
|
+
Thread.current[:action_reporter_current_request_uuid]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def current_request_uuid=(uuid)
|
|
23
|
+
Thread.current[:action_reporter_current_request_uuid] = uuid
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def current_remote_addr
|
|
27
|
+
Thread.current[:action_reporter_current_remote_addr]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def current_remote_addr=(addr)
|
|
31
|
+
Thread.current[:action_reporter_current_remote_addr] = addr
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def transaction_id
|
|
35
|
+
Thread.current[:action_reporter_transaction_id]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def transaction_id=(transaction_id)
|
|
39
|
+
Thread.current[:action_reporter_transaction_id] = transaction_id
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def transaction_name
|
|
43
|
+
Thread.current[:action_reporter_transaction_name]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def transaction_name=(transaction_name)
|
|
47
|
+
Thread.current[:action_reporter_transaction_name] = transaction_name
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def reset
|
|
51
|
+
Thread.current[:action_reporter_current_user] = nil
|
|
52
|
+
Thread.current[:action_reporter_current_request_uuid] = nil
|
|
53
|
+
Thread.current[:action_reporter_current_remote_addr] = nil
|
|
54
|
+
Thread.current[:action_reporter_transaction_id] = nil
|
|
55
|
+
Thread.current[:action_reporter_transaction_name] = nil
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
module ActionReporter
|
|
2
2
|
class Error < StandardError; end
|
|
3
|
+
|
|
4
|
+
# Raised when there's a configuration issue (e.g., missing gem, invalid setup)
|
|
5
|
+
class ConfigurationError < Error; end
|
|
6
|
+
|
|
7
|
+
# Raised when a reporter encounters an error during operation
|
|
8
|
+
class ReporterError < Error; end
|
|
3
9
|
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module ActionReporter
|
|
4
|
+
# Plugin discovery mechanism for auto-discovering reporters
|
|
5
|
+
# This is lazy-loaded to avoid blocking application boot
|
|
6
|
+
module PluginDiscovery
|
|
7
|
+
class << self
|
|
8
|
+
# Initialize class instance variables
|
|
9
|
+
@registered_reporters = {}
|
|
10
|
+
@discovered_reporters = nil
|
|
11
|
+
@discovery_lock = Mutex.new
|
|
12
|
+
|
|
13
|
+
# Accessors for class instance variables
|
|
14
|
+
def registered_reporters
|
|
15
|
+
@registered_reporters ||= {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
attr_reader :discovered_reporters
|
|
19
|
+
|
|
20
|
+
attr_writer :discovered_reporters
|
|
21
|
+
|
|
22
|
+
def discovery_lock
|
|
23
|
+
@discovery_lock ||= Mutex.new
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Register a reporter manually (useful for custom reporters)
|
|
27
|
+
# @param name [Symbol] Reporter name
|
|
28
|
+
# @param class_name [String] Fully qualified class name
|
|
29
|
+
# @param require_path [String] Path to require (e.g., "action_reporter/custom_reporter")
|
|
30
|
+
def register(name, class_name:, require_path:)
|
|
31
|
+
registered_reporters[name] = {
|
|
32
|
+
class_name: class_name,
|
|
33
|
+
require_path: require_path
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Discover reporters from the filesystem (lazy-loaded, cached)
|
|
38
|
+
# Only discovers files matching *_reporter.rb pattern in action_reporter/ directory
|
|
39
|
+
# @return [Array<Class>] Array of reporter classes
|
|
40
|
+
def discover
|
|
41
|
+
return discovered_reporters if discovered_reporters
|
|
42
|
+
|
|
43
|
+
discovery_lock.synchronize do
|
|
44
|
+
return discovered_reporters if discovered_reporters
|
|
45
|
+
|
|
46
|
+
self.discovered_reporters = []
|
|
47
|
+
# __dir__ is lib/action_reporter/, so we're already in the right directory
|
|
48
|
+
base_path = __dir__
|
|
49
|
+
|
|
50
|
+
# Discover built-in reporters
|
|
51
|
+
Dir.glob(File.join(base_path, "*_reporter.rb")).each do |file|
|
|
52
|
+
reporter_class = discover_reporter_from_file(file)
|
|
53
|
+
discovered_reporters << reporter_class if reporter_class
|
|
54
|
+
rescue => e
|
|
55
|
+
# Silently skip files that can't be loaded (non-blocking)
|
|
56
|
+
warn "ActionReporter: Failed to discover reporter from #{file}: #{e.message}" if logger
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
self.discovered_reporters = discovered_reporters.freeze
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Get all available reporters (discovered + registered)
|
|
64
|
+
# @return [Array<Class>] Array of reporter classes
|
|
65
|
+
def available_reporters
|
|
66
|
+
reporters = discover.dup
|
|
67
|
+
|
|
68
|
+
# Add registered reporters (lazy-loaded)
|
|
69
|
+
registered_reporters.each_value do |config|
|
|
70
|
+
reporter_class = load_registered_reporter(config)
|
|
71
|
+
reporters << reporter_class if reporter_class
|
|
72
|
+
rescue => e
|
|
73
|
+
# Silently skip registered reporters that can't be loaded (non-blocking)
|
|
74
|
+
warn "ActionReporter: Failed to load registered reporter #{config[:class_name]}: #{e.message}" if logger
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
reporters.uniq.freeze
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Reset discovery cache (useful for testing)
|
|
81
|
+
def reset!
|
|
82
|
+
discovery_lock.synchronize do
|
|
83
|
+
self.discovered_reporters = nil
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
def discover_reporter_from_file(file_path)
|
|
90
|
+
base_name = File.basename(file_path, ".rb")
|
|
91
|
+
|
|
92
|
+
# Convert snake_case to PascalCase
|
|
93
|
+
# e.g., "scout_apm_reporter" -> "ScoutApmReporter"
|
|
94
|
+
# e.g., "rails_reporter" -> "RailsReporter"
|
|
95
|
+
class_name = base_name
|
|
96
|
+
.split("_")
|
|
97
|
+
.map(&:capitalize)
|
|
98
|
+
.join
|
|
99
|
+
|
|
100
|
+
full_class_name = "ActionReporter::#{class_name}"
|
|
101
|
+
|
|
102
|
+
# Check if class is already defined (files are pre-required at boot)
|
|
103
|
+
return nil unless Object.const_defined?(full_class_name)
|
|
104
|
+
|
|
105
|
+
klass = Object.const_get(full_class_name)
|
|
106
|
+
return nil unless klass < Base
|
|
107
|
+
|
|
108
|
+
klass
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def load_registered_reporter(config)
|
|
112
|
+
# Check if class is already defined (e.g., in tests or already loaded)
|
|
113
|
+
return nil unless Object.const_defined?(config[:class_name])
|
|
114
|
+
|
|
115
|
+
klass = Object.const_get(config[:class_name])
|
|
116
|
+
return nil unless klass < Base
|
|
117
|
+
|
|
118
|
+
# Only require if class is not already available and require_path is provided
|
|
119
|
+
# This allows classes defined inline (e.g., in tests) to work without requiring files
|
|
120
|
+
if config[:require_path] && !required?(config[:require_path])
|
|
121
|
+
begin
|
|
122
|
+
require config[:require_path]
|
|
123
|
+
rescue LoadError => e
|
|
124
|
+
# If file doesn't exist but class is already defined, that's okay
|
|
125
|
+
# (e.g., class defined inline in tests or already loaded)
|
|
126
|
+
warn "ActionReporter: Could not require #{config[:require_path]}: #{e.message}" if logger
|
|
127
|
+
# Continue - class might already be defined
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
klass
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def required?(path)
|
|
135
|
+
$LOADED_FEATURES.any? { |feature| feature.include?(path) }
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def logger
|
|
139
|
+
ActionReporter.logger
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -25,5 +25,15 @@ module ActionReporter
|
|
|
25
25
|
def current_user=(user)
|
|
26
26
|
sentry_class.set_user(user_global_id: user&.to_global_id&.to_s)
|
|
27
27
|
end
|
|
28
|
+
|
|
29
|
+
def transaction_id=(transaction_id)
|
|
30
|
+
sentry_class.set_tags(transactionId: transaction_id)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def transaction_name=(transaction_name)
|
|
34
|
+
sentry_class.configure_scope do |scope|
|
|
35
|
+
scope.set_transaction_name(transaction_name)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
28
38
|
end
|
|
29
39
|
end
|
data/lib/action_reporter.rb
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
require "action_reporter/version"
|
|
2
|
+
require "action_reporter/utils"
|
|
3
|
+
require "action_reporter/base"
|
|
4
|
+
require "action_reporter/current"
|
|
5
|
+
require "action_reporter/plugin_discovery"
|
|
6
|
+
|
|
7
|
+
# Core reporters are still required for backward compatibility
|
|
8
|
+
# But discovery mechanism allows for lazy loading and custom reporters
|
|
9
|
+
require "action_reporter/rails_reporter"
|
|
10
|
+
require "action_reporter/honeybadger_reporter"
|
|
11
|
+
require "action_reporter/sentry_reporter"
|
|
12
|
+
require "action_reporter/scout_apm_reporter"
|
|
13
|
+
require "action_reporter/audited_reporter"
|
|
14
|
+
require "action_reporter/paper_trail_reporter"
|
|
9
15
|
|
|
10
16
|
module ActionReporter
|
|
11
17
|
module_function
|
|
12
18
|
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
# Legacy hardcoded list (maintained for backward compatibility)
|
|
20
|
+
# Use `available_reporters` for auto-discovered reporters
|
|
15
21
|
AVAILABLE_REPORTERS = [
|
|
16
22
|
ActionReporter::RailsReporter,
|
|
17
23
|
ActionReporter::HoneybadgerReporter,
|
|
@@ -21,76 +27,163 @@ module ActionReporter
|
|
|
21
27
|
ActionReporter::PaperTrailReporter
|
|
22
28
|
].freeze
|
|
23
29
|
|
|
30
|
+
# Get available reporters (auto-discovered + registered)
|
|
31
|
+
# This is lazy-loaded and does not block application boot
|
|
32
|
+
# @return [Array<Class>] Array of reporter classes
|
|
33
|
+
def available_reporters
|
|
34
|
+
PluginDiscovery.available_reporters
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Register a custom reporter
|
|
38
|
+
# This allows third-party gems or custom code to register reporters
|
|
39
|
+
# @param name [Symbol] Reporter name
|
|
40
|
+
# @param class_name [String] Fully qualified class name
|
|
41
|
+
# @param require_path [String] Path to require
|
|
42
|
+
# @example
|
|
43
|
+
# ActionReporter.register_reporter(:custom, class_name: "MyApp::CustomReporter", require_path: "my_app/custom_reporter")
|
|
44
|
+
def register_reporter(name, class_name:, require_path:)
|
|
45
|
+
PluginDiscovery.register(name, class_name: class_name, require_path: require_path)
|
|
46
|
+
end
|
|
47
|
+
|
|
24
48
|
@enabled_reporters = []
|
|
49
|
+
@logger = nil
|
|
50
|
+
@error_handler = nil
|
|
25
51
|
|
|
26
52
|
def enabled_reporters=(reporters)
|
|
27
|
-
@enabled_reporters = reporters
|
|
53
|
+
@enabled_reporters = reporters || []
|
|
28
54
|
end
|
|
29
55
|
|
|
30
56
|
def enabled_reporters
|
|
31
|
-
@enabled_reporters
|
|
57
|
+
@enabled_reporters || []
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def logger
|
|
61
|
+
@logger || ((defined?(Rails) && Rails.respond_to?(:logger)) ? Rails.logger : nil)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def logger=(logger)
|
|
65
|
+
@logger = logger
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def error_handler
|
|
69
|
+
@error_handler
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def error_handler=(handler)
|
|
73
|
+
@error_handler = handler
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def handle_reporter_error(reporter, error, method_name)
|
|
77
|
+
error_message = "ActionReporter: #{reporter.class}##{method_name} failed: #{error.class} - #{error.message}"
|
|
78
|
+
|
|
79
|
+
if logger
|
|
80
|
+
logger.error(error_message)
|
|
81
|
+
logger.debug(error.backtrace.join("\n")) if error.backtrace
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
if error_handler&.respond_to?(:call)
|
|
85
|
+
error_handler.call(error, reporter, method_name)
|
|
86
|
+
end
|
|
87
|
+
rescue => e
|
|
88
|
+
# If error handling itself fails, log to stderr as last resort
|
|
89
|
+
warn "ActionReporter: Error handler failed: #{e.message}"
|
|
32
90
|
end
|
|
33
91
|
|
|
34
92
|
def notify(error, context: {})
|
|
35
93
|
enabled_reporters.each do |reporter|
|
|
36
94
|
next unless reporter.respond_to?(:notify)
|
|
37
95
|
|
|
38
|
-
|
|
96
|
+
begin
|
|
97
|
+
reporter.notify(error, context: context)
|
|
98
|
+
rescue => e
|
|
99
|
+
handle_reporter_error(reporter, e, "notify")
|
|
100
|
+
end
|
|
39
101
|
end
|
|
40
102
|
end
|
|
41
103
|
|
|
42
104
|
def context(args)
|
|
105
|
+
raise ArgumentError, "context must be a Hash" unless args.is_a?(Hash)
|
|
106
|
+
|
|
43
107
|
enabled_reporters.each do |reporter|
|
|
44
108
|
next unless reporter.respond_to?(:context)
|
|
45
109
|
|
|
46
|
-
|
|
110
|
+
begin
|
|
111
|
+
reporter.context(args)
|
|
112
|
+
rescue => e
|
|
113
|
+
handle_reporter_error(reporter, e, "context")
|
|
114
|
+
end
|
|
47
115
|
end
|
|
48
116
|
end
|
|
49
117
|
|
|
50
118
|
def reset_context
|
|
119
|
+
Current.current_user = nil
|
|
120
|
+
Current.current_request_uuid = nil
|
|
121
|
+
Current.current_remote_addr = nil
|
|
122
|
+
Current.transaction_id = nil
|
|
123
|
+
Current.transaction_name = nil
|
|
124
|
+
|
|
51
125
|
enabled_reporters.each do |reporter|
|
|
52
126
|
next unless reporter.respond_to?(:reset_context)
|
|
53
127
|
|
|
54
|
-
|
|
128
|
+
begin
|
|
129
|
+
reporter.reset_context
|
|
130
|
+
rescue => e
|
|
131
|
+
handle_reporter_error(reporter, e, "reset_context")
|
|
132
|
+
end
|
|
55
133
|
end
|
|
134
|
+
|
|
135
|
+
# Reset Current attributes if supported
|
|
136
|
+
Current.reset if Current.respond_to?(:reset)
|
|
56
137
|
end
|
|
57
138
|
|
|
58
139
|
def current_user
|
|
59
|
-
|
|
140
|
+
Current.current_user
|
|
60
141
|
end
|
|
61
142
|
|
|
62
143
|
def current_user=(user)
|
|
63
|
-
|
|
144
|
+
Current.current_user = user
|
|
64
145
|
enabled_reporters.each do |reporter|
|
|
65
146
|
next unless reporter.respond_to?(:current_user=)
|
|
66
147
|
|
|
67
|
-
|
|
148
|
+
begin
|
|
149
|
+
reporter.current_user = user
|
|
150
|
+
rescue => e
|
|
151
|
+
handle_reporter_error(reporter, e, "current_user=")
|
|
152
|
+
end
|
|
68
153
|
end
|
|
69
154
|
end
|
|
70
155
|
|
|
71
156
|
def current_request_uuid
|
|
72
|
-
|
|
157
|
+
Current.current_request_uuid
|
|
73
158
|
end
|
|
74
159
|
|
|
75
160
|
def current_request_uuid=(request_uuid)
|
|
76
|
-
|
|
161
|
+
Current.current_request_uuid = request_uuid
|
|
77
162
|
enabled_reporters.each do |reporter|
|
|
78
163
|
next unless reporter.respond_to?(:current_request_uuid=)
|
|
79
164
|
|
|
80
|
-
|
|
165
|
+
begin
|
|
166
|
+
reporter.current_request_uuid = request_uuid
|
|
167
|
+
rescue => e
|
|
168
|
+
handle_reporter_error(reporter, e, "current_request_uuid=")
|
|
169
|
+
end
|
|
81
170
|
end
|
|
82
171
|
end
|
|
83
172
|
|
|
84
173
|
def current_remote_addr
|
|
85
|
-
|
|
174
|
+
Current.current_remote_addr
|
|
86
175
|
end
|
|
87
176
|
|
|
88
177
|
def current_remote_addr=(remote_addr)
|
|
89
|
-
|
|
178
|
+
Current.current_remote_addr = remote_addr
|
|
90
179
|
enabled_reporters.each do |reporter|
|
|
91
180
|
next unless reporter.respond_to?(:current_remote_addr=)
|
|
92
181
|
|
|
93
|
-
|
|
182
|
+
begin
|
|
183
|
+
reporter.current_remote_addr = remote_addr
|
|
184
|
+
rescue => e
|
|
185
|
+
handle_reporter_error(reporter, e, "current_remote_addr=")
|
|
186
|
+
end
|
|
94
187
|
end
|
|
95
188
|
end
|
|
96
189
|
|
|
@@ -98,7 +191,68 @@ module ActionReporter
|
|
|
98
191
|
enabled_reporters.each do |reporter|
|
|
99
192
|
next unless reporter.respond_to?(:check_in)
|
|
100
193
|
|
|
101
|
-
|
|
194
|
+
begin
|
|
195
|
+
reporter.check_in(identifier)
|
|
196
|
+
rescue => e
|
|
197
|
+
handle_reporter_error(reporter, e, "check_in")
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def transaction_id
|
|
203
|
+
Current.transaction_id
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def transaction_id=(transaction_id)
|
|
207
|
+
Current.transaction_id = transaction_id
|
|
208
|
+
context(transaction_id: transaction_id)
|
|
209
|
+
|
|
210
|
+
enabled_reporters.each do |reporter|
|
|
211
|
+
next unless reporter.respond_to?(:transaction_id=)
|
|
212
|
+
|
|
213
|
+
begin
|
|
214
|
+
reporter.transaction_id = transaction_id
|
|
215
|
+
rescue => e
|
|
216
|
+
handle_reporter_error(reporter, e, "transaction_id=")
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def transaction_name
|
|
222
|
+
Current.transaction_name
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def transaction_name=(transaction_name)
|
|
226
|
+
Current.transaction_name = transaction_name
|
|
227
|
+
context(transaction_name: transaction_name)
|
|
228
|
+
|
|
229
|
+
enabled_reporters.each do |reporter|
|
|
230
|
+
next unless reporter.respond_to?(:transaction_name=)
|
|
231
|
+
|
|
232
|
+
begin
|
|
233
|
+
reporter.transaction_name = transaction_name
|
|
234
|
+
rescue => e
|
|
235
|
+
handle_reporter_error(reporter, e, "transaction_name=")
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def transaction(name: nil, id: nil, **context_options, &block)
|
|
241
|
+
raise ArgumentError, "transaction requires a block" unless block_given?
|
|
242
|
+
|
|
243
|
+
previous_name = transaction_name
|
|
244
|
+
previous_id = transaction_id
|
|
245
|
+
|
|
246
|
+
begin
|
|
247
|
+
self.transaction_name = name if name
|
|
248
|
+
self.transaction_id = id if id
|
|
249
|
+
|
|
250
|
+
context(context_options) if context_options.any?
|
|
251
|
+
|
|
252
|
+
block.call
|
|
253
|
+
ensure
|
|
254
|
+
self.transaction_name = previous_name if name
|
|
255
|
+
self.transaction_id = previous_id if id
|
|
102
256
|
end
|
|
103
257
|
end
|
|
104
258
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: action_reporter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrei Makarov
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rails
|
|
@@ -94,6 +93,20 @@ dependencies:
|
|
|
94
93
|
- - "~>"
|
|
95
94
|
- !ruby/object:Gem::Version
|
|
96
95
|
version: '15'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: bundler
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '2'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '2'
|
|
97
110
|
- !ruby/object:Gem::Dependency
|
|
98
111
|
name: rspec
|
|
99
112
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -142,30 +155,58 @@ dependencies:
|
|
|
142
155
|
requirements:
|
|
143
156
|
- - "~>"
|
|
144
157
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: '0.
|
|
158
|
+
version: '0.15'
|
|
146
159
|
type: :development
|
|
147
160
|
prerelease: false
|
|
148
161
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
162
|
requirements:
|
|
150
163
|
- - "~>"
|
|
151
164
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: '0.
|
|
165
|
+
version: '0.15'
|
|
153
166
|
- !ruby/object:Gem::Dependency
|
|
154
167
|
name: simplecov
|
|
155
168
|
requirement: !ruby/object:Gem::Requirement
|
|
156
169
|
requirements:
|
|
157
170
|
- - "~>"
|
|
158
171
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: '0.
|
|
172
|
+
version: '0.22'
|
|
160
173
|
type: :development
|
|
161
174
|
prerelease: false
|
|
162
175
|
version_requirements: !ruby/object:Gem::Requirement
|
|
163
176
|
requirements:
|
|
164
177
|
- - "~>"
|
|
165
178
|
- !ruby/object:Gem::Version
|
|
166
|
-
version: '0.
|
|
179
|
+
version: '0.22'
|
|
167
180
|
- !ruby/object:Gem::Dependency
|
|
168
181
|
name: simplecov-cobertura
|
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - "~>"
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '3'
|
|
187
|
+
type: :development
|
|
188
|
+
prerelease: false
|
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
190
|
+
requirements:
|
|
191
|
+
- - "~>"
|
|
192
|
+
- !ruby/object:Gem::Version
|
|
193
|
+
version: '3'
|
|
194
|
+
- !ruby/object:Gem::Dependency
|
|
195
|
+
name: standard
|
|
196
|
+
requirement: !ruby/object:Gem::Requirement
|
|
197
|
+
requirements:
|
|
198
|
+
- - "~>"
|
|
199
|
+
- !ruby/object:Gem::Version
|
|
200
|
+
version: '1'
|
|
201
|
+
type: :development
|
|
202
|
+
prerelease: false
|
|
203
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
204
|
+
requirements:
|
|
205
|
+
- - "~>"
|
|
206
|
+
- !ruby/object:Gem::Version
|
|
207
|
+
version: '1'
|
|
208
|
+
- !ruby/object:Gem::Dependency
|
|
209
|
+
name: appraisal
|
|
169
210
|
requirement: !ruby/object:Gem::Requirement
|
|
170
211
|
requirements:
|
|
171
212
|
- - "~>"
|
|
@@ -178,9 +219,23 @@ dependencies:
|
|
|
178
219
|
- - "~>"
|
|
179
220
|
- !ruby/object:Gem::Version
|
|
180
221
|
version: '2'
|
|
222
|
+
- !ruby/object:Gem::Dependency
|
|
223
|
+
name: rbs
|
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
|
225
|
+
requirements:
|
|
226
|
+
- - "~>"
|
|
227
|
+
- !ruby/object:Gem::Version
|
|
228
|
+
version: '3'
|
|
229
|
+
type: :development
|
|
230
|
+
prerelease: false
|
|
231
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
232
|
+
requirements:
|
|
233
|
+
- - "~>"
|
|
234
|
+
- !ruby/object:Gem::Version
|
|
235
|
+
version: '3'
|
|
181
236
|
description: Ruby wrapper for multiple reporting services
|
|
182
237
|
email:
|
|
183
|
-
-
|
|
238
|
+
- contact@kiskolabs.com
|
|
184
239
|
executables: []
|
|
185
240
|
extensions: []
|
|
186
241
|
extra_rdoc_files: []
|
|
@@ -192,13 +247,16 @@ files:
|
|
|
192
247
|
- lib/action_reporter.rb
|
|
193
248
|
- lib/action_reporter/audited_reporter.rb
|
|
194
249
|
- lib/action_reporter/base.rb
|
|
250
|
+
- lib/action_reporter/current.rb
|
|
195
251
|
- lib/action_reporter/error.rb
|
|
196
252
|
- lib/action_reporter/honeybadger_reporter.rb
|
|
197
253
|
- lib/action_reporter/paper_trail_reporter.rb
|
|
254
|
+
- lib/action_reporter/plugin_discovery.rb
|
|
198
255
|
- lib/action_reporter/rails_reporter.rb
|
|
199
256
|
- lib/action_reporter/scout_apm_reporter.rb
|
|
200
257
|
- lib/action_reporter/sentry_reporter.rb
|
|
201
258
|
- lib/action_reporter/utils.rb
|
|
259
|
+
- lib/action_reporter/version.rb
|
|
202
260
|
homepage: https://github.com/amkisko/action_reporter.rb
|
|
203
261
|
licenses:
|
|
204
262
|
- MIT
|
|
@@ -208,7 +266,6 @@ metadata:
|
|
|
208
266
|
bug_tracker_uri: https://github.com/amkisko/action_reporter.rb/issues
|
|
209
267
|
changelog_uri: https://github.com/amkisko/action_reporter.rb/blob/main/CHANGELOG.md
|
|
210
268
|
rubygems_mfa_required: 'true'
|
|
211
|
-
post_install_message:
|
|
212
269
|
rdoc_options: []
|
|
213
270
|
require_paths:
|
|
214
271
|
- lib
|
|
@@ -223,8 +280,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
223
280
|
- !ruby/object:Gem::Version
|
|
224
281
|
version: '0'
|
|
225
282
|
requirements: []
|
|
226
|
-
rubygems_version: 3.
|
|
227
|
-
signing_key:
|
|
283
|
+
rubygems_version: 3.6.9
|
|
228
284
|
specification_version: 4
|
|
229
285
|
summary: See description
|
|
230
286
|
test_files: []
|