jcw 0.1.0 → 0.2.1

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: 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