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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cad5a62bd56d635becd56bf9bae4d6421879d29952473fd507ae60885ea4723e
4
- data.tar.gz: 0b2d65ef6e1f9a84bd369d908f4133f3787156fcc5a6b46a194b4193fa735411
3
+ metadata.gz: 5f58226124306beb915f76259d055c013e197d24dee87513d751764486ce8033
4
+ data.tar.gz: eee031ad3b4f4b9d5b8ed8645e5d7f676f0490f1f9351cec516ffc72ef5b298a
5
5
  SHA512:
6
- metadata.gz: c025894e106d650dcfe1bab82cf878b89a561eaae8a7eb23246a8d01a34800460a17734f55da518602d504a554b41648f6039d3174b2747d093dba8fbfbb0f26
7
- data.tar.gz: 790e1a50a3fabff8db4c62017a556532b8acf3f1df6a330b91dfafba0e1af1701335f8463688fb8d201b75420542fd6cbba054939d33cd80e400e87b07100ed3
6
+ metadata.gz: fe129ae49b3b255a02f1cadcc6920820348846d0b10dba93ab554322b545401a63c8bce7becd239502e9ff433b127e738ff612d4b1cc9903a0f32212ce68eda1
7
+ data.tar.gz: 275de1f70c2c0f4e9d608e79d93e773d75538b18a47c1f2848a7753bb6151b5f96a8ef7c74b36b3a462360de7be196a247d3be3429cfd7f1b00364691ae01a5e
data/.gitignore CHANGED
@@ -11,3 +11,6 @@
11
11
  .rspec_status
12
12
  /.rakeTasks
13
13
  /.idea
14
+
15
+ # rbenv
16
+ .ruby-version
data/CHANGELOG.md CHANGED
@@ -1,6 +1,31 @@
1
1
  # Changelog
2
2
 
3
- *Release Date*: 2019/11/21
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.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.7)
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 = SecureRandom
34
- config.dispatcher = Stenotype::Dispatcher.new
35
- config.gc_project_id = "google_cloud_project_id"
36
- config.gc_credentials = "path_to_key_json"
37
- config.gc_topic = "google_cloud_topic"
38
- config.gc_mode = :async # either :sync or :async
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.gc_project_id
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.gc_credentials
82
+ #### config.google_cloud.credentials
59
83
 
60
84
  Google cloud credentials. Might be obtained from Google Cloud management console.
61
85
 
62
- #### config.gc_topic
86
+ #### config.google_cloud.topic
63
87
 
64
88
  Google Cloud topic used for publishing the events.
65
89
 
66
- #### config.gc_mode
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
- Google Cloud publish mode. Two options are available: `:sync, :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.
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
- data,
80
- options: additional_options,
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
- # Stenotype allows you to emit events which are then being published to a list of
6
- # targets. Currently two targets are provided by default: Google Cloud Pub Sub and
7
- # STDOUT for debug purposes.
8
- #
9
- # There is also a rails integration module which defines a handy DSL
10
- # for triggering events in various Rails components. ActionController and
11
- # ActiveJob are supported at the time of writing.
12
- #
13
- # Both extensions for Rails are enabled by default, but there are config options
14
- # to control their presence.
15
- # config.stenotype.rails do |rails_modules|
16
- # rails_modules.enable_action_controller_ext = true
17
- # rails_modules.enable_active_job_ext = true
18
- # end
19
- #
20
- #
21
- # To make publishing possible one must specify a list of targets. You could use
22
- # StdoutAdapter for debug purposes before switching to a production publisher.
23
- # By default the list of targets is empty and you'll get an error saying
24
- # that no targets are specified.
25
- #
26
- # A config option is available for setting up the targets:
27
- #
28
- # config.stenotype.targets = [Stenotype::Adapters::StdoutAdapter.new]
29
- #
30
- # Or using Google Cloud:
31
- #
32
- # config.stenotype.targets = [Stenotype::Adapters::GoogleCloud.new]
33
- #
34
- # Or both:
35
- #
36
- # config.stenotype.targets = [
37
- # Stenotype::Adapters::StdoutAdapter.new,
38
- # Stenotype::Adapters::GoogleCloud.new
39
- # ]
40
- #
41
- # To be able to use Google Cloud one has to specify Google Cloud credentials:
42
- #
43
- # config.stenotype.google_cloud do |gc_config|
44
- # gc_config.credentials = "SPECIFY YOUR CREDENTIALS" # path/to/key.json
45
- # gc_config.project_id = "SPECIFY YOUR PROJECT ID"
46
- # gc_config.topic = "SPECIFY YOUR TOPIC"
47
- # gc_config.mode = :async
48
- # end
49
- #
50
- # Each event is shipped with a UUID generated with SecureRandom by default.
51
- # This might be changed by using a corresponding config option. Note that
52
- # uuid_generator expects method #uuid to be implemented
53
- #
54
- # config.stenotype.uuid_generator = SecureRandom
55
- #
56
- # In rare cases you might want to get control over how the event is being dispatched.
57
- # Dispatcher must implement instance method #publish.
58
- # Which dispatcher to use is controlled by the following config option:
59
- #
60
- # config.stenotype.dispatcher = Stenotype::Dispatcher
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 [NotImplementedError] unless implemented in a subclass
38
+ # @raise {NotImplementedError} unless implemented in a subclass
39
39
  #
40
- def publish(_event_data, **_additional_arguments)
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, **additional_arguments)
51
+ def publish(event_data, **additional_attrs)
52
52
  if config.async
53
- publish_async(event_data, **additional_arguments)
53
+ publish_async(event_data, **additional_attrs)
54
54
  else
55
- publish_sync(event_data, **additional_arguments)
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, **additional_arguments)
62
- topic.publish(event_data, additional_arguments)
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, **additional_arguments)
66
- topic.publish_async(event_data, additional_arguments) do |result|
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, **additional_arguments)
35
- client.info(**event_data, **additional_arguments)
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
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+ require "stenotype"
5
+
6
+ at_exit do
7
+ targets = Stenotype.config.targets
8
+ targets.each(&:flush!)
9
+ end
10
+ # :nocov:
@@ -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
 
@@ -33,11 +33,12 @@ module Stenotype
33
33
  end
34
34
 
35
35
  #
36
- # @!method emit_event(data = {}, method: caller_locations.first.label, eval_context: nil)
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 data {Hash} Data to be sent to the targets
40
- # @param method {String} An optional method name
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(data = {}, method: caller_locations.first.label, eval_context: nil)
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: "class_instance",
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
- { type: "class_instance" },
124
- options: {
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
- { type: "class" },
146
- options: {
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
@@ -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 data {Hash} Data to be published to the targets.
15
- # @param options {Hash} A hash of additional options to be tracked.
16
- # @param eval_context {Hash} A context having handler defined in {Stenotype::ContextHandlers}.
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!(data, options: {}, eval_context: {}, dispatcher: Stenotype.config.dispatcher)
21
- event = new(data, options: options, eval_context: eval_context, dispatcher: dispatcher)
22
- event.emit!
23
- event
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 :data, :options, :eval_context, :dispatcher
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 {Hash} data Data to be published to the targets.
35
- # @param {Hash} options A hash of additional options to be tracked.
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(data, options: {}, eval_context: {}, dispatcher: Stenotype.config.dispatcher)
41
- @data = data
42
- @options = options
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(data, options, eval_context)
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
- dispatcher.publish(self)
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
- **event_data,
46
- **event_options,
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 event_data
55
- event.data
54
+ def event_name
55
+ event.name
56
56
  end
57
57
 
58
- def event_options
59
- event.options
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 data {Hash} Data to be sent to targets
23
+ # @param name {[String, Symbol]} Event name
24
+ # @todo What is really the name here?
24
25
  #
25
- def _record_freshly_event(data)
26
- Stenotype::Event.emit!(data, options: {}, eval_context: { controller: self })
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(type: "view")
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(type: "view")
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
- { options: {},
40
- eval_context: { active_job: self }},
40
+ { eval_context: { active_job: self }},
41
41
  )
42
42
  super(*args, **rest_args, &block)
43
43
  end
@@ -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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Stenotype
4
4
  # :nodoc:
5
- VERSION = "0.1.1"
5
+ VERSION = "0.1.7"
6
6
  # :nodoc:
7
7
  end
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.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: 2019-12-09 00:00:00.000000000 Z
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