action_reporter 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: d04726ad07e0a3930895a3f5f50c570cee75636ba92aa13d142f1d45c84c2812
4
+ data.tar.gz: 12a7b129dda548f8dca465a2d406b8d6982c4bc34fd8259edafe57451c8cfe07
5
+ SHA512:
6
+ metadata.gz: 35b4f4953e373d8c45d29a250dc0e0d4ee53b4a6aab4121c779ecc1090d669059c26da764562ff360e5f6e540ced4b8de9d347cfa10dc8e71650ac816ead214b
7
+ data.tar.gz: 65ea44fc78c36bb0227ad930ff737060b1c6188ebb237a6d5adbc1b13504a91886cd38a7694a64ce1205973525af93e5d95f02e79376f10207271fb95c0d7c1b
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # 1.0.0
2
+
3
+ * Initial version
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 amkisko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # action_reporter
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/action_reporter.svg)](https://badge.fury.io/rb/action_reporter) [![Test Status](https://github.com/amkisko/action_reporter/actions/workflows/test.yml/badge.svg)](https://github.com/amkisko/action_reporter/actions/workflows/test.yml)
4
+
5
+ Ruby wrapper for multiple reporting services.
6
+
7
+ Supported services:
8
+ - Rails logger
9
+ - Audited
10
+ - Sentry
11
+ - Honeybadger
12
+ - scoutapm
13
+
14
+ Sponsored by [Kisko Labs](https://www.kiskolabs.com).
15
+
16
+ ## Install
17
+
18
+ Using Bundler:
19
+ ```sh
20
+ bundle add action_reporter
21
+ ```
22
+
23
+ Using RubyGems:
24
+ ```sh
25
+ gem install action_reporter
26
+ ```
27
+
28
+ ## Gemfile
29
+
30
+ ```ruby
31
+ gem 'action_reporter'
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ Put this in your `config/initializers/action_reporter.rb` file:
37
+
38
+ ```ruby
39
+ ActionReporter.enabled_reporters = [
40
+ ActionReporter::Reporters::RailsReporter.new,
41
+ # ActionReporter::Reporters::AuditedReporter.new,
42
+ # ActionReporter::Reporters::SentryReporter.new,
43
+ # ActionReporter::Reporters::HoneybadgerReporter.new,
44
+ # ActionReporter::Reporters::ScoutApmReporter.new
45
+ ]
46
+ ```
47
+
48
+ Then you can use it in your code:
49
+
50
+ ```ruby
51
+ ActionReporter.context(audited_user: current_user)
52
+ ActionReporter.notify('Something went wrong', context: { record: record })
53
+ ```
54
+
55
+ ## Contributing
56
+
57
+ Bug reports and pull requests are welcome on GitHub at https://github.com/amkisko/action_reporter
58
+
59
+ ## Publishing
60
+
61
+ ```sh
62
+ rm action_reporter-*.gem
63
+ gem build action_reporter.gemspec
64
+ gem push action_reporter-*.gem
65
+ ```
66
+
67
+ ## License
68
+
69
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,29 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "action_reporter"
3
+ s.version = "1.0.0"
4
+
5
+ s.license = "MIT"
6
+
7
+ s.platform = Gem::Platform::RUBY
8
+
9
+ s.authors = ["Andrei Makarov"]
10
+ s.email = ["andrei@kiskolabs.com"]
11
+ s.homepage = "https://github.com/amkisko/action_reporter"
12
+ s.description = "Ruby wrapper for multiple reporting services"
13
+ s.summary = "See description"
14
+ s.metadata = {
15
+ "homepage" => "https://github.com/amkisko/action_reporter",
16
+ "source_code_uri" => "https://github.com/amkisko/action_reporter",
17
+ "bug_tracker_uri" => "https://github.com/amkisko/action_reporter/issues",
18
+ "changelog_uri" => "https://github.com/amkisko/action_reporter/blob/main/CHANGELOG.md",
19
+ "rubygems_mfa_required" => "true"
20
+ }
21
+
22
+ s.files = Dir.glob("lib/**/*.rb") + Dir.glob("bin/**/*") + %w(CHANGELOG.md LICENSE.md README.md action_reporter.gemspec)
23
+
24
+ # s.bindir = "bin"
25
+ # s.executables = ["action_reporter"]
26
+
27
+ s.required_ruby_version = ">= 3.2.0"
28
+ s.require_path = "lib"
29
+ end
@@ -0,0 +1,30 @@
1
+ module ActionReporter
2
+ class AuditedReporter < Base
3
+ class_accessor "Audited"
4
+
5
+ def transform_context?
6
+ false
7
+ end
8
+
9
+ def notify(*)
10
+ end
11
+
12
+ def context(args)
13
+ Audited.store[:current_remote_address] = args[:remote_addr] if args[
14
+ :remote_addr
15
+ ].present?
16
+ Audited.store[:audited_user] = args[:audited_user] if args[
17
+ :audited_user
18
+ ].present?
19
+ end
20
+
21
+ def reset_context
22
+ Audited.store.delete(:current_remote_address)
23
+ Audited.store.delete(:audited_user)
24
+ end
25
+
26
+ def audited_user
27
+ Audited.store[:audited_user]
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ module ActionReporter
2
+ class Base
3
+ def self.class_accessor(class_name)
4
+ return unless Object.const_defined?(class_name)
5
+
6
+ const_name = class_name.gsub("::", "")
7
+ const_set(const_name, Object.const_get(class_name))
8
+ end
9
+
10
+ def transform_context?
11
+ true
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module ActionReporter
2
+ class HoneybadgerReporter < Base
3
+ class_accessor "Honeybadger"
4
+
5
+ def notify(error, context: {})
6
+ Honeybadger.notify(error, context: context)
7
+ end
8
+
9
+ def context(args)
10
+ Honeybadger.context(args)
11
+ end
12
+
13
+ def reset_context
14
+ Honeybadger.context.clear!
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module ActionReporter
2
+ class RailsReporter < Base
3
+ class_accessor "Rails"
4
+
5
+ def notify(error, context: {})
6
+ Rails.logger.info(
7
+ "Reporter notification: #{error.inspect}, #{context.inspect}"
8
+ )
9
+ end
10
+
11
+ def context(args)
12
+ Rails.logger.info("Reporter context: #{args.inspect}")
13
+ end
14
+
15
+ def reset_context
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ module ActionReporter
2
+ class ScoutApmReporter < Base
3
+ class_accessor "ScoutApm::Agent"
4
+ class_accessor "ScoutApm::Context"
5
+
6
+ def notify(*args, **kwargs)
7
+ ScoutApmAgent.instance.error(*args, **kwargs)
8
+ end
9
+
10
+ def context(args)
11
+ if args[:audited_user].present?
12
+ ScoutApmContext.add_user(
13
+ audited_user_global_id: args[:audited_user].to_global_id
14
+ )
15
+ end
16
+ ScoutApmContext.add(args)
17
+ end
18
+
19
+ def reset_context
20
+ ScoutApmContext.clear!
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module ActionReporter
2
+ class SentryReporter < Base
3
+ class_accessor "Sentry"
4
+
5
+ def notify(error, context: {})
6
+ self.context(context)
7
+ Sentry.capture_exception(error)
8
+ end
9
+
10
+ def context(args)
11
+ args.each do |key, value|
12
+ Sentry.configure_scope { |scope| scope.set_context(key, value) }
13
+ end
14
+ end
15
+
16
+ def reset_context
17
+ Sentry.configure_scope { |scope| scope.clear_breadcrumbs }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module ActionReporter
2
+ module Utils
3
+ module_function
4
+
5
+ def deep_transform_values(hash, &block)
6
+ hash.each_with_object({}) do |(k, v), result|
7
+ value = if v.is_a?(Hash)
8
+ deep_transform_values(v, &block)
9
+ elsif v.is_a?(Array)
10
+ v.map { |e| e.is_a?(Hash) ? deep_transform_values(e, &block) : e }
11
+ else
12
+ v
13
+ end
14
+
15
+ result[k] = block.call(value)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module ActionReporter
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,63 @@
1
+ require 'action_reporter/version'
2
+ require 'action_reporter/utils'
3
+ require 'action_reporter/base'
4
+ require 'action_reporter/rails_reporter'
5
+ require 'action_reporter/honeybadger_reporter'
6
+ require 'action_reporter/sentry_reporter'
7
+ require 'action_reporter/scout_apm_reporter'
8
+ require 'action_reporter/audited_reporter'
9
+
10
+ module ActionReporter
11
+ module_function
12
+
13
+ AVAILABLE_REPORTERS = [
14
+ ActionReporter::RailsReporter,
15
+ ActionReporter::HoneybadgerReporter,
16
+ ActionReporter::SentryReporter,
17
+ ActionReporter::ScoutApmReporter,
18
+ ActionReporter::AuditedReporter
19
+ ].freeze
20
+
21
+ @enabled_reporters = []
22
+
23
+ def enabled_reporters=(reporters)
24
+ @enabled_reporters = reporters
25
+ end
26
+
27
+ def enabled_reporters
28
+ @enabled_reporters
29
+ end
30
+
31
+ def notify(error, context: {})
32
+ enabled_reporters.each do |reporter|
33
+ new_context =
34
+ reporter.transform_context? ? transform_context(context) : context
35
+ reporter.notify(error, context: new_context)
36
+ end
37
+ end
38
+
39
+ def context(args)
40
+ enabled_reporters.each do |reporter|
41
+ new_args = reporter.transform_context? ? transform_context(args) : args
42
+ reporter.context(new_args)
43
+ end
44
+ end
45
+
46
+ def reset_context
47
+ enabled_reporters.each(&:reset_context)
48
+ end
49
+
50
+ def audited_user
51
+ enabled_reporters.find { |r| r.respond_to?(:audited_user) }&.audited_user
52
+ end
53
+
54
+ def transform_context(context)
55
+ ActionReporter::Utils.deep_transform_values(context.except(:audited_user)) do |value|
56
+ if value.respond_to?(:to_global_id)
57
+ value.to_global_id.to_s
58
+ else
59
+ value
60
+ end
61
+ end
62
+ end
63
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: action_reporter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrei Makarov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-04-18 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Ruby wrapper for multiple reporting services
14
+ email:
15
+ - andrei@kiskolabs.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - CHANGELOG.md
21
+ - LICENSE.md
22
+ - README.md
23
+ - action_reporter.gemspec
24
+ - lib/action_reporter.rb
25
+ - lib/action_reporter/audited_reporter.rb
26
+ - lib/action_reporter/base.rb
27
+ - lib/action_reporter/honeybadger_reporter.rb
28
+ - lib/action_reporter/rails_reporter.rb
29
+ - lib/action_reporter/scout_apm_reporter.rb
30
+ - lib/action_reporter/sentry_reporter.rb
31
+ - lib/action_reporter/utils.rb
32
+ - lib/action_reporter/version.rb
33
+ homepage: https://github.com/amkisko/action_reporter
34
+ licenses:
35
+ - MIT
36
+ metadata:
37
+ homepage: https://github.com/amkisko/action_reporter
38
+ source_code_uri: https://github.com/amkisko/action_reporter
39
+ bug_tracker_uri: https://github.com/amkisko/action_reporter/issues
40
+ changelog_uri: https://github.com/amkisko/action_reporter/blob/main/CHANGELOG.md
41
+ rubygems_mfa_required: 'true'
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 3.2.0
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubygems_version: 3.3.3
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: See description
61
+ test_files: []