technologic 0.6.3 → 0.6.4
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/README.md +26 -4
- data/lib/generators/technologic/initializer/USAGE +8 -0
- data/lib/generators/technologic/initializer/initializer_generator.rb +13 -0
- data/lib/generators/technologic/initializer/templates/initializer.rb.erb +74 -0
- data/lib/json_log_converter.rb +46 -0
- data/lib/technologic.rb +2 -0
- data/lib/technologic/config_options.rb +0 -2
- data/lib/technologic/setup.rb +0 -5
- data/lib/technologic/shared_examples.rb +12 -0
- data/lib/technologic/shared_examples/a_debug_event_is_logged.rb +32 -0
- data/lib/technologic/shared_examples/a_fatal_event_is_logged.rb +32 -0
- data/lib/technologic/shared_examples/a_logged_event_with_severity.rb +32 -0
- data/lib/technologic/shared_examples/a_surveiled_event.rb +42 -0
- data/lib/technologic/shared_examples/a_warn_event_is_logged.rb +32 -0
- data/lib/technologic/shared_examples/an_error_event_is_logged.rb +32 -0
- data/lib/technologic/shared_examples/an_info_event_is_logged.rb +32 -0
- data/lib/technologic/shared_examples/an_instrumented_error_exception.rb +31 -0
- data/lib/technologic/shared_examples/an_instrumented_exception_with_severity.rb +44 -0
- data/lib/technologic/shared_examples/an_instrumented_fatal_exception.rb +31 -0
- data/lib/technologic/spec_helper.rb +3 -0
- data/lib/technologic/version.rb +1 -1
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: baaef725c4fcecbabe7a4b884cca555d444d1d127da3d359534486ed6704cfe8
|
4
|
+
data.tar.gz: 3eda1c0eb2ffbc45fc6076863f524dcb102c2451b1dbe03cf6823f87e204cbfc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38ec48be6eb419ab8b163c1a668e903783e1e70db56cde77a61c55ad67969f601de5aa402319b2b5d5d2dfb11cac95480b44e162837b2e613fecc2649a8bbdd8
|
7
|
+
data.tar.gz: 1a64a64b011dbad32f913ecda755714d9f2b57b6ec921fb87cb42566a3c62cb3fed788c83283cadb83ae4e7daee0cbb44e206184841ed117423494b31b6bc7df
|
data/README.md
CHANGED
@@ -5,9 +5,11 @@
|
|
5
5
|
[](https://codeclimate.com/github/Freshly/spicerack/maintainability)
|
6
6
|
[](https://codeclimate.com/github/Freshly/spicerack/test_coverage)
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
* [Installation](#installation)
|
9
|
+
* [Usage](#usage)
|
10
|
+
* [Development](#development)
|
11
|
+
* [Contributing](#contributing)
|
12
|
+
* [License](#license)
|
11
13
|
|
12
14
|
## Installation
|
13
15
|
|
@@ -27,7 +29,27 @@ Or install it yourself as:
|
|
27
29
|
|
28
30
|
## Usage
|
29
31
|
|
30
|
-
|
32
|
+
Simply write the error class, the message as a symbol, and then as a hash anything else you want to see in the logs.
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
error :ERROR_MESSAGE_HERE, HASH_KEY: INFO_TO_PASS, HASH_KEY2: INFO_TO_PASS,
|
36
|
+
```
|
37
|
+
|
38
|
+
All error classes are available: `debug` `info` `warn` `error` `fatal`
|
39
|
+
|
40
|
+
Some examples for each:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
debug :something_is_not_perfect_here, info_wanted: the_info
|
44
|
+
|
45
|
+
info :some_logged_info_i_may_look_at, info_wanted: the_info
|
46
|
+
|
47
|
+
warn :its_weird_and_you_wanna_know, info_wanted: the_info
|
48
|
+
|
49
|
+
error :email_for_user_does_not_exist, user_id: @user.email
|
50
|
+
|
51
|
+
fatal :it_is_going_to_be_a_long_day, need_to_know: info_dump
|
52
|
+
```
|
31
53
|
|
32
54
|
## Development
|
33
55
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Technologic
|
4
|
+
module Generators
|
5
|
+
class InitializerGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
7
|
+
|
8
|
+
def create_initializer
|
9
|
+
template "initializer.rb.erb", File.join("config/initializers/technologic.rb")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Rails.application.configure do
|
4
|
+
# When disabled, the default subscribers and loggers are not registered, so events are triggered but not listened for.
|
5
|
+
# config.technologic.enabled = true
|
6
|
+
|
7
|
+
# Technologic uses an event based model to log the events you dispatch inside of your objects.
|
8
|
+
# Logging is therefore only one of the capabilities empowered by Technologic.
|
9
|
+
# Use the Technologic `on_event` subscribers to quickly build out metrics reporting, profiling, etc.
|
10
|
+
|
11
|
+
# Subscribers listen for messages triggered by Technologic's severity methods (debug, info, warn, error, fatal).
|
12
|
+
# Messages are converted into `Technologic::Event` objects and all registered event handlers are triggered.
|
13
|
+
# When disabled, subscribers will not listen for instrumentation messages, so no event handlers will be triggered.
|
14
|
+
# config.technologic.subscribe_to_fatal = true
|
15
|
+
# config.technologic.subscribe_to_error = true
|
16
|
+
# config.technologic.subscribe_to_warn = true
|
17
|
+
# config.technologic.subscribe_to_info = true
|
18
|
+
# config.technologic.subscribe_to_debug = true
|
19
|
+
|
20
|
+
# Loggers register with their affiliated subscribers to listen for and handle events of the specified severity.
|
21
|
+
# When disabled, event handlers are not registered with the subscribers, so no logs will be written.
|
22
|
+
# config.technologic.log_fatal_events = true
|
23
|
+
# config.technologic.log_error_events = true
|
24
|
+
# config.technologic.log_warn_events = true
|
25
|
+
# config.technologic.log_info_events = true
|
26
|
+
# config.technologic.log_debug_events = true
|
27
|
+
end
|
28
|
+
|
29
|
+
# Technologic is designed to elegantly export into very clean, minimal, and powerful JSON logs and comes packaged with
|
30
|
+
# a simple way to convert the default Rails logger to emit JSON logs.
|
31
|
+
# Uncomment the lines below to convert the default logger over to JSON logs.
|
32
|
+
#
|
33
|
+
# JsonLogConverter.convert_rails_logger
|
34
|
+
#
|
35
|
+
# This class takes a block if you want to customize the payload yourself:
|
36
|
+
#
|
37
|
+
# JsonLogConverter.convert_rails_logger do |severity, timestamp, msg|
|
38
|
+
# { technologic_is_cool: true, severity: severity[0], timestamp: timestamp.to_i, msg: msg }
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# By default, the log payload used by the converter is:
|
42
|
+
#
|
43
|
+
# { severity:, timestamp:, tags: <if there are any>, message: <for strings>, ...event_data_keys }
|
44
|
+
#
|
45
|
+
# If you want to manipulate this default payload in your custom formatter, use `#default_json_payload`
|
46
|
+
#
|
47
|
+
# JsonLogConvert.convert_rails_logger do |severity, timestamp, msg|
|
48
|
+
# default_json_payload(severity, timestamp, msg).merge(technologic_is_cool: true)
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# *NOTE*: Whatever value you return from the block is logged, so if you return nothing a blank line will be logged!
|
52
|
+
# Unless you've changed something about the default Rails logger, it's also a "tagged logger".
|
53
|
+
# You can use the `#current_tags` method within your formatter block to get access to these tags.
|
54
|
+
#
|
55
|
+
# JsonLogConverter.convert_rails_logger do |severity, timestamp, msg|
|
56
|
+
# next if current_tags.include? "silence"
|
57
|
+
# default_json_payload(severity, timestamp, msg)
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# Finally, the converter provides a Technologic specific convenience method for some optional log parsing.
|
61
|
+
# By default, Technologic events are whatever event you log plus the class where the event originated from.
|
62
|
+
# This is emitted as one key called event where these values are joined by a period:
|
63
|
+
#
|
64
|
+
# { event: "something_bad_happened.Klass" }
|
65
|
+
#
|
66
|
+
# If you would prefer these two data values to be split in the logs, ex:
|
67
|
+
#
|
68
|
+
# { event: "something_bad_happened", class: "Klass" }
|
69
|
+
#
|
70
|
+
# Then you can use the `#split_event_key_for_payload` method provided with the converter:
|
71
|
+
#
|
72
|
+
# JsonLogConverter.convert_rails_logger do |severity, timestamp, msg|
|
73
|
+
# split_event_key_for_payload(default_json_payload(severity, timestamp, msg))
|
74
|
+
# end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This plays nicely with Technologic's severity logging methods, writing clean JSON rather than stringified hashes.
|
4
|
+
# Call within a `config/initializer` to replace `ActiveSupport::TaggedLogging#call` with a custom JSON log formatter.
|
5
|
+
#
|
6
|
+
# JsonLogConverter.convert_rails_logger
|
7
|
+
#
|
8
|
+
# You can optionally provide a block to the `convert_rails_logger` method to hand-craft the log payload yourself:
|
9
|
+
#
|
10
|
+
# JsonLogConverter.convert_rails_logger do |severity, timestamp, msg|
|
11
|
+
# payload = { severity: severity, timestamp: timestamp }
|
12
|
+
# payload[:tags] = current_tags if current_tags.any?
|
13
|
+
# payload.merge(msg.is_a?(Hash) ? msg : { message: msg })
|
14
|
+
# end
|
15
|
+
|
16
|
+
module JsonLogConverter
|
17
|
+
def self.convert_rails_logger(&block)
|
18
|
+
define_method(:log_payload_for, &block) if block_given?
|
19
|
+
Rails.logger.formatter.extend self
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(severity, timestamp, _progname, msg)
|
23
|
+
"#{log_payload_for(severity, timestamp, msg).to_json}\n"
|
24
|
+
end
|
25
|
+
|
26
|
+
def default_json_payload(severity, timestamp, msg)
|
27
|
+
payload = { severity: severity, timestamp: timestamp }
|
28
|
+
payload[:tags] = current_tags if current_tags.any?
|
29
|
+
payload.merge(msg.is_a?(Hash) ? msg : { message: msg })
|
30
|
+
end
|
31
|
+
|
32
|
+
def split_event_key_for_payload(payload)
|
33
|
+
return payload unless payload[:event]&.include? "."
|
34
|
+
|
35
|
+
parts = payload[:event].split(".")
|
36
|
+
return payload unless parts.length == 2
|
37
|
+
|
38
|
+
payload[:event] = parts[0]
|
39
|
+
payload[:class] = parts[1]
|
40
|
+
payload
|
41
|
+
end
|
42
|
+
|
43
|
+
def log_payload_for(severity, timestamp, msg)
|
44
|
+
default_json_payload(severity, timestamp, msg)
|
45
|
+
end
|
46
|
+
end
|
data/lib/technologic.rb
CHANGED
@@ -15,7 +15,5 @@ module Technologic
|
|
15
15
|
class_attribute :log_warn_events, default: true
|
16
16
|
class_attribute :log_info_events, default: true
|
17
17
|
class_attribute :log_debug_events, default: true
|
18
|
-
|
19
|
-
class_attribute :include_in_classes, default: %w[ApplicationController]
|
20
18
|
end
|
21
19
|
end
|
data/lib/technologic/setup.rb
CHANGED
@@ -8,7 +8,6 @@ module Technologic
|
|
8
8
|
|
9
9
|
setup_subscribers(technologic_config)
|
10
10
|
setup_loggers(technologic_config)
|
11
|
-
setup_includes(technologic_config)
|
12
11
|
end
|
13
12
|
|
14
13
|
private
|
@@ -28,10 +27,6 @@ module Technologic
|
|
28
27
|
Technologic::InfoSubscriber.on_event { |e| Technologic::Logger.log(:info, e) } if config.log_info_events
|
29
28
|
Technologic::DebugSubscriber.on_event { |e| Technologic::Logger.log(:debug, e) } if config.log_debug_events
|
30
29
|
end
|
31
|
-
|
32
|
-
def setup_includes(config)
|
33
|
-
config.include_in_classes.each { |class_name| class_name.constantize.include(Technologic) }
|
34
|
-
end
|
35
30
|
end
|
36
31
|
end
|
37
32
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "shared_examples/a_debug_event_is_logged"
|
4
|
+
require_relative "shared_examples/a_fatal_event_is_logged"
|
5
|
+
require_relative "shared_examples/a_logged_event_with_severity"
|
6
|
+
require_relative "shared_examples/a_surveiled_event"
|
7
|
+
require_relative "shared_examples/a_warn_event_is_logged"
|
8
|
+
require_relative "shared_examples/an_error_event_is_logged"
|
9
|
+
require_relative "shared_examples/an_info_event_is_logged"
|
10
|
+
require_relative "shared_examples/an_instrumented_exception_with_severity"
|
11
|
+
require_relative "shared_examples/an_instrumented_error_exception"
|
12
|
+
require_relative "shared_examples/an_instrumented_fatal_exception"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# RSpec example that tests usage of `#debug`
|
4
|
+
#
|
5
|
+
# class Klass
|
6
|
+
# include Technologic
|
7
|
+
#
|
8
|
+
# def initialize(user)
|
9
|
+
# @user = user
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def do_a_thing
|
13
|
+
# debug :thing_being_done, user: @user
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# RSpec.describe Klass do
|
18
|
+
# let(:instance) { described_class.new(user) }
|
19
|
+
# let(:user) { double }
|
20
|
+
#
|
21
|
+
# before { instance.do_a_thing }
|
22
|
+
#
|
23
|
+
# it_behaves_like "a debug event is logged", :thing_being_done do
|
24
|
+
# let(:expected_data) do
|
25
|
+
# { user: user }
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
RSpec.shared_examples_for "a debug event is logged" do |event, for_class = described_class|
|
31
|
+
include_examples "a logged event with severity", event, :debug, for_class
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# RSpec example that tests usage of `#fatal`
|
4
|
+
#
|
5
|
+
# class Klass
|
6
|
+
# include Technologic
|
7
|
+
#
|
8
|
+
# def initialize(user)
|
9
|
+
# @user = user
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def do_a_thing
|
13
|
+
# fatal :thing_being_done, user: @user
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# RSpec.describe Klass do
|
18
|
+
# let(:instance) { described_class.new(user) }
|
19
|
+
# let(:user) { double }
|
20
|
+
#
|
21
|
+
# before { instance.do_a_thing }
|
22
|
+
#
|
23
|
+
# it_behaves_like "a fatal event is logged", :thing_being_done do
|
24
|
+
# let(:expected_data) do
|
25
|
+
# { user: user }
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
RSpec.shared_examples_for "a fatal event is logged" do |event, for_class = described_class|
|
31
|
+
include_examples "a logged event with severity", event, :fatal, for_class
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# RSpec example that tests usage of named severity log handlers (used to DRY out other shared examples)
|
4
|
+
#
|
5
|
+
# class Klass
|
6
|
+
# include Technologic
|
7
|
+
#
|
8
|
+
# def initialize(user)
|
9
|
+
# @user = user
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def do_a_thing
|
13
|
+
# info :thing_being_done, user: @user
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# RSpec.describe Klass do
|
18
|
+
# let(:instance) { described_class.new(user) }
|
19
|
+
# let(:user) { double }
|
20
|
+
#
|
21
|
+
# before { instance.do_a_thing }
|
22
|
+
#
|
23
|
+
# it_behaves_like "a logged event with severity", :thing_being_done, :info do
|
24
|
+
# let(:expected_data) do
|
25
|
+
# { user: user }
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
RSpec.shared_examples_for "a logged event with severity" do |event, severity, for_class = described_class|
|
31
|
+
include_examples "an instrumented event", "#{event}.#{for_class}.#{severity}"
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# RSpec example that tests usage of `#surveil`
|
4
|
+
#
|
5
|
+
# class Klass
|
6
|
+
# include Technologic
|
7
|
+
#
|
8
|
+
# def initialize(user)
|
9
|
+
# @user = user
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def do_a_thing
|
13
|
+
# surveil(:doing_a_thing, user: @user) { :a_thing_is_done }
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# RSpec.describe Klass do
|
18
|
+
# let(:instance) { described_class.new(user) }
|
19
|
+
# let(:user) { double }
|
20
|
+
#
|
21
|
+
# before { instance.do_a_thing }
|
22
|
+
#
|
23
|
+
# it_behaves_like "a surveiled event", :doing_a_thing do
|
24
|
+
# let(:expected_data) do
|
25
|
+
# { user: user }
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
RSpec.shared_examples_for "a surveiled event" do |expected_event|
|
31
|
+
subject { ActiveSupport::Notifications }
|
32
|
+
|
33
|
+
let(:expected_class) { described_class }
|
34
|
+
let(:expected_args_start) { [ "#{expected_event}_started.#{expected_class}.info", expected_data ] }
|
35
|
+
let(:expected_args_finished) { [ "#{expected_event}_finished.#{expected_class}.info", {} ] }
|
36
|
+
let(:expected_data) do
|
37
|
+
{}
|
38
|
+
end
|
39
|
+
|
40
|
+
it { is_expected.to have_received(:instrument).with(*expected_args_start) }
|
41
|
+
it { is_expected.to have_received(:instrument).with(*expected_args_finished) }
|
42
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# RSpec example that tests usage of `#warn`
|
4
|
+
#
|
5
|
+
# class Klass
|
6
|
+
# include Technologic
|
7
|
+
#
|
8
|
+
# def initialize(user)
|
9
|
+
# @user = user
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def do_a_thing
|
13
|
+
# warn :thing_being_done, user: @user
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# RSpec.describe Klass do
|
18
|
+
# let(:instance) { described_class.new(user) }
|
19
|
+
# let(:user) { double }
|
20
|
+
#
|
21
|
+
# before { instance.do_a_thing }
|
22
|
+
#
|
23
|
+
# it_behaves_like "a warn event is logged", :thing_being_done do
|
24
|
+
# let(:expected_data) do
|
25
|
+
# { user: user }
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
RSpec.shared_examples_for "a warn event is logged" do |event, for_class = described_class|
|
31
|
+
include_examples "a logged event with severity", event, :warn, for_class
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# RSpec example that tests usage of `#error`
|
4
|
+
#
|
5
|
+
# class Klass
|
6
|
+
# include Technologic
|
7
|
+
#
|
8
|
+
# def initialize(user)
|
9
|
+
# @user = user
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def do_a_thing
|
13
|
+
# error :thing_being_done, user: @user
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# RSpec.describe Klass do
|
18
|
+
# let(:instance) { described_class.new(user) }
|
19
|
+
# let(:user) { double }
|
20
|
+
#
|
21
|
+
# before { instance.do_a_thing }
|
22
|
+
#
|
23
|
+
# it_behaves_like "an error event is logged", :thing_being_done do
|
24
|
+
# let(:expected_data) do
|
25
|
+
# { user: user }
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
RSpec.shared_examples_for "an error event is logged" do |event, for_class = described_class|
|
31
|
+
include_examples "a logged event with severity", event, :error, for_class
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# RSpec example that tests usage of `#info`
|
4
|
+
#
|
5
|
+
# class Klass
|
6
|
+
# include Technologic
|
7
|
+
#
|
8
|
+
# def initialize(user)
|
9
|
+
# @user = user
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def do_a_thing
|
13
|
+
# info :thing_being_done, user: @user
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# RSpec.describe Klass do
|
18
|
+
# let(:instance) { described_class.new(user) }
|
19
|
+
# let(:user) { double }
|
20
|
+
#
|
21
|
+
# before { instance.do_a_thing }
|
22
|
+
#
|
23
|
+
# it_behaves_like "an info event is logged", :thing_being_done do
|
24
|
+
# let(:expected_data) do
|
25
|
+
# { user: user }
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
RSpec.shared_examples_for "an info event is logged" do |event, for_class = described_class|
|
31
|
+
include_examples "a logged event with severity", event, :info, for_class
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# RSpec example that tests usage of `#error!`
|
4
|
+
#
|
5
|
+
# class Klass
|
6
|
+
# include Technologic
|
7
|
+
#
|
8
|
+
# def initialize(user)
|
9
|
+
# @user = user
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def do_a_thing
|
13
|
+
# error! RuntimeError, "Something bad always happens when you do a thing!", user: @user
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# RSpec.describe Klass do
|
18
|
+
# include_examples "an instrumented error exception", RuntimeError do
|
19
|
+
# let(:instance) { described_class.new(user) }
|
20
|
+
# let(:user) { double }
|
21
|
+
# let(:example_method) { instance.do_a_thing }
|
22
|
+
# let(:expected_message) { "Something bad always happens when you do a thing!" }
|
23
|
+
# let(:expected_data) do
|
24
|
+
# { user: user }
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
|
29
|
+
RSpec.shared_examples_for "an instrumented error exception" do |error_class|
|
30
|
+
include_examples "an instrumented exception with severity", error_class, :error!
|
31
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# RSpec example that tests usage of exception raising severity loggers (used to DRY out other shared examples)
|
4
|
+
#
|
5
|
+
# class Klass
|
6
|
+
# include Technologic
|
7
|
+
#
|
8
|
+
# def initialize(user)
|
9
|
+
# @user = user
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def do_a_thing
|
13
|
+
# error! RuntimeError, "Something bad always happens when you do a thing!", user: @user
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# RSpec.describe Klass do
|
18
|
+
# include_examples "an instrumented exception with severity", RuntimeError, :error! do
|
19
|
+
# let(:instance) { described_class.new(user) }
|
20
|
+
# let(:user) { double }
|
21
|
+
# let(:example_method) { instance.do_a_thing }
|
22
|
+
# let(:expected_message) { "Something bad always happens when you do a thing!" }
|
23
|
+
# let(:expected_data) do
|
24
|
+
# { user: user }
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
|
29
|
+
RSpec.shared_examples_for "an instrumented exception with severity" do |error_class, severity|
|
30
|
+
before { allow(instance).to receive(severity).and_call_original }
|
31
|
+
|
32
|
+
let(:expected_message) { nil }
|
33
|
+
let(:expected_data) do
|
34
|
+
{}
|
35
|
+
end
|
36
|
+
let(:expected_arguments) do
|
37
|
+
[ error_class, expected_message ].tap { |arr| arr << expected_data unless expected_data.empty? }.compact
|
38
|
+
end
|
39
|
+
|
40
|
+
it "raises and logs" do
|
41
|
+
expect { example_method }.to raise_error error_class, expected_message
|
42
|
+
expect(instance).to have_received(severity).with(*expected_arguments)
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# RSpec example that tests usage of `#fatal!`
|
4
|
+
#
|
5
|
+
# class Klass
|
6
|
+
# include Technologic
|
7
|
+
#
|
8
|
+
# def initialize(user)
|
9
|
+
# @user = user
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def do_a_thing
|
13
|
+
# fatal! RuntimeError, "Something terrible always happens when you do a thing!", user: @user
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# RSpec.describe Klass do
|
18
|
+
# include_examples "an instrumented fatal exception", RuntimeError do
|
19
|
+
# let(:instance) { described_class.new(user) }
|
20
|
+
# let(:user) { double }
|
21
|
+
# let(:example_method) { instance.do_a_thing }
|
22
|
+
# let(:expected_message) { "Something terrible always happens when you do a thing!" }
|
23
|
+
# let(:expected_data) do
|
24
|
+
# { user: user }
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
|
29
|
+
RSpec.shared_examples_for "an instrumented fatal exception" do |error_class|
|
30
|
+
include_examples "an instrumented exception with severity", error_class, :fatal!
|
31
|
+
end
|
data/lib/technologic/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: technologic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Garside
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.6.
|
47
|
+
version: 0.6.4
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.6.
|
54
|
+
version: 0.6.4
|
55
55
|
description: An opinionated philosophy on logging for Ruby on Rails applications.
|
56
56
|
email:
|
57
57
|
- garside@gmail.com
|
@@ -61,6 +61,10 @@ extra_rdoc_files: []
|
|
61
61
|
files:
|
62
62
|
- LICENSE.txt
|
63
63
|
- README.md
|
64
|
+
- lib/generators/technologic/initializer/USAGE
|
65
|
+
- lib/generators/technologic/initializer/initializer_generator.rb
|
66
|
+
- lib/generators/technologic/initializer/templates/initializer.rb.erb
|
67
|
+
- lib/json_log_converter.rb
|
64
68
|
- lib/technologic.rb
|
65
69
|
- lib/technologic/config_options.rb
|
66
70
|
- lib/technologic/debug_subscriber.rb
|
@@ -71,6 +75,18 @@ files:
|
|
71
75
|
- lib/technologic/logger.rb
|
72
76
|
- lib/technologic/railtie.rb
|
73
77
|
- lib/technologic/setup.rb
|
78
|
+
- lib/technologic/shared_examples.rb
|
79
|
+
- lib/technologic/shared_examples/a_debug_event_is_logged.rb
|
80
|
+
- lib/technologic/shared_examples/a_fatal_event_is_logged.rb
|
81
|
+
- lib/technologic/shared_examples/a_logged_event_with_severity.rb
|
82
|
+
- lib/technologic/shared_examples/a_surveiled_event.rb
|
83
|
+
- lib/technologic/shared_examples/a_warn_event_is_logged.rb
|
84
|
+
- lib/technologic/shared_examples/an_error_event_is_logged.rb
|
85
|
+
- lib/technologic/shared_examples/an_info_event_is_logged.rb
|
86
|
+
- lib/technologic/shared_examples/an_instrumented_error_exception.rb
|
87
|
+
- lib/technologic/shared_examples/an_instrumented_exception_with_severity.rb
|
88
|
+
- lib/technologic/shared_examples/an_instrumented_fatal_exception.rb
|
89
|
+
- lib/technologic/spec_helper.rb
|
74
90
|
- lib/technologic/subscriber/base.rb
|
75
91
|
- lib/technologic/subscriber/core.rb
|
76
92
|
- lib/technologic/subscriber/event_handling.rb
|