stenotype 0.1.1 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/CHANGELOG.md +26 -1
- data/Gemfile.lock +2 -2
- data/README.md +59 -15
- data/lib/generators/stenotype/initializer/templates/initializer.rb.erb +76 -59
- data/lib/stenotype/adapters/base.rb +23 -2
- data/lib/stenotype/adapters/google_cloud.rb +27 -7
- data/lib/stenotype/adapters/stdout_adapter.rb +14 -2
- data/lib/stenotype/at_exit.rb +10 -0
- data/lib/stenotype/configuration.rb +41 -1
- data/lib/stenotype/emitter.rb +21 -17
- data/lib/stenotype/event.rb +40 -16
- data/lib/stenotype/event_serializer.rb +6 -6
- data/lib/stenotype/frameworks/rails/action_controller.rb +6 -5
- data/lib/stenotype/frameworks/rails/active_job.rb +2 -2
- data/lib/stenotype/railtie.rb +2 -0
- data/lib/stenotype/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f58226124306beb915f76259d055c013e197d24dee87513d751764486ce8033
|
4
|
+
data.tar.gz: eee031ad3b4f4b9d5b8ed8645e5d7f676f0490f1f9351cec516ffc72ef5b298a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe129ae49b3b255a02f1cadcc6920820348846d0b10dba93ab554322b545401a63c8bce7becd239502e9ff433b127e738ff612d4b1cc9903a0f32212ce68eda1
|
7
|
+
data.tar.gz: 275de1f70c2c0f4e9d608e79d93e773d75538b18a47c1f2848a7753bb6151b5f96a8ef7c74b36b3a462360de7be196a247d3be3429cfd7f1b00364691ae01a5e
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,31 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
*Release Date*:
|
3
|
+
*Release Date*: 2020/01/13
|
4
|
+
|
5
|
+
### 0.1.7 2020/01/20
|
6
|
+
* Adds a config option to allow explicit adapter setup.
|
7
|
+
* Adds an `after_initialize` rails hook to setup adapters.
|
8
|
+
* Remove topic from the list of Google Cloud adapter arguments.
|
9
|
+
|
10
|
+
### 0.1.6 2020/01/17
|
11
|
+
* Allow topic to be explicitly set upon Google Cloud adapter initialization
|
12
|
+
|
13
|
+
### 0.1.5 2020/01/13
|
14
|
+
* In case `graceful_error_handling` is set to off raise a generic `Stenotype::Error` on any exception in order to intercept a single error type in the client code.
|
15
|
+
* Adds an `at_exit` hook to flush the async message queue when using the library in async mode.
|
16
|
+
|
17
|
+
### 0.1.4 2020/01/10
|
18
|
+
* Adds a new configuration option `graceful_error_handling` to suppress errors raised from the gem's internals yet logging the error to specified `config.logger`
|
19
|
+
|
20
|
+
### 0.1.3: 2020/01/10
|
21
|
+
* Adds a new configuration option `logger` to use during error handling
|
22
|
+
* Adds a new config option `Stenotype.config.enabled`. If the option is set to false then event is not going to be published. The option is `true` by default.
|
23
|
+
|
24
|
+
### 0.1.2: 2019/12/10
|
25
|
+
|
26
|
+
* Changes the interface of how event is emitted. Now you must pass `event_name`, `attributes` and optional `eval_context`. Note that `additional_options` are eliminated
|
27
|
+
* Makes StdoutAdapter more informative by adding a special line for every entry in the log.
|
28
|
+
* Fixes Rails initializer not working after switching to Configurable from Spicerack.
|
4
29
|
|
5
30
|
### 0.1.1: 2019/11/25
|
6
31
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
stenotype (0.1.
|
4
|
+
stenotype (0.1.6)
|
5
5
|
activesupport (>= 5.0.0)
|
6
6
|
google-cloud-pubsub (~> 1.0.0)
|
7
7
|
spicery (>= 0.19.0, < 1.0)
|
@@ -147,7 +147,7 @@ GEM
|
|
147
147
|
coderay (~> 1.1.0)
|
148
148
|
method_source (~> 0.9.0)
|
149
149
|
public_suffix (4.0.1)
|
150
|
-
rack (2.0.
|
150
|
+
rack (2.0.8)
|
151
151
|
rack-test (1.1.0)
|
152
152
|
rack (>= 1.0, < 3)
|
153
153
|
rails (5.2.4)
|
data/README.md
CHANGED
@@ -25,24 +25,48 @@ Or install it yourself as:
|
|
25
25
|
Configuring the library is as simple as:
|
26
26
|
```ruby
|
27
27
|
Stenotype.configure do |config|
|
28
|
+
config.enabled = true
|
28
29
|
config.targets = [ # Supported targets
|
29
30
|
Stenotype::Adapters::StdoutAdapter.new,
|
30
31
|
Stenotype::Adapters::GoogleCloud.new
|
31
32
|
]
|
32
33
|
|
33
|
-
config.uuid_generator
|
34
|
-
config.dispatcher
|
35
|
-
config.
|
36
|
-
config.
|
37
|
-
config.
|
38
|
-
|
34
|
+
config.uuid_generator = SecureRandom
|
35
|
+
config.dispatcher = Stenotype::Dispatcher.new
|
36
|
+
config.logger = Logger.new(STDOUT)
|
37
|
+
config.graceful_error_handling = true
|
38
|
+
config.auto_adapter_initialization = true
|
39
|
+
|
40
|
+
config.google_cloud do |gc_config|
|
41
|
+
gc_config.project_id = "google_cloud_project_id"
|
42
|
+
gc_config.credentials = "path_to_key_json"
|
43
|
+
gc_config.topic = "google_cloud_topic"
|
44
|
+
gc_config.async = true # either true or false
|
45
|
+
end
|
46
|
+
|
47
|
+
config.rails do |rails_config|
|
48
|
+
rails_config.enable_action_controller_ext = true
|
49
|
+
rails_config.enable_active_job_ext = true
|
50
|
+
end
|
39
51
|
end
|
40
52
|
```
|
41
53
|
|
54
|
+
#### config.enabled
|
55
|
+
|
56
|
+
A flag checked upon emission of an event. Will prevent event emission if set to false. An event is emitted if set to true.
|
57
|
+
|
42
58
|
#### config.targets
|
43
59
|
|
44
60
|
Contain an array of targets for the events to be published to. Targets must implement method `#publish(event_data, **additional_arguments)`.
|
45
61
|
|
62
|
+
#### config.logger
|
63
|
+
|
64
|
+
Specifies a logger for messages and exceptions to be output to. If not set defaults to `Logger.new(STDOUT)`, otherwise a manually set logger is used.
|
65
|
+
|
66
|
+
#### config.graceful_error_handling
|
67
|
+
|
68
|
+
This flag if set to `true` is going to suppress all `StandardError`'s raised within a gem. Raises the error to the caller if set to `false`
|
69
|
+
|
46
70
|
#### config.uuid_generator
|
47
71
|
|
48
72
|
An object that must implement method `#uuid`. Used when an event is emitted to generate a unique id for each event.
|
@@ -51,21 +75,33 @@ An object that must implement method `#uuid`. Used when an event is emitted to g
|
|
51
75
|
|
52
76
|
Dispatcher used to dispatch the event. A dispatcher must implement method `#publish(even, serializer: Stenotype::EventSerializer)`. By default `Stenotype::EventSerializer` is used, which is responsible for collecting the data from the event and evaluation context.
|
53
77
|
|
54
|
-
#### config.
|
78
|
+
#### config.google_cloud.project_id
|
55
79
|
|
56
80
|
Google cloud project ID. Please refer to Google Cloud management console to get one.
|
57
81
|
|
58
|
-
#### config.
|
82
|
+
#### config.google_cloud.credentials
|
59
83
|
|
60
84
|
Google cloud credentials. Might be obtained from Google Cloud management console.
|
61
85
|
|
62
|
-
#### config.
|
86
|
+
#### config.google_cloud.topic
|
63
87
|
|
64
88
|
Google Cloud topic used for publishing the events.
|
65
89
|
|
66
|
-
#### config.
|
90
|
+
#### config.google_cloud.async
|
91
|
+
|
92
|
+
Google Cloud publish mode. The mode is either sync or async. When in `sync` mode the event will be published in the same thread (which might influence performance). For `async` mode the event will be put into a pull which is going to be flushed after a threshold is met.
|
67
93
|
|
68
|
-
|
94
|
+
#### config.rails.enable_action_controller_ext
|
95
|
+
|
96
|
+
Allows to enable/disable Rails ActionController extension
|
97
|
+
|
98
|
+
#### config.rails.enable_active_job_ext
|
99
|
+
|
100
|
+
Allows to enable/disable Rails ActiveJob extension
|
101
|
+
|
102
|
+
#### config.rails.auto_adapter_initialization
|
103
|
+
|
104
|
+
Controls whether the hook `auto_initialize!` is run for each adapter. If set to true `auto_initialize!` is invoked for every adapter. If false `auto_initialize!` is not run. For example for google cloud adapter this will instantiate `client` and `topic` objects before first publish. If set to false `client` and `topic` are lazy initialized.
|
69
105
|
|
70
106
|
#### Configuring context handlers
|
71
107
|
|
@@ -76,8 +112,8 @@ Each event is emitted in a context which might be an ActionController instance o
|
|
76
112
|
Emitting an event is as simple as:
|
77
113
|
```ruby
|
78
114
|
Stenotype::Event.emit!(
|
79
|
-
|
80
|
-
|
115
|
+
"Event Name",
|
116
|
+
{ attr1: :value1, attr2: :value2 },
|
81
117
|
eval_context: { name_of_registered_context_handler: context_object }
|
82
118
|
)
|
83
119
|
```
|
@@ -172,9 +208,9 @@ Stenotype::ContextHandlers.register CustomHandler
|
|
172
208
|
class PlainRubyClass < BaseClass
|
173
209
|
def some_method(data)
|
174
210
|
event_data = collect_some_data_as_a_hash
|
175
|
-
emit_event(event_data) # method name will be `some_method`, eval_context: { klass: self }
|
211
|
+
emit_event("event_name", event_data) # method name will be `some_method`, eval_context: { klass: self }
|
176
212
|
other_event_data = do_something_else
|
177
|
-
emit_event(other_event_data, method: :custom_method_name, eval_context: { overriden_handler: self })
|
213
|
+
emit_event("other_event_name", other_event_data, method: :custom_method_name, eval_context: { overriden_handler: self })
|
178
214
|
end
|
179
215
|
end
|
180
216
|
```
|
@@ -197,6 +233,14 @@ class CustomAdapter < Stenotype::Adapters::Base
|
|
197
233
|
def publish(event_data, **additional_arguments)
|
198
234
|
# custom publishing logic
|
199
235
|
end
|
236
|
+
|
237
|
+
def flush!
|
238
|
+
# actions to be taken to flush the messages
|
239
|
+
end
|
240
|
+
|
241
|
+
def auto_initialize!
|
242
|
+
# actions to be taken to setup internal adapter state (client, endpoint, whatsoever)
|
243
|
+
end
|
200
244
|
end
|
201
245
|
```
|
202
246
|
|
@@ -1,65 +1,82 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
Rails.application.configure do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
4
|
+
Stenotype.configure do |config|
|
5
|
+
#
|
6
|
+
# Stenotype allows you to emit events which are then being published to a list of
|
7
|
+
# targets. Currently two targets are provided by default: Google Cloud Pub Sub and
|
8
|
+
# STDOUT for debug purposes.
|
9
|
+
#
|
10
|
+
# There is also a rails integration module which defines a handy DSL
|
11
|
+
# for triggering events in various Rails components. ActionController and
|
12
|
+
# ActiveJob are supported at the time of writing.
|
13
|
+
#
|
14
|
+
# Both extensions for Rails are enabled by default, but there are config options
|
15
|
+
# to control their presence.
|
16
|
+
# config.rails do |rails_modules|
|
17
|
+
# rails_modules.enable_action_controller_ext = true
|
18
|
+
# rails_modules.enable_active_job_ext = true
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# To enable or disable the library use the following config option:
|
22
|
+
#
|
23
|
+
# config.enabled = true # or false
|
24
|
+
#
|
25
|
+
# To make publishing possible one must specify a list of targets. You could use
|
26
|
+
# StdoutAdapter for debug purposes before switching to a production publisher.
|
27
|
+
# By default the list of targets is empty and you'll get an error saying
|
28
|
+
# that no targets are specified.
|
29
|
+
#
|
30
|
+
# A config option is available for setting up the targets:
|
31
|
+
#
|
32
|
+
# config.targets = [Stenotype::Adapters::StdoutAdapter.new]
|
33
|
+
#
|
34
|
+
# Or using Google Cloud:
|
35
|
+
#
|
36
|
+
# config.targets = [Stenotype::Adapters::GoogleCloud.new]
|
37
|
+
#
|
38
|
+
# Or both:
|
39
|
+
#
|
40
|
+
# config.targets = [
|
41
|
+
# Stenotype::Adapters::StdoutAdapter.new,
|
42
|
+
# Stenotype::Adapters::GoogleCloud.new
|
43
|
+
# ]
|
44
|
+
#
|
45
|
+
# To be able to use Google Cloud one has to specify Google Cloud credentials:
|
46
|
+
#
|
47
|
+
# config.google_cloud do |gc_config|
|
48
|
+
# gc_config.credentials = "SPECIFY YOUR CREDENTIALS" # path/to/key.json
|
49
|
+
# gc_config.project_id = "SPECIFY YOUR PROJECT ID"
|
50
|
+
# gc_config.topic = "SPECIFY YOUR TOPIC"
|
51
|
+
# gc_config.async = true
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# Each event is shipped with a UUID generated with SecureRandom by default.
|
55
|
+
# This might be changed by using a corresponding config option. Note that
|
56
|
+
# uuid_generator expects method #uuid to be implemented
|
57
|
+
#
|
58
|
+
# config.uuid_generator = SecureRandom
|
59
|
+
#
|
60
|
+
# In rare cases you might want to get control over how the event is being dispatched.
|
61
|
+
# Dispatcher must implement instance method #publish.
|
62
|
+
# Which dispatcher to use is controlled by the following config option:
|
63
|
+
#
|
64
|
+
# config.dispatcher = Stenotype::Dispatcher
|
65
|
+
#
|
66
|
+
# An option to suppress exception within a gem is available:
|
67
|
+
#
|
68
|
+
# config.graceful_error_handling = true
|
69
|
+
#
|
70
|
+
# To log errors a logger config option is available. Logger.new(STDOUT) is used by default.
|
71
|
+
#
|
72
|
+
# config.logger = Logger.new(STDOUT)
|
73
|
+
#
|
74
|
+
# Add your own context handlers
|
75
|
+
#
|
76
|
+
# Stenotype::ContextHandlers.register Your::Custom::HandlerClass
|
77
|
+
#
|
78
|
+
end
|
62
79
|
end
|
63
80
|
|
64
81
|
# For more usage instructions please refer to either README.md or yard documentation
|
65
|
-
# in gem repository https://github.com/Freshly/stenotype
|
82
|
+
# in gem repository https://github.com/Freshly/stenotype
|
@@ -35,12 +35,33 @@ module Stenotype
|
|
35
35
|
#
|
36
36
|
# This method is expected to be implemented by subclasses
|
37
37
|
# @abstract
|
38
|
-
# @raise
|
38
|
+
# @raise {NotImplementedError} unless implemented in a subclass
|
39
39
|
#
|
40
|
-
def publish(_event_data, **
|
40
|
+
def publish(_event_data, **_additional_attrs)
|
41
41
|
raise NotImplementedError,
|
42
42
|
"#{self.class.name} must implement method #publish"
|
43
43
|
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Allows custom setup of the adapter. Noop by default
|
47
|
+
# @abstract
|
48
|
+
#
|
49
|
+
def auto_initialize!
|
50
|
+
# noop by default
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# This method is expected to be implemented by subclasses. In case async
|
55
|
+
# publisher is used the process might end before the async queue of
|
56
|
+
# messages is processed, so this method is going to be used in a
|
57
|
+
# `at_exit` hook to flush the queue.
|
58
|
+
# @abstract
|
59
|
+
# @raise {NotImplementedError} unless implemented in a subclass
|
60
|
+
#
|
61
|
+
def flush!
|
62
|
+
raise NotImplementedError,
|
63
|
+
"#{self.class.name} must implement method #flush"
|
64
|
+
end
|
44
65
|
end
|
45
66
|
end
|
46
67
|
end
|
@@ -48,22 +48,42 @@ module Stenotype
|
|
48
48
|
# # publishes to default CustomGCClient
|
49
49
|
# google_cloud_adapter.publish({ event: :data }, { additional: :data })
|
50
50
|
#
|
51
|
-
def publish(event_data, **
|
51
|
+
def publish(event_data, **additional_attrs)
|
52
52
|
if config.async
|
53
|
-
publish_async(event_data, **
|
53
|
+
publish_async(event_data, **additional_attrs)
|
54
54
|
else
|
55
|
-
publish_sync(event_data, **
|
55
|
+
publish_sync(event_data, **additional_attrs)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
#
|
60
|
+
# Flushes the topic's async queue
|
61
|
+
#
|
62
|
+
def flush!
|
63
|
+
# a publisher might be uninitialized until the first event is published
|
64
|
+
return unless topic.async_publisher
|
65
|
+
|
66
|
+
topic.async_publisher.stop.wait!
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# If not called both client and topic are lazy initialized on first call (if not
|
71
|
+
# passed to #initialize). #auto_initialize! is going to explicitly initialize
|
72
|
+
# both client and topic.
|
73
|
+
#
|
74
|
+
def auto_initialize!
|
75
|
+
client
|
76
|
+
topic
|
77
|
+
end
|
78
|
+
|
59
79
|
private
|
60
80
|
|
61
|
-
def publish_sync(event_data, **
|
62
|
-
topic.publish(event_data,
|
81
|
+
def publish_sync(event_data, **additional_attrs)
|
82
|
+
topic.publish(event_data, additional_attrs)
|
63
83
|
end
|
64
84
|
|
65
|
-
def publish_async(event_data, **
|
66
|
-
topic.publish_async(event_data,
|
85
|
+
def publish_async(event_data, **additional_attrs)
|
86
|
+
topic.publish_async(event_data, additional_attrs) do |result|
|
67
87
|
raise Stenotype::MessageNotPublishedError unless result.succeeded?
|
68
88
|
end
|
69
89
|
end
|
@@ -31,8 +31,20 @@ module Stenotype
|
|
31
31
|
# adapter = Stenotype::Adapters::StdoutAdapter.new(client: STDERR)
|
32
32
|
# adapter.publish({ event: :data }, { additional: :data })
|
33
33
|
#
|
34
|
-
def publish(event_data, **
|
35
|
-
client.info(
|
34
|
+
def publish(event_data, **additional_attrs)
|
35
|
+
client.info("[Stenotype::Event] emitted with the following attributes") do
|
36
|
+
{
|
37
|
+
**event_data,
|
38
|
+
**additional_attrs,
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Does nothing
|
45
|
+
#
|
46
|
+
def flush!
|
47
|
+
# noop
|
36
48
|
end
|
37
49
|
|
38
50
|
private
|
@@ -6,6 +6,7 @@ module Stenotype
|
|
6
6
|
#
|
7
7
|
# @example Configuring the library
|
8
8
|
# Stenotype.configure do |config|
|
9
|
+
# config.enabled = true
|
9
10
|
# config.targets = [Target1.new, Target2.new]
|
10
11
|
# config.uuid_generator = SecureRandom
|
11
12
|
#
|
@@ -25,6 +26,18 @@ module Stenotype
|
|
25
26
|
module Configuration
|
26
27
|
extend Spicerack::Configurable
|
27
28
|
|
29
|
+
# @!attribute graceful_error_handling
|
30
|
+
# @return {true, false} a flag for suppressing error raised withing the gem
|
31
|
+
|
32
|
+
# @!attribute logger
|
33
|
+
# @return {Logger} a logger with default severity methods to output gem level messages
|
34
|
+
|
35
|
+
# @!attribute enabled
|
36
|
+
# @return {true, false} a flag indicating whether event emission is enabled
|
37
|
+
|
38
|
+
# @!attribute auto_adapter_initialization
|
39
|
+
# @return {true, false} enables/disables lazy initialization of adapters' clients
|
40
|
+
|
28
41
|
# @!attribute targets
|
29
42
|
# @return {Array<#publish>} a list of targets responding to method [#publish]
|
30
43
|
|
@@ -49,7 +62,6 @@ module Stenotype
|
|
49
62
|
# @!attribute [rw] google_cloud.async
|
50
63
|
# @return [true, false] GC publish mode, either async if true, sync if false
|
51
64
|
|
52
|
-
|
53
65
|
# @!attribute [rw] rails
|
54
66
|
# @return [NestedConfiguration] Rails configuration.
|
55
67
|
|
@@ -60,9 +72,12 @@ module Stenotype
|
|
60
72
|
# @return [true, false] A flag of whether ActiveJob ext is enabled
|
61
73
|
|
62
74
|
configuration_options do
|
75
|
+
option :graceful_error_handling, default: true
|
76
|
+
option :enabled, default: true
|
63
77
|
option :targets, default: []
|
64
78
|
option :dispatcher, default: Stenotype::Dispatcher
|
65
79
|
option :uuid_generator, default: SecureRandom
|
80
|
+
option :logger
|
66
81
|
|
67
82
|
nested :google_cloud do
|
68
83
|
option :credentials, default: nil
|
@@ -74,11 +89,34 @@ module Stenotype
|
|
74
89
|
nested :rails do
|
75
90
|
option :enable_action_controller_ext, default: true
|
76
91
|
option :enable_active_job_ext, default: true
|
92
|
+
option :auto_adapter_initialization, default: true
|
77
93
|
end
|
78
94
|
end
|
79
95
|
|
80
96
|
module_function
|
81
97
|
|
98
|
+
#
|
99
|
+
# @example With default logger
|
100
|
+
# Stenotype.configure do |config|
|
101
|
+
# # config.logger = nil # logger not set manually
|
102
|
+
# end
|
103
|
+
# Stenotype.config.logger #=> `Logger.new(STDOUT)` instance
|
104
|
+
#
|
105
|
+
# @example With custom logger
|
106
|
+
# Stenotype.configure do |config|
|
107
|
+
# config.logger = custom_logger_instance
|
108
|
+
# end
|
109
|
+
# Stenotype.config.logger #=> custom_logger_instance
|
110
|
+
#
|
111
|
+
# @return [{Logger, CustomLogger}] a logger object. Logger.new(STDOUT) by
|
112
|
+
# default if another is not set during configuration
|
113
|
+
#
|
114
|
+
def logger
|
115
|
+
return config.logger if config.logger
|
116
|
+
|
117
|
+
config.logger || Logger.new(STDOUT)
|
118
|
+
end
|
119
|
+
|
82
120
|
#
|
83
121
|
# @example When at least one target is present
|
84
122
|
# Stenotype.configure do |config|
|
@@ -93,6 +131,8 @@ module Stenotype
|
|
93
131
|
# @raise {Stenotype::NoTargetsSpecifiedError} in case no targets are configured
|
94
132
|
# @return {Array<#publish>} An array of targets implementing method [#publish]
|
95
133
|
#
|
134
|
+
# @todo THIS NEVER GETS CALLED, needs a fix
|
135
|
+
#
|
96
136
|
def targets
|
97
137
|
return config.targets unless config.targets.empty?
|
98
138
|
|
data/lib/stenotype/emitter.rb
CHANGED
@@ -33,11 +33,12 @@ module Stenotype
|
|
33
33
|
end
|
34
34
|
|
35
35
|
#
|
36
|
-
# @!method emit_event(
|
36
|
+
# @!method emit_event(name, attributes = {}, method: caller_locations.first.label, eval_context: nil)
|
37
37
|
# A method injected into target class to manually track events
|
38
38
|
# @!scope instance
|
39
|
-
# @param
|
40
|
-
# @param
|
39
|
+
# @param name {[String, Symbol]} Event name.
|
40
|
+
# @param attributes {Hash} Data to be sent to the targets.
|
41
|
+
# @param method {String} An optional method name.
|
41
42
|
# @param eval_context {Hash} A hash linking object to context handler
|
42
43
|
# @return {Stenotype::Event} An instance of emitted event
|
43
44
|
# @example Usage of emit_event
|
@@ -91,15 +92,14 @@ module Stenotype
|
|
91
92
|
#
|
92
93
|
def self.build_instance_methods(instance_mod)
|
93
94
|
instance_mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
94
|
-
def emit_event(
|
95
|
+
def emit_event(event_name, attributes = {}, method: caller_locations.first.label, eval_context: nil)
|
95
96
|
Stenotype::Event.emit!(
|
97
|
+
event_name,
|
96
98
|
{
|
97
|
-
type: "
|
98
|
-
**data,
|
99
|
-
},
|
100
|
-
options: {
|
99
|
+
type: "instance_method",
|
101
100
|
class: self.class.name,
|
102
|
-
method: method.to_sym
|
101
|
+
method: method.to_sym,
|
102
|
+
**attributes,
|
103
103
|
},
|
104
104
|
eval_context: (eval_context || { klass: self })
|
105
105
|
)
|
@@ -120,12 +120,14 @@ module Stenotype
|
|
120
120
|
proxy.module_eval do
|
121
121
|
define_method(method) do |*args, **rest_args, &block|
|
122
122
|
Stenotype::Event.emit!(
|
123
|
-
|
124
|
-
|
123
|
+
# @todo How do we name such events?
|
124
|
+
"instance_method",
|
125
|
+
{
|
126
|
+
type: "instance_method",
|
125
127
|
class: self.class.name,
|
126
|
-
method: __method__
|
128
|
+
method: __method__,
|
127
129
|
},
|
128
|
-
eval_context: { klass: self }
|
130
|
+
eval_context: { klass: self },
|
129
131
|
)
|
130
132
|
super(*args, **rest_args, &block)
|
131
133
|
end
|
@@ -142,12 +144,14 @@ module Stenotype
|
|
142
144
|
proxy.module_eval do
|
143
145
|
define_method(method) do |*args, **rest_args, &block|
|
144
146
|
Stenotype::Event.emit!(
|
145
|
-
|
146
|
-
|
147
|
+
# @todo How do we name such events?
|
148
|
+
"class_method",
|
149
|
+
{
|
150
|
+
type: "class_method",
|
147
151
|
class: self.name,
|
148
|
-
method: __method__
|
152
|
+
method: __method__,
|
149
153
|
},
|
150
|
-
eval_context: { klass: self }
|
154
|
+
eval_context: { klass: self },
|
151
155
|
)
|
152
156
|
super(*args, **rest_args, &block)
|
153
157
|
end
|
data/lib/stenotype/event.rb
CHANGED
@@ -11,19 +11,31 @@ module Stenotype
|
|
11
11
|
# @example Emit an event using class method
|
12
12
|
# Stenotype::Event.emit!(data, options, eval_context)
|
13
13
|
#
|
14
|
-
# @param
|
15
|
-
# @param
|
16
|
-
# @param
|
17
|
-
# @param dispatcher {#publish} A dispatcher object responding to [#publish]
|
14
|
+
# @param {[String, Symbol]} name Event name.
|
15
|
+
# @param {Hash} attributes Data to be published to the targets.
|
16
|
+
# @param {Hash} eval_context A context having handler defined in {Stenotype::ContextHandlers}.
|
17
|
+
# @param dispatcher {#publish} A dispatcher object responding to [#publish].
|
18
18
|
# @return {Stenotype::Event} An instance of {Stenotype::Event}
|
19
19
|
#
|
20
|
-
def self.emit!(
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
def self.emit!(name, attributes = {}, eval_context: {}, dispatcher: Stenotype.config.dispatcher)
|
21
|
+
return unless Stenotype.config.enabled
|
22
|
+
|
23
|
+
begin
|
24
|
+
event = new(name, attributes, eval_context: eval_context, dispatcher: dispatcher)
|
25
|
+
event.emit!
|
26
|
+
event
|
27
|
+
rescue StandardError => exception
|
28
|
+
#
|
29
|
+
# @todo This is a temporary solution to enable conditional logger fetching
|
30
|
+
# needs a fix to use default Spicerack::Configuration functionality
|
31
|
+
#
|
32
|
+
Stenotype::Configuration.logger.error(exception)
|
33
|
+
|
34
|
+
raise Stenotype::Error unless Stenotype.config.graceful_error_handling
|
35
|
+
end
|
24
36
|
end
|
25
37
|
|
26
|
-
attr_reader :
|
38
|
+
attr_reader :name, :attributes, :eval_context, :dispatcher
|
27
39
|
|
28
40
|
#
|
29
41
|
# @example Create an event
|
@@ -31,15 +43,15 @@ module Stenotype
|
|
31
43
|
# @example Create an event with custom dispatcher
|
32
44
|
# event = Stenotype::Event.new(data, options, eval_context, dispatcher: MyDispatcher.new)
|
33
45
|
#
|
34
|
-
# @param {
|
35
|
-
# @param {Hash}
|
46
|
+
# @param {[String, Symbol]} name Event name.
|
47
|
+
# @param {Hash} attributes Data to be published to the targets.
|
36
48
|
# @param {Hash} eval_context A context having handler defined in {Stenotype::ContextHandlers}.
|
37
49
|
# @param dispatcher {#publish} A dispatcher object responding to [#publish].
|
38
50
|
# @return {Stenotype::Event} An instance of event
|
39
51
|
#
|
40
|
-
def initialize(
|
41
|
-
@
|
42
|
-
@
|
52
|
+
def initialize(name, attributes = {}, eval_context: {}, dispatcher: Stenotype.config.dispatcher)
|
53
|
+
@name = name
|
54
|
+
@attributes = attributes
|
43
55
|
@eval_context = eval_context
|
44
56
|
@dispatcher = dispatcher.new
|
45
57
|
end
|
@@ -48,11 +60,23 @@ module Stenotype
|
|
48
60
|
# Emits a {Stenotype::Event}.
|
49
61
|
#
|
50
62
|
# @example Emit an instance of event
|
51
|
-
# event = Stenotype::Event.new(
|
63
|
+
# event = Stenotype::Event.new('events_name', { key: :value }, eval_context: { controller: ctrl })
|
52
64
|
# event.emit! #=> Publishes the event to targets
|
53
65
|
#
|
54
66
|
def emit!
|
55
|
-
|
67
|
+
return unless Stenotype.config.enabled
|
68
|
+
|
69
|
+
begin
|
70
|
+
dispatcher.publish(self)
|
71
|
+
rescue StandardError => exception
|
72
|
+
#
|
73
|
+
# @todo This is a temporary solution to enable conditional logger fetching
|
74
|
+
# needs a fix to use default Spicerack::Configuration functionality
|
75
|
+
#
|
76
|
+
Stenotype::Configuration.logger.error(exception)
|
77
|
+
|
78
|
+
raise Stenotype::Error unless Stenotype.config.graceful_error_handling
|
79
|
+
end
|
56
80
|
end
|
57
81
|
end
|
58
82
|
end
|
@@ -42,8 +42,8 @@ module Stenotype
|
|
42
42
|
#
|
43
43
|
def serialize
|
44
44
|
{
|
45
|
-
|
46
|
-
**
|
45
|
+
name: event_name,
|
46
|
+
**event_attributes,
|
47
47
|
**default_options,
|
48
48
|
**eval_context_options,
|
49
49
|
}
|
@@ -51,12 +51,12 @@ module Stenotype
|
|
51
51
|
|
52
52
|
private
|
53
53
|
|
54
|
-
def
|
55
|
-
event.
|
54
|
+
def event_name
|
55
|
+
event.name
|
56
56
|
end
|
57
57
|
|
58
|
-
def
|
59
|
-
event.
|
58
|
+
def event_attributes
|
59
|
+
event.attributes
|
60
60
|
end
|
61
61
|
|
62
62
|
def eval_context
|
@@ -20,10 +20,11 @@ module Stenotype
|
|
20
20
|
|
21
21
|
#
|
22
22
|
# Emits and event with given data
|
23
|
-
# @param
|
23
|
+
# @param name {[String, Symbol]} Event name
|
24
|
+
# @todo What is really the name here?
|
24
25
|
#
|
25
|
-
def _record_freshly_event(
|
26
|
-
Stenotype::Event.emit!(
|
26
|
+
def _record_freshly_event(name)
|
27
|
+
Stenotype::Event.emit!(name, { type: "controller_action" }, { eval_context: { controller: self }})
|
27
28
|
end
|
28
29
|
|
29
30
|
#
|
@@ -72,7 +73,7 @@ module Stenotype
|
|
72
73
|
return if delta.empty?
|
73
74
|
|
74
75
|
before_action only: delta do
|
75
|
-
_record_freshly_event(
|
76
|
+
_record_freshly_event("view")
|
76
77
|
end
|
77
78
|
|
78
79
|
_tracked_actions.merge(delta)
|
@@ -110,7 +111,7 @@ module Stenotype
|
|
110
111
|
return if delta.empty?
|
111
112
|
|
112
113
|
before_action only: delta.to_a do
|
113
|
-
_record_freshly_event(
|
114
|
+
_record_freshly_event("view")
|
114
115
|
end
|
115
116
|
|
116
117
|
# merge is a mutating op
|
@@ -35,9 +35,9 @@ module Stenotype
|
|
35
35
|
proxy.module_eval do
|
36
36
|
define_method(:perform) do |*args, **rest_args, &block|
|
37
37
|
Stenotype::Event.emit!(
|
38
|
+
"active_job_#{self.class.name}",
|
38
39
|
{ type: "active_job" },
|
39
|
-
{
|
40
|
-
eval_context: { active_job: self }},
|
40
|
+
{ eval_context: { active_job: self }},
|
41
41
|
)
|
42
42
|
super(*args, **rest_args, &block)
|
43
43
|
end
|
data/lib/stenotype/railtie.rb
CHANGED
@@ -18,6 +18,8 @@ module Stenotype
|
|
18
18
|
|
19
19
|
config.stenotype = Stenotype.config
|
20
20
|
|
21
|
+
config.after_initialize { config.stenotype.targets.each(&:auto_initialize!) } if config.stenotype.rails.auto_adapter_initialization
|
22
|
+
|
21
23
|
if config.stenotype.rails.enable_action_controller_ext
|
22
24
|
ActiveSupport.on_load(:action_controller) do
|
23
25
|
Stenotype::ContextHandlers.register Stenotype::ContextHandlers::Rails::Controller
|
data/lib/stenotype/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stenotype
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roman Kapitonov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -267,6 +267,7 @@ files:
|
|
267
267
|
- lib/stenotype/adapters/base.rb
|
268
268
|
- lib/stenotype/adapters/google_cloud.rb
|
269
269
|
- lib/stenotype/adapters/stdout_adapter.rb
|
270
|
+
- lib/stenotype/at_exit.rb
|
270
271
|
- lib/stenotype/configuration.rb
|
271
272
|
- lib/stenotype/context_handlers.rb
|
272
273
|
- lib/stenotype/context_handlers/base.rb
|