jcw 0.1.0 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47920cfcec226ff9785a16c1297f9a7aafc571db02c0d2a2b27f66440d6d874f
4
- data.tar.gz: c90c9a5636ae6c7827074cd1b64329999f21a098d3c04b92fe3a5da085aaaad5
3
+ metadata.gz: bc773311ab088e7276e7fb32a3f4482fe573b1395504aa2a3f65976c2554ee5d
4
+ data.tar.gz: e55467a99786575009b8bb0bd87204c0349517913db982e3367235ef11b5d6ca
5
5
  SHA512:
6
- metadata.gz: 91dea8b748dbc92f865113b8066a57cf84fbf6ccea64ede2dedf9dcc02f2b33f6fe315182efcd209746c00f0889d863239ef86991adba8f946e9f27b8d536b0a
7
- data.tar.gz: 6d8ed800f4b0a113f73546943d0f87bb2ca8ce9b71fc6e6c740c5411c266c94e94dab113e9944ef27db047b067d4dbe194ab782c329d9ac47fd5b99c3239bf58
6
+ metadata.gz: 1dfba6de347759d9dbd0073f7f258b7305a2257a340d26dc2248df54cdaaba7319583b18a281b688356f1fbce4ccd0144cffa7656919803418127d036af829f0
7
+ data.tar.gz: a60b7db65670d6c171acda171c77cc4de936959417d484fd04678d82ed94ed638c59dafca5bc0336d27007d894af7a6ec8cc2057d28f865472520629f7d71782
@@ -41,11 +41,8 @@ jobs:
41
41
  strategy:
42
42
  fail-fast: false
43
43
  matrix:
44
- ruby: [2.7, 2.7.4, 3.0.0, 3.0.1, 3.0.2]
44
+ ruby: [2.6, 2.7, 2.7.4, 3.0.0, 3.0.1, 3.0.2]
45
45
  experimental: [false]
46
- include:
47
- - ruby: head
48
- experimental: true
49
46
 
50
47
  steps:
51
48
  - uses: actions/checkout@v2
data/.rubocop.yml CHANGED
@@ -3,7 +3,7 @@ inherit_gem:
3
3
 
4
4
  AllCops:
5
5
  DisplayCopNames: true
6
- TargetRubyVersion: 2.7
6
+ TargetRubyVersion: 2.6
7
7
 
8
8
  RSpec/EmptyLineAfterHook:
9
9
  Enabled: false
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jcw (0.1.0)
4
+ jcw (0.2.1)
5
5
  activesupport (>= 5.0)
6
+ gruf (~> 2.10)
6
7
  httprb-opentracing (~> 0.4.0)
7
8
  jaeger-client (~> 1.1.0)
8
9
  rack-tracer (~> 0.9.0)
@@ -43,11 +44,28 @@ GEM
43
44
  docile (1.4.0)
44
45
  domain_name (0.5.20190701)
45
46
  unf (>= 0.0.5, < 1.0.0)
47
+ e2mmap (0.1.0)
46
48
  erubi (1.10.0)
47
49
  ffi (1.15.3)
48
50
  ffi-compiler (1.0.1)
49
51
  ffi (>= 1.0.0)
50
52
  rake
53
+ google-protobuf (3.19.1)
54
+ googleapis-common-protos-types (1.3.0)
55
+ google-protobuf (~> 3.14)
56
+ grpc (1.41.1)
57
+ google-protobuf (~> 3.17)
58
+ googleapis-common-protos-types (~> 1.0)
59
+ grpc-tools (1.41.1)
60
+ gruf (2.10.0)
61
+ activesupport (> 4)
62
+ concurrent-ruby (> 1)
63
+ e2mmap (~> 0.1)
64
+ grpc (~> 1.10)
65
+ grpc-tools (~> 1.10)
66
+ json (>= 2.3)
67
+ slop (~> 4.6)
68
+ thwait (~> 0.1)
51
69
  http (5.0.1)
52
70
  addressable (~> 2.3)
53
71
  http-cookie (~> 1.0)
@@ -65,6 +83,7 @@ GEM
65
83
  jaeger-client (1.1.0)
66
84
  opentracing (~> 0.3)
67
85
  thrift
86
+ json (2.6.1)
68
87
  llhttp-ffi (0.3.1)
69
88
  ffi-compiler (~> 1.0)
70
89
  rake (~> 13.0)
@@ -74,12 +93,12 @@ GEM
74
93
  method_source (1.0.0)
75
94
  mini_portile2 (2.6.1)
76
95
  minitest (5.14.4)
77
- nokogiri (1.12.3)
96
+ nokogiri (1.12.5)
78
97
  mini_portile2 (~> 2.6.1)
79
98
  racc (~> 1.4)
80
- nokogiri (1.12.3-x86_64-darwin)
99
+ nokogiri (1.12.5-x86_64-darwin)
81
100
  racc (~> 1.4)
82
- nokogiri (1.12.3-x86_64-linux)
101
+ nokogiri (1.12.5-x86_64-linux)
83
102
  racc (~> 1.4)
84
103
  opentracing (0.5.0)
85
104
  parallel (1.20.1)
@@ -163,8 +182,11 @@ GEM
163
182
  simplecov-html (0.12.3)
164
183
  simplecov-lcov (0.8.0)
165
184
  simplecov_json_formatter (0.1.3)
185
+ slop (4.9.1)
166
186
  thor (1.1.0)
167
- thrift (0.14.2)
187
+ thrift (0.15.0)
188
+ thwait (0.2.0)
189
+ e2mmap
168
190
  tzinfo (2.0.4)
169
191
  concurrent-ruby (~> 1.0)
170
192
  unf (0.1.4)
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # JCW &middot; [![Supporting](https://github.com/Cado-Labs/cado-labs-logos/blob/main/cado_labs_badge.png)](https://github.com/Cado-Labs/) &middot; [![Coverage Status](https://coveralls.io/repos/github/Cado-Labs/jcw/badge.svg?branch=gem-without-zeitwerk)](https://coveralls.io/github/Cado-Labs/jcw?branch=gem-without-zeitwerk)
1
+ # JCW &middot; <a target="_blank" href="https://github.com/Cado-Labs"><img src="https://github.com/Cado-Labs/cado-labs-logos/raw/main/cado_labs_badge.svg" alt="Supported by Cado Labs" style="max-width: 100%; height: 20px"></a> &middot; [![Coverage Status](https://coveralls.io/repos/github/Cado-Labs/jcw/badge.svg?branch=gem-without-zeitwerk)](https://coveralls.io/github/Cado-Labs/jcw?branch=gem-without-zeitwerk) &middot; [![Gem Version](https://badge.fury.io/rb/jcw.svg)](https://badge.fury.io/rb/jcw)
2
2
 
3
3
  Simple wrapper for the gem "jaeger-client" with simpler customization.
4
4
 
@@ -6,7 +6,7 @@ Simple wrapper for the gem "jaeger-client" with simpler customization.
6
6
 
7
7
  <p>
8
8
  <a href="https://github.com/Cado-Labs">
9
- <img src="https://github.com/Cado-Labs/cado-labs-logos/blob/main/cado_labs_supporting.svg" alt="Supported by Cado Labs" />
9
+ <img src="https://github.com/Cado-Labs/cado-labs-resources/blob/main/cado_labs_supporting_rounded.svg" alt="Supported by Cado Labs" />
10
10
  </a>
11
11
  </p>
12
12
 
@@ -25,7 +25,7 @@ gem install jcw
25
25
  ```
26
26
 
27
27
  ```ruby
28
- require 'jcw'
28
+ require 'jcw'
29
29
  ```
30
30
 
31
31
  ## Usage
@@ -68,17 +68,57 @@ Rails.application.middleware.use(JCW::RackTracer)
68
68
  # Not recommended for UDP sender, because default max packet size is 65,000 bytes.
69
69
  Rails.application.config.tap do |config|
70
70
  config.middleware.use(
71
- ::JCW::RackTracer,
72
- on_finish_span:
73
- -> (span) { ::JCW::JaegerLogger.current.logs.each { |log| span.log_kv(**log) } },
71
+ JCW::RackTracer,
72
+ on_finish_span: lambda do |span|
73
+ JCW::Logger.current.logs.each { |log| span.log_kv(**log) }
74
+ JCW::Logger.current.clear # Do not forget to avoid memory leaks
75
+ end,
74
76
  )
75
- config.logger.extend(::JCW::JaegerLoggerExtension)
77
+
78
+ config.logger.extend(JCW::LoggerExtension)
76
79
  end
77
80
  ```
78
81
  - `config.subscribe_to` - not recommended for UDP sender, because default max packet size is 65,000 bytes.
79
82
 
83
+ #### GRPC Integration
84
+
85
+ Client side
86
+
87
+ ```ruby
88
+ # Add JCW::Interceptors::Gruf::Client Interceptor to Gruf Client Initializer
89
+ options = {}
90
+ client_options = { timeout: 10, interceptors: [JCW::Interceptors::Gruf::Client.new] }
91
+
92
+ client = Gruf::Client.new(
93
+ service: Test::Service, options: options, client_options: client_options
94
+ )
95
+
96
+ request_method = "some_method"
97
+ client.call(request_method)
98
+ ```
99
+
100
+ Server side
101
+
102
+ ```ruby
103
+ # Add Server Interceptor
104
+ Rails.configuration.to_prepare do
105
+ Gruf.configure do |config|
106
+ config.interceptors.use(JCW::Interceptors::Gruf::Server)
107
+ end
108
+ end
109
+
110
+ # Configure
111
+ ::JCW::Wrapper.configure do |config|
112
+ config.service_name = "Service Name"
113
+ config.connection = { protocol: :udp, host: "127.0.0.1", port: 6831 }
114
+ config.enabled = true
115
+ config.subscribe_to = [/.*/]
116
+ config.grpc_ignore_methods = %w[grpc.ignore.method]
117
+ end
118
+ ```
119
+
80
120
  ### Contributing
81
-
121
+
82
122
  - Fork it ( https://github.com/Cado-Labs/jcw )
83
123
  - Create your feature branch (`git checkout -b feature/my-new-feature`)
84
124
  - Commit your changes (`git commit -am '[feature_context] Add some feature'`)
@@ -92,7 +132,7 @@ Released under MIT License.
92
132
  ## Supporting
93
133
 
94
134
  <a href="https://github.com/Cado-Labs">
95
- <img src="https://github.com/Cado-Labs/cado-labs-logos/blob/main/cado_labs_logo.png" alt="Supported by Cado Labs" />
135
+ <img src="https://github.com/Cado-Labs/cado-labs-resources/blob/main/cado_labs_supporting_rounded.svg" alt="Supported by Cado Labs" />
96
136
  </a>
97
137
 
98
138
  ## Authors
data/jcw.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = "Wrapper for the gem 'jaeger-client' with simpler customization."
13
13
  spec.homepage = "https://github.com/Cado-Labs/jcw"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
15
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
16
16
 
17
17
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
18
18
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ["lib"]
24
24
 
25
25
  spec.add_dependency "activesupport", ">= 5.0"
26
+ spec.add_dependency "gruf", "~> 2.10"
26
27
  spec.add_dependency "httprb-opentracing", "~> 0.4.0"
27
28
  spec.add_dependency "jaeger-client", "~> 1.1.0"
28
29
  spec.add_dependency "rack-tracer", "~> 0.9.0"
data/lib/jcw/config.rb CHANGED
@@ -7,7 +7,8 @@ module JCW
7
7
  :subscribe_to,
8
8
  :connection,
9
9
  :flush_interval,
10
- :tags
10
+ :tags,
11
+ :grpc_ignore_methods
11
12
 
12
13
  def enabled
13
14
  @enabled ||= false
@@ -34,5 +35,9 @@ module JCW
34
35
  def tags
35
36
  @tags ||= {}
36
37
  end
38
+
39
+ def grpc_ignore_methods
40
+ @grpc_ignore_methods ||= []
41
+ end
37
42
  end
38
43
  end
data/lib/jcw/init.rb CHANGED
@@ -14,7 +14,7 @@ module JCW
14
14
  def init_jaeger_client
15
15
  return unless config.enabled?
16
16
 
17
- reporter = config.connection[:protocol] == :tcp ? tcp_reporter : nil
17
+ reporter = config.connection[:protocol].to_sym == :tcp ? tcp_reporter : nil
18
18
 
19
19
  OpenTracing.global_tracer = Jaeger::Client.build(
20
20
  service_name: config.service_name,
@@ -41,11 +41,10 @@ module JCW
41
41
  end
42
42
 
43
43
  def activate_subscribers
44
- subscribers = config.subscribe_to
45
- return if subscribers.blank?
44
+ events = config.subscribe_to
45
+ return if events.blank?
46
46
 
47
- Tracing.register_subscribers(subscribers)
48
- Tracing.subscribe_tracing_events
47
+ events.each { |event| JCW::Subscriber.subscribe_to_event!(event) }
49
48
  end
50
49
 
51
50
  def init_http_tracer
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "gruf"
4
+
5
+ module JCW
6
+ module Interceptors
7
+ module Gruf
8
+ class Client < ::Gruf::Interceptors::ClientInterceptor
9
+ def call(request_context:)
10
+ tracer = OpenTracing.global_tracer
11
+ metadata = request_context.metadata
12
+
13
+ tags = {
14
+ "component" => "gRPC",
15
+ "span.kind" => "client",
16
+ "grpc.method_type" => "request_response",
17
+ "grpc.headers" => metadata,
18
+ }
19
+
20
+ tracer.start_active_span(request_context.method.to_s, tags: tags) do |current_scope|
21
+ current_span = current_scope.span
22
+ current_span.log_kv(
23
+ event: "request",
24
+ data: request_context.requests.map { |request| request.try(:to_h) },
25
+ )
26
+ hpack_carrier = Hpack.new(metadata)
27
+ tracer.inject(current_span.context, ::OpenTracing::FORMAT_TEXT_MAP, hpack_carrier)
28
+
29
+ yield
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JCW
4
+ module Interceptors
5
+ module Gruf
6
+ class Hpack
7
+ def initialize(wrapped)
8
+ @wrapped = wrapped
9
+ end
10
+
11
+ def [](key)
12
+ @wrapped[key.downcase]
13
+ end
14
+
15
+ def []=(key, value)
16
+ return unless value
17
+
18
+ @wrapped[key.downcase] = value
19
+ end
20
+
21
+ def each(&block)
22
+ @wrapped.each(&block)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "gruf"
4
+
5
+ module JCW
6
+ module Interceptors
7
+ module Gruf
8
+ class Server < ::Gruf::Interceptors::ServerInterceptor
9
+ # rubocop:disable Metrics/MethodLength
10
+ def call
11
+ method = request.method_name
12
+ return yield if Wrapper.config.grpc_ignore_methods.include?(method)
13
+
14
+ tracer = OpenTracing.global_tracer
15
+ on_finish_span = options[:on_finish_span]
16
+ service_class = request.service
17
+ method_name = request.method_key
18
+ name = method_name.to_s.camelize
19
+ route = "/#{service_class.service_name}/#{name}"
20
+
21
+ begin
22
+ tags = {
23
+ "component" => "gRPC",
24
+ "span.kind" => "server",
25
+ "grpc.method_type" => "request_response",
26
+ }
27
+ hpack_carrier = Hpack.new(request.active_call.metadata)
28
+ parent_span_context = tracer.extract(::OpenTracing::FORMAT_TEXT_MAP, hpack_carrier)
29
+ current_scope = tracer.start_active_span(
30
+ route,
31
+ child_of: parent_span_context,
32
+ tags: tags,
33
+ )
34
+ current_span = current_scope.span
35
+ current_span.log_kv(event: "request", data: request.message.to_h)
36
+
37
+ response = yield
38
+
39
+ if response.try(:error_fields)
40
+ current_span.set_tag("error", true)
41
+ current_span.log_kv(event: "error", data: response.to_h)
42
+ end
43
+ rescue => e
44
+ if current_span
45
+ current_span.set_tag("error", true)
46
+ current_span.log_kv(event: "error", error_object: e)
47
+ end
48
+ raise
49
+ ensure
50
+ on_finish_span&.call(current_span)
51
+ current_scope.close if current_span
52
+ end
53
+
54
+ response
55
+ end
56
+ # rubocop:enable Metrics/MethodLength
57
+ end
58
+ end
59
+ end
60
+ end
@@ -1,26 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JCW
4
- class Subscriber
5
- class << self
6
- def subscribe_to_event!(event_name)
7
- ActiveSupport::Notifications.subscribe(event_name) do |*args|
8
- (span = OpenTracing.scope_manager.active&.span) or next
9
- event = ActiveSupport::Notifications::Event.new(*args)
10
- span.log_kv(context: span_context(event))
11
- end
4
+ module Subscriber
5
+ extend self
6
+
7
+ IGNORED_PAYLOAD_KEYS = %i[request response headers exception exception_object].freeze
8
+
9
+ def subscribe_to_event!(event)
10
+ ActiveSupport::Notifications.subscribe(event) do |name, _start, _finish, _uid, payload|
11
+ add(name, payload)
12
12
  end
13
+ end
13
14
 
14
- private
15
+ def add(name, payload)
16
+ # skip Rails internal events
17
+ return if name.start_with?("!")
15
18
 
16
- def span_context(event)
17
- {
18
- name: event.name,
19
- time: event.time,
20
- payload: event.payload.to_s,
21
- transaction_id: event.transaction_id,
22
- }.as_json
19
+ span = OpenTracing.scope_manager.active&.span
20
+ return if span.blank?
21
+
22
+ if payload.is_a?(Hash)
23
+ # we should only mutate the copy of the payload
24
+ payload = payload.dup
25
+ IGNORED_PAYLOAD_KEYS.each { |key| payload.delete(key) if payload.key?(key) }
23
26
  end
27
+
28
+ span.log_kv(message: name, context: JSON.dump(payload))
24
29
  end
25
30
  end
26
31
  end
data/lib/jcw/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JCW
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.1"
5
5
  end
data/lib/jcw/wrapper.rb CHANGED
@@ -17,10 +17,12 @@ module JCW
17
17
  end
18
18
  end
19
19
 
20
- require_relative "tracing"
21
20
  require_relative "init"
22
21
  require_relative "subscriber"
23
22
  require_relative "http_tracer"
24
23
  require_relative "rack_tracer"
24
+ require_relative "interceptors/gruf/client"
25
+ require_relative "interceptors/gruf/server"
26
+ require_relative "interceptors/gruf/hpack"
25
27
  require_relative "logger"
26
28
  require_relative "logger_extension"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jcw
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Starovojtov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-01 00:00:00.000000000 Z
11
+ date: 2021-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: gruf
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.10'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.10'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: httprb-opentracing
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -244,11 +258,13 @@ files:
244
258
  - lib/jcw/config.rb
245
259
  - lib/jcw/http_tracer.rb
246
260
  - lib/jcw/init.rb
261
+ - lib/jcw/interceptors/gruf/client.rb
262
+ - lib/jcw/interceptors/gruf/hpack.rb
263
+ - lib/jcw/interceptors/gruf/server.rb
247
264
  - lib/jcw/logger.rb
248
265
  - lib/jcw/logger_extension.rb
249
266
  - lib/jcw/rack_tracer.rb
250
267
  - lib/jcw/subscriber.rb
251
- - lib/jcw/tracing.rb
252
268
  - lib/jcw/version.rb
253
269
  - lib/jcw/wrapper.rb
254
270
  homepage: https://github.com/Cado-Labs/jcw
@@ -263,7 +279,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
263
279
  requirements:
264
280
  - - ">="
265
281
  - !ruby/object:Gem::Version
266
- version: 2.7.0
282
+ version: 2.6.0
267
283
  required_rubygems_version: !ruby/object:Gem::Requirement
268
284
  requirements:
269
285
  - - ">="
data/lib/jcw/tracing.rb DELETED
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JCW
4
- module Tracing
5
- class << self
6
- attr_reader :subscribers
7
-
8
- def register_subscribers(subscribers)
9
- @subscribers = subscribers
10
- end
11
-
12
- def subscribe_tracing_events
13
- subscribers.each { |subscriber| Subscriber.subscribe_to_event!(subscriber) }
14
- end
15
- end
16
- end
17
- end