jcw 0.1.3 → 0.2.3

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: c7621b3db92b4172f29ae46a914d6f5a33611f276dfaa17d1effeff36f16c68b
4
- data.tar.gz: c9ac2ea12ee2862fcb762673dd5285e7422b86fe91c38a39f9fa66bd890fa83c
3
+ metadata.gz: 2b1e12954a296bbc3e7413110a7b151fe38c0d422e156cebbd5ae7157bbe111b
4
+ data.tar.gz: '00488dffa129ca3c4a2b45fb3f8f947f1dec9b4310b8a900813426afa397fc92'
5
5
  SHA512:
6
- metadata.gz: e6558c6b64a50a283c6e9a97024ee8191fd595bb73b071ae84259ec7a61d51ab4046b6f70e33f335bedf7888f791f170375e2b7f3ab428a373259716c9acfe19
7
- data.tar.gz: c5d6da1d532632920fdce571c254737654d0e37c7aca2d89bf8852126ae15882c3f4965461b341ecfcbf04add3a366010b103d5cd83cf2fe1df8b9c71860e15d
6
+ metadata.gz: 61b7221435873848d3bb19e0e9ca30157c127601633fb4ca129fbc150fe5da98f2013bdc334139c455801fcb7fe90db8fb47809a4b1bba86f4e58d8ab1034162
7
+ data.tar.gz: 1140c437317341c6836f196711496f9dedb0e0959571d7f882c9750f6c690ca3026dd807916fd958c7a7628587cea5e985da1b55631f9b4fcbc15691a8cf7e49
@@ -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,29 +1,29 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jcw (0.1.3)
5
- activesupport (>= 5.0)
4
+ jcw (0.2.3)
5
+ activesupport (>= 5.0, < 7.0.0)
6
+ gruf (~> 2.10)
6
7
  httprb-opentracing (~> 0.4.0)
7
8
  jaeger-client (~> 1.1.0)
8
- rack-tracer (~> 0.9.0)
9
9
 
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- actionpack (6.1.4.1)
14
- actionview (= 6.1.4.1)
15
- activesupport (= 6.1.4.1)
13
+ actionpack (6.1.4.4)
14
+ actionview (= 6.1.4.4)
15
+ activesupport (= 6.1.4.4)
16
16
  rack (~> 2.0, >= 2.0.9)
17
17
  rack-test (>= 0.6.3)
18
18
  rails-dom-testing (~> 2.0)
19
19
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
20
- actionview (6.1.4.1)
21
- activesupport (= 6.1.4.1)
20
+ actionview (6.1.4.4)
21
+ activesupport (= 6.1.4.4)
22
22
  builder (~> 3.1)
23
23
  erubi (~> 1.4)
24
24
  rails-dom-testing (~> 2.0)
25
25
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
26
- activesupport (6.1.4.1)
26
+ activesupport (6.1.4.4)
27
27
  concurrent-ruby (~> 1.0, >= 1.0.2)
28
28
  i18n (>= 1.6, < 2)
29
29
  minitest (>= 5.1)
@@ -33,7 +33,7 @@ GEM
33
33
  public_suffix (>= 2.0.2, < 5.0)
34
34
  ast (2.4.2)
35
35
  builder (3.2.4)
36
- bundler-audit (0.8.0)
36
+ bundler-audit (0.9.0.1)
37
37
  bundler (>= 1.2.0, < 3)
38
38
  thor (~> 1.0)
39
39
  coderay (1.1.3)
@@ -43,16 +43,33 @@ GEM
43
43
  docile (1.4.0)
44
44
  domain_name (0.5.20190701)
45
45
  unf (>= 0.0.5, < 1.0.0)
46
+ e2mmap (0.1.0)
46
47
  erubi (1.10.0)
47
- ffi (1.15.3)
48
+ ffi (1.15.4)
48
49
  ffi-compiler (1.0.1)
49
50
  ffi (>= 1.0.0)
50
51
  rake
51
- http (5.0.1)
52
- addressable (~> 2.3)
52
+ google-protobuf (3.19.2)
53
+ googleapis-common-protos-types (1.3.0)
54
+ google-protobuf (~> 3.14)
55
+ grpc (1.41.0)
56
+ google-protobuf (~> 3.17)
57
+ googleapis-common-protos-types (~> 1.0)
58
+ grpc-tools (1.41.0)
59
+ gruf (2.12.0)
60
+ activesupport (> 4)
61
+ concurrent-ruby (> 1)
62
+ e2mmap (>= 0.1)
63
+ grpc (~> 1.10, <= 1.41.0)
64
+ grpc-tools (~> 1.10, <= 1.41.0)
65
+ json (>= 2.3)
66
+ slop (>= 4.6)
67
+ thwait (>= 0.1)
68
+ http (5.0.4)
69
+ addressable (~> 2.8)
53
70
  http-cookie (~> 1.0)
54
71
  http-form_data (~> 2.2)
55
- llhttp-ffi (~> 0.3.0)
72
+ llhttp-ffi (~> 0.4.0)
56
73
  http-cookie (1.0.4)
57
74
  domain_name (~> 0.5)
58
75
  http-form_data (2.3.0)
@@ -60,20 +77,21 @@ GEM
60
77
  ffi-compiler (>= 1.0, < 2.0)
61
78
  httprb-opentracing (0.4.0)
62
79
  opentracing (~> 0.5.0)
63
- i18n (1.8.10)
80
+ i18n (1.8.11)
64
81
  concurrent-ruby (~> 1.0)
65
82
  jaeger-client (1.1.0)
66
83
  opentracing (~> 0.3)
67
84
  thrift
68
- llhttp-ffi (0.3.1)
85
+ json (2.6.1)
86
+ llhttp-ffi (0.4.0)
69
87
  ffi-compiler (~> 1.0)
70
88
  rake (~> 13.0)
71
- loofah (2.12.0)
89
+ loofah (2.13.0)
72
90
  crass (~> 1.0.2)
73
91
  nokogiri (>= 1.5.9)
74
92
  method_source (1.0.0)
75
93
  mini_portile2 (2.6.1)
76
- minitest (5.14.4)
94
+ minitest (5.15.0)
77
95
  nokogiri (1.12.5)
78
96
  mini_portile2 (~> 2.6.1)
79
97
  racc (~> 1.4)
@@ -82,33 +100,33 @@ GEM
82
100
  nokogiri (1.12.5-x86_64-linux)
83
101
  racc (~> 1.4)
84
102
  opentracing (0.5.0)
85
- parallel (1.20.1)
86
- parser (3.0.2.0)
103
+ opentracing_test_tracer (0.1.1)
104
+ opentracing
105
+ parallel (1.21.0)
106
+ parser (3.0.3.2)
87
107
  ast (~> 2.4.1)
88
108
  pry (0.14.1)
89
109
  coderay (~> 1.1)
90
110
  method_source (~> 1.0)
91
111
  public_suffix (4.0.6)
92
- racc (1.5.2)
112
+ racc (1.6.0)
93
113
  rack (2.2.3)
94
114
  rack-test (1.1.0)
95
115
  rack (>= 1.0, < 3)
96
- rack-tracer (0.9.0)
97
- opentracing (~> 0.4)
98
116
  rails-dom-testing (2.0.3)
99
117
  activesupport (>= 4.2.0)
100
118
  nokogiri (>= 1.6)
101
119
  rails-html-sanitizer (1.4.2)
102
120
  loofah (~> 2.3)
103
- railties (6.1.4.1)
104
- actionpack (= 6.1.4.1)
105
- activesupport (= 6.1.4.1)
121
+ railties (6.1.4.4)
122
+ actionpack (= 6.1.4.4)
123
+ activesupport (= 6.1.4.4)
106
124
  method_source
107
125
  rake (>= 0.13)
108
126
  thor (~> 1.0)
109
127
  rainbow (3.0.0)
110
128
  rake (13.0.6)
111
- regexp_parser (2.1.1)
129
+ regexp_parser (2.2.0)
112
130
  rexml (3.2.5)
113
131
  rspec (3.10.0)
114
132
  rspec-core (~> 3.10.0)
@@ -122,7 +140,7 @@ GEM
122
140
  rspec-mocks (3.10.2)
123
141
  diff-lcs (>= 1.2.0, < 2.0)
124
142
  rspec-support (~> 3.10.0)
125
- rspec-support (3.10.2)
143
+ rspec-support (3.10.3)
126
144
  rubocop (1.17.0)
127
145
  parallel (~> 1.10)
128
146
  parser (>= 3.0.0.0)
@@ -132,7 +150,7 @@ GEM
132
150
  rubocop-ast (>= 1.7.0, < 2.0)
133
151
  ruby-progressbar (~> 1.7)
134
152
  unicode-display_width (>= 1.4.0, < 3.0)
135
- rubocop-ast (1.11.0)
153
+ rubocop-ast (1.15.0)
136
154
  parser (>= 3.0.1.1)
137
155
  rubocop-config-umbrellio (1.17.0.53)
138
156
  rubocop (= 1.17.0)
@@ -163,15 +181,18 @@ GEM
163
181
  simplecov-html (0.12.3)
164
182
  simplecov-lcov (0.8.0)
165
183
  simplecov_json_formatter (0.1.3)
184
+ slop (4.9.1)
166
185
  thor (1.1.0)
167
186
  thrift (0.15.0)
187
+ thwait (0.2.0)
188
+ e2mmap
168
189
  tzinfo (2.0.4)
169
190
  concurrent-ruby (~> 1.0)
170
191
  unf (0.1.4)
171
192
  unf_ext
172
- unf_ext (0.0.7.7)
173
- unicode-display_width (2.0.0)
174
- zeitwerk (2.4.2)
193
+ unf_ext (0.0.8)
194
+ unicode-display_width (2.1.0)
195
+ zeitwerk (2.5.1)
175
196
 
176
197
  PLATFORMS
177
198
  ruby
@@ -184,6 +205,7 @@ DEPENDENCIES
184
205
  http
185
206
  http-parser
186
207
  jcw!
208
+ opentracing_test_tracer
187
209
  pry
188
210
  railties
189
211
  rake
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) &middot; [![Gem Version](https://badge.fury.io/rb/jcw.svg)](https://badge.fury.io/rb/jcw)
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
 
@@ -42,10 +42,11 @@ UDP Sender(default):
42
42
  hostname: "custom-hostname",
43
43
  custom_tag: "custom-tag-value",
44
44
  }
45
+ config.rack_ignore_paths = %w[/api/test]
45
46
  end
46
47
 
47
- # Set middleware for wrapping all requests(gem RackTracer)
48
- Rails.application.middleware.use(JCW::RackTracer)
48
+ # Set middleware for wrapping all requests
49
+ Rails.application.middleware.use(JCW::Rack::Tracer)
49
50
  ```
50
51
 
51
52
  TCP Sender:
@@ -59,16 +60,17 @@ TCP Sender:
59
60
  hostname: "custom-hostname",
60
61
  custom_tag: "custom-tag-value",
61
62
  }
63
+ config.rack_ignore_paths = %w[/api/test]
62
64
  end
63
65
 
64
66
  # Set middleware for wrapping all requests
65
- Rails.application.middleware.use(JCW::RackTracer)
67
+ Rails.application.middleware.use(JCW::Rack::Tracer)
66
68
 
67
69
  # If you need send all logs with spans set on_finish_span and extend JaegerLoggerExtension
68
70
  # Not recommended for UDP sender, because default max packet size is 65,000 bytes.
69
71
  Rails.application.config.tap do |config|
70
72
  config.middleware.use(
71
- JCW::RackTracer,
73
+ JCW::Rack::Tracer,
72
74
  on_finish_span: lambda do |span|
73
75
  JCW::Logger.current.logs.each { |log| span.log_kv(**log) }
74
76
  JCW::Logger.current.clear # Do not forget to avoid memory leaks
@@ -80,6 +82,43 @@ end
80
82
  ```
81
83
  - `config.subscribe_to` - not recommended for UDP sender, because default max packet size is 65,000 bytes.
82
84
 
85
+ #### GRPC Integration
86
+
87
+ Client side
88
+
89
+ ```ruby
90
+ # Add JCW::Interceptors::Gruf::Client Interceptor to Gruf Client Initializer
91
+ options = {}
92
+ client_options = { timeout: 10, interceptors: [JCW::Interceptors::Gruf::Client.new] }
93
+
94
+ client = Gruf::Client.new(
95
+ service: Test::Service, options: options, client_options: client_options
96
+ )
97
+
98
+ request_method = "some_method"
99
+ client.call(request_method)
100
+ ```
101
+
102
+ Server side
103
+
104
+ ```ruby
105
+ # Add Server Interceptor
106
+ Rails.configuration.to_prepare do
107
+ Gruf.configure do |config|
108
+ config.interceptors.use(JCW::Interceptors::Gruf::Server)
109
+ end
110
+ end
111
+
112
+ # Configure
113
+ ::JCW::Wrapper.configure do |config|
114
+ config.service_name = "Service Name"
115
+ config.connection = { protocol: :udp, host: "127.0.0.1", port: 6831 }
116
+ config.enabled = true
117
+ config.subscribe_to = [/.*/]
118
+ config.grpc_ignore_methods = %w[grpc.ignore.method]
119
+ end
120
+ ```
121
+
83
122
  ### Contributing
84
123
 
85
124
  - Fork it ( https://github.com/Cado-Labs/jcw )
@@ -95,7 +134,7 @@ Released under MIT License.
95
134
  ## Supporting
96
135
 
97
136
  <a href="https://github.com/Cado-Labs">
98
- <img src="https://github.com/Cado-Labs/cado-labs-logos/blob/main/cado_labs_logo.png" alt="Supported by Cado Labs" />
137
+ <img src="https://github.com/Cado-Labs/cado-labs-resources/blob/main/cado_labs_supporting_rounded.svg" alt="Supported by Cado Labs" />
99
138
  </a>
100
139
 
101
140
  ## 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)/}) }
@@ -22,15 +22,16 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ["lib"]
24
24
 
25
- spec.add_dependency "activesupport", ">= 5.0"
25
+ spec.add_dependency "activesupport", ">= 5.0", "< 7.0.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
- spec.add_dependency "rack-tracer", "~> 0.9.0"
29
29
 
30
30
  spec.add_development_dependency "bundler"
31
31
  spec.add_development_dependency "bundler-audit"
32
32
  spec.add_development_dependency "http"
33
33
  spec.add_development_dependency "http-parser"
34
+ spec.add_development_dependency "opentracing_test_tracer"
34
35
  spec.add_development_dependency "pry"
35
36
  spec.add_development_dependency "railties"
36
37
  spec.add_development_dependency "rake"
@@ -38,4 +39,7 @@ Gem::Specification.new do |spec|
38
39
  spec.add_development_dependency "rubocop-config-umbrellio"
39
40
  spec.add_development_dependency "simplecov"
40
41
  spec.add_development_dependency "simplecov-lcov"
42
+ spec.metadata = {
43
+ "rubygems_mfa_required" => "true",
44
+ }
41
45
  end
data/lib/jcw/config.rb CHANGED
@@ -7,7 +7,9 @@ module JCW
7
7
  :subscribe_to,
8
8
  :connection,
9
9
  :flush_interval,
10
- :tags
10
+ :tags,
11
+ :grpc_ignore_methods,
12
+ :rack_ignore_paths
11
13
 
12
14
  def enabled
13
15
  @enabled ||= false
@@ -34,5 +36,13 @@ module JCW
34
36
  def tags
35
37
  @tags ||= {}
36
38
  end
39
+
40
+ def grpc_ignore_methods
41
+ @grpc_ignore_methods ||= []
42
+ end
43
+
44
+ def rack_ignore_paths
45
+ @rack_ignore_paths ||= []
46
+ end
37
47
  end
38
48
  end
@@ -17,6 +17,7 @@ module JCW
17
17
  host = request.uri.host if request.uri.respond_to?(:host)
18
18
  port = request.uri.port if request.uri.respond_to?(:port)
19
19
  verb = request.verb.to_s.upcase if request.respond_to?(:verb)
20
+ full_path = request.uri.to_s
20
21
 
21
22
  tags = {
22
23
  "component" => "ruby-httprb",
@@ -25,13 +26,15 @@ module JCW
25
26
  "http.url" => path,
26
27
  "peer.host" => host,
27
28
  "peer.port" => port,
29
+ "full_path" => full_path,
28
30
  }.compact
29
31
 
30
32
  tracer = ::HTTP::Tracer.tracer
31
33
 
32
- tracer.start_active_span("http.request", tags: tags) do |scope|
34
+ request_name = "http.request #{verb} #{path}"
35
+ tracer.start_active_span(request_name, tags: tags) do |scope|
33
36
  request.headers.merge!(options.headers)
34
- OpenTracing.inject(scope.span.context, OpenTracing::FORMAT_RACK,
37
+ OpenTracing.inject(scope.span.context, OpenTracing::FORMAT_TEXT_MAP,
35
38
  request.headers)
36
39
 
37
40
  res = perform_without_tracing(request, options)
@@ -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,5 +1,139 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # inspired https://github.com/opentracing-contrib/ruby-rack-tracer/blob/master/lib/rack/tracer.rb
3
4
  module JCW
4
- RackTracer = Class.new(Rack::Tracer)
5
+ module Rack
6
+ class Tracer
7
+ REQUEST_URI = "REQUEST_URI"
8
+ REQUEST_PATH = "REQUEST_PATH"
9
+ REQUEST_METHOD = "REQUEST_METHOD"
10
+
11
+ # Create a new Rack Tracer middleware.
12
+ #
13
+ # @param app The Rack application/middlewares stack.
14
+ # @param tracer [OpenTracing::Tracer] A tracer to be used when start_span, and extract
15
+ # is called.
16
+ # @param on_start_span [Proc, nil] A callback evaluated after a new span is created.
17
+ # @param on_finish_span [Proc, nil] A callback evaluated after a span is finished.
18
+ # @param ignore_paths [Array<Class>] An array of paths to be skiped by the tracer.
19
+ # @param errors [Array<Class>] An array of error classes to be captured by the tracer
20
+ # as errors. Errors are **not** muted by the middleware, they're re-raised afterwards.
21
+ def initialize(app, # rubocop:disable Metrics/ParameterLists
22
+ tracer: OpenTracing.global_tracer,
23
+ on_start_span: nil,
24
+ on_finish_span: nil,
25
+ trust_incoming_span: true,
26
+ ignore_paths: Wrapper.config.rack_ignore_paths,
27
+ errors: [StandardError])
28
+ @app = app
29
+ @tracer = tracer
30
+ @on_start_span = on_start_span
31
+ @on_finish_span = on_finish_span
32
+ @trust_incoming_span = trust_incoming_span
33
+ @errors = errors
34
+ @ignore_paths = ignore_paths
35
+ end
36
+
37
+ def call(env)
38
+ method = env[REQUEST_METHOD]
39
+ path = env[REQUEST_PATH]
40
+ url = env[REQUEST_URI]
41
+ return @app.call(env) if @ignore_paths.include?(path)
42
+
43
+ set_extract_env(env)
44
+ context = @tracer.extract(OpenTracing::FORMAT_TEXT_MAP, env) if @trust_incoming_span
45
+ scope = build_scope(method, url, context)
46
+ span = scope.span
47
+ perform_on_start_span(env, span, @on_start_span)
48
+ call_request(env, span)
49
+ rescue *@errors => error
50
+ build_error_log(span, error)
51
+ raise
52
+ ensure
53
+ begin
54
+ close_scope(scope)
55
+ ensure
56
+ perform_on_finish_span(span)
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def set_extract_env(env)
63
+ env["uber-trace-id"] = env["HTTP_UBER_TRACE_ID"]
64
+ end
65
+
66
+ def build_scope(method, url, context)
67
+ @tracer.start_active_span(
68
+ method,
69
+ child_of: context,
70
+ tags: {
71
+ "component" => "rack",
72
+ "span.kind" => "server",
73
+ "http.method" => method,
74
+ "http.url" => url,
75
+ },
76
+ )
77
+ end
78
+
79
+ def perform_on_start_span(env, span, on_start_span)
80
+ on_start_span&.call(span)
81
+ env["rack.span"] = span
82
+ end
83
+
84
+ def call_request(env, span)
85
+ @app.call(env).tap do |status_code, _headers, _body|
86
+ set_tag(span, status_code, env)
87
+ end
88
+ end
89
+
90
+ def set_tag(span, status_code, env)
91
+ span.set_tag("http.status_code", status_code)
92
+ route = route_from_env(env)
93
+ span.operation_name = route
94
+ end
95
+
96
+ def route_from_env(env)
97
+ method = env[REQUEST_METHOD]
98
+ if (sinatra_route = env["sinatra.route"])
99
+ sinatra_route
100
+ elsif (rails_controller = env["action_controller.instance"])
101
+ "#{method} #{rails_controller.controller_name}/#{rails_controller.action_name}"
102
+ elsif (grape_route_args = env["grape.routing_args"] || env["rack.routing_args"])
103
+ "#{method} #{grape_route_from_args(grape_route_args)}"
104
+ else
105
+ "#{method} #{env[REQUEST_PATH] || env["SCRIPT_NAME"] || env["PATH_INFO"]}".strip
106
+ end
107
+ end
108
+
109
+ def grape_route_from_args(route_args)
110
+ route_info = route_args[:route_info]
111
+ if route_info.respond_to?(:path)
112
+ route_info.path
113
+ elsif (rack_route_options = route_info.instance_variable_get(:@options))
114
+ rack_route_options[:path]
115
+ end
116
+ end
117
+
118
+ def build_error_log(span, error)
119
+ span.set_tag("error", true)
120
+ span.log_kv(
121
+ event: "error",
122
+ "error.kind": error.class.to_s,
123
+ "error.object": error,
124
+ message: error.message,
125
+ stack: error.backtrace.join("\n"),
126
+ )
127
+ end
128
+
129
+ def perform_on_finish_span(span)
130
+ return unless @on_finish_span
131
+ @on_finish_span.call(span)
132
+ end
133
+
134
+ def close_scope(scope)
135
+ scope&.close
136
+ end
137
+ end
138
+ end
5
139
  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.3"
4
+ VERSION = "0.2.3"
5
5
  end
data/lib/jcw/wrapper.rb CHANGED
@@ -21,5 +21,8 @@ require_relative "init"
21
21
  require_relative "subscriber"
22
22
  require_relative "http_tracer"
23
23
  require_relative "rack_tracer"
24
+ require_relative "interceptors/gruf/client"
25
+ require_relative "interceptors/gruf/server"
26
+ require_relative "interceptors/gruf/hpack"
24
27
  require_relative "logger"
25
28
  require_relative "logger_extension"
data/lib/jcw.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rack/tracer"
3
+ require "opentracing"
4
4
  require "jaeger/client"
5
5
  require "active_support"
6
6
  require "httprb-opentracing"
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.3
4
+ version: 0.2.3
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-10-05 00:00:00.000000000 Z
11
+ date: 2022-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -17,6 +17,9 @@ dependencies:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '5.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 7.0.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,48 +27,51 @@ dependencies:
24
27
  - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: '5.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 7.0.0
27
33
  - !ruby/object:Gem::Dependency
28
- name: httprb-opentracing
34
+ name: gruf
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: 0.4.0
39
+ version: '2.10'
34
40
  type: :runtime
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
44
  - - "~>"
39
45
  - !ruby/object:Gem::Version
40
- version: 0.4.0
46
+ version: '2.10'
41
47
  - !ruby/object:Gem::Dependency
42
- name: jaeger-client
48
+ name: httprb-opentracing
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: 1.1.0
53
+ version: 0.4.0
48
54
  type: :runtime
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: 1.1.0
60
+ version: 0.4.0
55
61
  - !ruby/object:Gem::Dependency
56
- name: rack-tracer
62
+ name: jaeger-client
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
65
  - - "~>"
60
66
  - !ruby/object:Gem::Version
61
- version: 0.9.0
67
+ version: 1.1.0
62
68
  type: :runtime
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
72
  - - "~>"
67
73
  - !ruby/object:Gem::Version
68
- version: 0.9.0
74
+ version: 1.1.0
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: bundler
71
77
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +128,20 @@ dependencies:
122
128
  - - ">="
123
129
  - !ruby/object:Gem::Version
124
130
  version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: opentracing_test_tracer
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
125
145
  - !ruby/object:Gem::Dependency
126
146
  name: pry
127
147
  requirement: !ruby/object:Gem::Requirement
@@ -244,6 +264,9 @@ files:
244
264
  - lib/jcw/config.rb
245
265
  - lib/jcw/http_tracer.rb
246
266
  - lib/jcw/init.rb
267
+ - lib/jcw/interceptors/gruf/client.rb
268
+ - lib/jcw/interceptors/gruf/hpack.rb
269
+ - lib/jcw/interceptors/gruf/server.rb
247
270
  - lib/jcw/logger.rb
248
271
  - lib/jcw/logger_extension.rb
249
272
  - lib/jcw/rack_tracer.rb
@@ -253,7 +276,8 @@ files:
253
276
  homepage: https://github.com/Cado-Labs/jcw
254
277
  licenses:
255
278
  - MIT
256
- metadata: {}
279
+ metadata:
280
+ rubygems_mfa_required: 'true'
257
281
  post_install_message:
258
282
  rdoc_options: []
259
283
  require_paths:
@@ -262,7 +286,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
262
286
  requirements:
263
287
  - - ">="
264
288
  - !ruby/object:Gem::Version
265
- version: 2.7.0
289
+ version: 2.6.0
266
290
  required_rubygems_version: !ruby/object:Gem::Requirement
267
291
  requirements:
268
292
  - - ">="