stenotype 0.1.1 → 0.1.2

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: 5b998a75c7aef576ca3040ad7cd7a07082fddc9cd937b57e3d3e84d807124aba
4
+ data.tar.gz: 29d5bc462c420c881eeeeca851146c74e8f6db1240de777d8e19ca0806274fdd
5
5
  SHA512:
6
- metadata.gz: c025894e106d650dcfe1bab82cf878b89a561eaae8a7eb23246a8d01a34800460a17734f55da518602d504a554b41648f6039d3174b2747d093dba8fbfbb0f26
7
- data.tar.gz: 790e1a50a3fabff8db4c62017a556532b8acf3f1df6a330b91dfafba0e1af1701335f8463688fb8d201b75420542fd6cbba054939d33cd80e400e87b07100ed3
6
+ metadata.gz: 71094a00ecce450e4e2edbbda1327cf2f794c52d5d64bd304b67ec5f2498e49020c0ed4f2a07bc9425d5df8929ebe2d809447ea4b52baca0eb6569af27fcf22a
7
+ data.tar.gz: 1874d642a66cc7a2771fd78e92a2dc3e7aaea9ea520055cc2b7abe5bb2f9bf51dce5989e1498352411d134a371ec8b546ded1e8cb8e3d75b7408eaa340d06cbd
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  *Release Date*: 2019/11/21
4
4
 
5
+ ### 0.1.2: 2019/12/10
6
+
7
+ * 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
8
+ * Makes StdoutAdapter more informative by adding a special line for every entry in the log.
9
+ * Fixes Rails initializer not working after switching to Configurable from Spicerack.
10
+
5
11
  ### 0.1.1: 2019/11/25
6
12
 
7
13
  * Moves all error into top level namespace definition file.
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.2)
5
5
  activesupport (>= 5.0.0)
6
6
  google-cloud-pubsub (~> 1.0.0)
7
7
  spicery (>= 0.19.0, < 1.0)
@@ -96,7 +96,7 @@ GEM
96
96
  googleauth (~> 0.9)
97
97
  grpc (~> 1.24)
98
98
  rly (~> 0.2.3)
99
- google-protobuf (3.11.1)
99
+ google-protobuf (3.11.1-universal-darwin)
100
100
  googleapis-common-protos (1.3.9)
101
101
  google-protobuf (~> 3.0)
102
102
  googleapis-common-protos-types (~> 1.0)
@@ -110,7 +110,7 @@ GEM
110
110
  multi_json (~> 1.11)
111
111
  os (>= 0.9, < 2.0)
112
112
  signet (~> 0.12)
113
- grpc (1.25.0)
113
+ grpc (1.25.0-universal-darwin)
114
114
  google-protobuf (~> 3.8)
115
115
  googleapis-common-protos-types (~> 1.0)
116
116
  grpc-google-iam-v1 (0.6.9)
data/README.md CHANGED
@@ -32,10 +32,18 @@ Stenotype.configure do |config|
32
32
 
33
33
  config.uuid_generator = SecureRandom
34
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
35
+
36
+ config.google_cloud do |gc_config|
37
+ gc_config.project_id = "google_cloud_project_id"
38
+ gc_config.credentials = "path_to_key_json"
39
+ gc_config.topic = "google_cloud_topic"
40
+ gc_config.async = true # either true or false
41
+ end
42
+
43
+ config.rails do |rails_config|
44
+ rails_config.enable_action_controller_ext = true
45
+ rails_config.enable_active_job_ext = true
46
+ end
39
47
  end
40
48
  ```
41
49
 
@@ -51,21 +59,29 @@ An object that must implement method `#uuid`. Used when an event is emitted to g
51
59
 
52
60
  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
61
 
54
- #### config.gc_project_id
62
+ #### config.google_cloud.project_id
55
63
 
56
64
  Google cloud project ID. Please refer to Google Cloud management console to get one.
57
65
 
58
- #### config.gc_credentials
66
+ #### config.google_cloud.credentials
59
67
 
60
68
  Google cloud credentials. Might be obtained from Google Cloud management console.
61
69
 
62
- #### config.gc_topic
70
+ #### config.google_cloud.topic
63
71
 
64
72
  Google Cloud topic used for publishing the events.
65
73
 
66
- #### config.gc_mode
74
+ #### config.google_cloud.async
75
+
76
+ 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.
77
+
78
+ #### config.rails.enable_action_controller_ext
79
+
80
+ Allows to enable/disable Rails ActionController extension
81
+
82
+ #### config.rails.enable_active_job_ext
67
83
 
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.
84
+ Allows to enable/disable Rails ActiveJob extension
69
85
 
70
86
  #### Configuring context handlers
71
87
 
@@ -76,8 +92,8 @@ Each event is emitted in a context which might be an ActionController instance o
76
92
  Emitting an event is as simple as:
77
93
  ```ruby
78
94
  Stenotype::Event.emit!(
79
- data,
80
- options: additional_options,
95
+ "Event Name",
96
+ { attr1: :value1, attr2: :value2 },
81
97
  eval_context: { name_of_registered_context_handler: context_object }
82
98
  )
83
99
  ```
@@ -172,9 +188,9 @@ Stenotype::ContextHandlers.register CustomHandler
172
188
  class PlainRubyClass < BaseClass
173
189
  def some_method(data)
174
190
  event_data = collect_some_data_as_a_hash
175
- emit_event(event_data) # method name will be `some_method`, eval_context: { klass: self }
191
+ emit_event("event_name", event_data) # method name will be `some_method`, eval_context: { klass: self }
176
192
  other_event_data = do_something_else
177
- emit_event(other_event_data, method: :custom_method_name, eval_context: { overriden_handler: self })
193
+ emit_event("other_event_name", other_event_data, method: :custom_method_name, eval_context: { overriden_handler: self })
178
194
  end
179
195
  end
180
196
  ```
@@ -1,65 +1,71 @@
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
+ #
22
+ # To make publishing possible one must specify a list of targets. You could use
23
+ # StdoutAdapter for debug purposes before switching to a production publisher.
24
+ # By default the list of targets is empty and you'll get an error saying
25
+ # that no targets are specified.
26
+ #
27
+ # A config option is available for setting up the targets:
28
+ #
29
+ # config.targets = [Stenotype::Adapters::StdoutAdapter.new]
30
+ #
31
+ # Or using Google Cloud:
32
+ #
33
+ # config.targets = [Stenotype::Adapters::GoogleCloud.new]
34
+ #
35
+ # Or both:
36
+ #
37
+ # config.targets = [
38
+ # Stenotype::Adapters::StdoutAdapter.new,
39
+ # Stenotype::Adapters::GoogleCloud.new
40
+ # ]
41
+ #
42
+ # To be able to use Google Cloud one has to specify Google Cloud credentials:
43
+ #
44
+ # config.google_cloud do |gc_config|
45
+ # gc_config.credentials = "SPECIFY YOUR CREDENTIALS" # path/to/key.json
46
+ # gc_config.project_id = "SPECIFY YOUR PROJECT ID"
47
+ # gc_config.topic = "SPECIFY YOUR TOPIC"
48
+ # gc_config.async = true
49
+ # end
50
+ #
51
+ # Each event is shipped with a UUID generated with SecureRandom by default.
52
+ # This might be changed by using a corresponding config option. Note that
53
+ # uuid_generator expects method #uuid to be implemented
54
+ #
55
+ # config.uuid_generator = SecureRandom
56
+ #
57
+ # In rare cases you might want to get control over how the event is being dispatched.
58
+ # Dispatcher must implement instance method #publish.
59
+ # Which dispatcher to use is controlled by the following config option:
60
+ #
61
+ # config.dispatcher = Stenotype::Dispatcher
62
+ #
63
+ # Add your own context handlers
64
+ #
65
+ # Stenotype::ContextHandlers.register Your::Custom::HandlerClass
66
+ #
67
+ end
62
68
  end
63
69
 
64
70
  # For more usage instructions please refer to either README.md or yard documentation
65
- # in gem repository https://github.com/Freshly/stenotype
71
+ # in gem repository https://github.com/Freshly/stenotype
@@ -37,7 +37,7 @@ module Stenotype
37
37
  # @abstract
38
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
@@ -48,22 +48,22 @@ 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
59
  private
60
60
 
61
- def publish_sync(event_data, **additional_arguments)
62
- topic.publish(event_data, additional_arguments)
61
+ def publish_sync(event_data, **additional_attrs)
62
+ topic.publish(event_data, additional_attrs)
63
63
  end
64
64
 
65
- def publish_async(event_data, **additional_arguments)
66
- topic.publish_async(event_data, additional_arguments) do |result|
65
+ def publish_async(event_data, **additional_attrs)
66
+ topic.publish_async(event_data, additional_attrs) do |result|
67
67
  raise Stenotype::MessageNotPublishedError unless result.succeeded?
68
68
  end
69
69
  end
@@ -31,8 +31,13 @@ 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
36
41
  end
37
42
 
38
43
  private
@@ -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,19 @@ 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)
20
+ def self.emit!(name, attributes = {}, eval_context: {}, dispatcher: Stenotype.config.dispatcher)
21
+ event = new(name, attributes, eval_context: eval_context, dispatcher: dispatcher)
22
22
  event.emit!
23
23
  event
24
24
  end
25
25
 
26
- attr_reader :data, :options, :eval_context, :dispatcher
26
+ attr_reader :name, :attributes, :eval_context, :dispatcher
27
27
 
28
28
  #
29
29
  # @example Create an event
@@ -31,15 +31,15 @@ module Stenotype
31
31
  # @example Create an event with custom dispatcher
32
32
  # event = Stenotype::Event.new(data, options, eval_context, dispatcher: MyDispatcher.new)
33
33
  #
34
- # @param {Hash} data Data to be published to the targets.
35
- # @param {Hash} options A hash of additional options to be tracked.
34
+ # @param {[String, Symbol]} name Event name.
35
+ # @param {Hash} attributes Data to be published to the targets.
36
36
  # @param {Hash} eval_context A context having handler defined in {Stenotype::ContextHandlers}.
37
37
  # @param dispatcher {#publish} A dispatcher object responding to [#publish].
38
38
  # @return {Stenotype::Event} An instance of event
39
39
  #
40
- def initialize(data, options: {}, eval_context: {}, dispatcher: Stenotype.config.dispatcher)
41
- @data = data
42
- @options = options
40
+ def initialize(name, attributes = {}, eval_context: {}, dispatcher: Stenotype.config.dispatcher)
41
+ @name = name
42
+ @attributes = attributes
43
43
  @eval_context = eval_context
44
44
  @dispatcher = dispatcher.new
45
45
  end
@@ -48,7 +48,7 @@ module Stenotype
48
48
  # Emits a {Stenotype::Event}.
49
49
  #
50
50
  # @example Emit an instance of event
51
- # event = Stenotype::Event.new(data, options, eval_context)
51
+ # event = Stenotype::Event.new('events_name', { key: :value }, eval_context: { controller: ctrl })
52
52
  # event.emit! #=> Publishes the event to targets
53
53
  #
54
54
  def emit!
@@ -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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Stenotype
4
4
  # :nodoc:
5
- VERSION = "0.1.1"
5
+ VERSION = "0.1.2"
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.2
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: 2019-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport