rails_distributed_tracing 0.0.2 → 1.0

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: 932ad0b65a26e5aef89cea57fd62cd2c21668c299709ffa1b9ad831b8644876a
4
- data.tar.gz: '09e8453fb7cbea081ebc58e2961ee5a9f02afdb7de799818ddbf5bdbbd1bbf07'
3
+ metadata.gz: abe92b91367b21afe0d77aec53d6da1ee5e9603dfdff83d3e688cb88a838ede1
4
+ data.tar.gz: 6eefcd8908103da02b797d49fd9e6111ad370b12d7c6e40ac924614873c80d5a
5
5
  SHA512:
6
- metadata.gz: 0b81bce1195aaaa5be5d780ade44a851c94984d03001165fb92ccfe19ac5d180a442856cde346c259c677e96d6cebcd4d82712227067c739f94792a568a46c0c
7
- data.tar.gz: 6843bb9073886b8ba3f6ad30c2483a04f875e8c99a06ca8c120c50f43265e70e40e65ab1c0cf1720a81a537b122a8e540d450d1253757534883c366fb769b5e1
6
+ metadata.gz: 335b44ade75fdd58e21b463bb7414f05944de229bb1feed0f94e92e1aa32c72b512de08cbcf22e2e6a72c606c07a83d42ff2c88c679d588998efbe77a20fa37a
7
+ data.tar.gz: f2f949f706b90c500f8ac7b20d604fc6bd4a558f1ea0c2607023b60b6a836e279cda5767c5cfe179190ba7b87d9e9352dc67f1b3368b1de58ed82f5da78cebaa
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.4.0
4
+ - ruby
5
+
6
+ before_install:
7
+ - rvm install 2.4.0
8
+ - rvm use 2.4.0
9
+
10
+ script:
11
+ - "bundle exec rspec"
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Ajit Singh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # rails_distributed_tracing
2
+ Distributed tracing for rails microservices
3
+
4
+ [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=102)](https://opensource.org/licenses/MIT)
5
+ [![Gem Version](https://badge.fury.io/rb/rails_distributed_tracing.svg)](https://badge.fury.io/rb/rails_distributed_tracing)
6
+ ![Gem Downloads](http://ruby-gem-downloads-badge.herokuapp.com/rails_distributed_tracing?type=total)
7
+ [![Build Status](https://travis-ci.org/ajitsing/rails_distributed_tracing.svg?branch=master)](https://travis-ci.org/ajitsing/rails_distributed_tracing)
8
+ [![Twitter Follow](https://img.shields.io/twitter/follow/Ajit5ingh.svg?style=social)](https://twitter.com/Ajit5ingh)
9
+
10
+ ## Installation
11
+ Add this line to Gemfile of your microservice:
12
+ ```ruby
13
+ gem 'rails_distributed_tracing'
14
+ ```
15
+
16
+ ## Configuration
17
+ Add request id tag to log tags in `application.rb`. This config will make sure that the logs are tagged with a request id.
18
+ If the service is origin service, `DistributedTracing.request_id_tag` will create a new request id else it will reuse the request id passed from the origin service.
19
+
20
+ ```ruby
21
+ require 'rails_distributed_tracing'
22
+
23
+ class Application < Rails::Application
24
+ config.log_tags = [DistributedTracing.request_id_tag]
25
+ end
26
+ ```
27
+
28
+ ## Passing request id tag to downstream services
29
+ To make the distributed tracing work every service has to the request id to all its downstream services.
30
+ For example lets assume that we have 3 services:
31
+ `OriginService`, `SecondService` and `ThirdService` .
32
+
33
+ Now a request comes to `OriginService`, the above config will create a new request_id for that request.
34
+ When `OriginService` makes a request to `SecondService` it should pass the same requst_id to it,
35
+ so that the request can be traced. The same should happen when `SecondService` calls the `ThirdService`.
36
+
37
+ The bottomline is whenever there is a communication between two services,
38
+ source service should always pass the request id to the destination service.
39
+
40
+ ## How to pass request id tag to downstream services
41
+ When a request id is generated `rails_distributed_tracing` holds that request id till the request returns the response. You can access that request_id anywhere in your application code with the help of below APIs.
42
+
43
+ ```ruby
44
+ DistributedTracing.current_request_id
45
+ ```
46
+
47
+ or you can directly get it as a request header
48
+
49
+ ```ruby
50
+ DistributedTracing.request_id_header
51
+ #=> {'Request-ID' => '8ed7e37b-94e8-4875-afb4-6b4cf1783817'}
52
+ ```
53
+
54
+ The gem will automatically pick the `Request-ID` header from your request and use it as log tag.
55
+
56
+ Note: Make sure that you always pass the current request id and not the stale one.
57
+
58
+
59
+ ## Contributing
60
+
61
+ 1. Fork it ( https://github.com/ajitsing/rails_distributed_tracing/fork )
62
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
63
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
64
+ 4. Push to the branch (`git push origin my-new-feature`)
65
+ 5. Create a new Pull Request
66
+
67
+
68
+ ## License
69
+ ```LICENSE
70
+ MIT License
71
+
72
+ Copyright (c) 2018 Ajit Singh
73
+
74
+ Permission is hereby granted, free of charge, to any person obtaining a copy
75
+ of this software and associated documentation files (the "Software"), to deal
76
+ in the Software without restriction, including without limitation the rights
77
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
78
+ copies of the Software, and to permit persons to whom the Software is
79
+ furnished to do so, subject to the following conditions:
80
+
81
+ The above copyright notice and this permission notice shall be included in all
82
+ copies or substantial portions of the Software.
83
+
84
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
85
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
86
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
87
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
88
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
89
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
90
+ SOFTWARE.
91
+ ```
92
+
@@ -1,2 +1,5 @@
1
1
  project_root = File.dirname(File.absolute_path(__FILE__))
2
- Dir.glob(project_root + '/rails_distributed_tracing/**/*.rb', &method(:require))
2
+ Dir.glob(project_root + '/rails_distributed_tracing/*.rb', &method(:require))
3
+
4
+ require 'rails_distributed_tracing/plugins/faraday' if defined?(Faraday::Middleware)
5
+ require 'rails_distributed_tracing/plugins/sidekiq' if defined?(Sidekiq)
@@ -1,20 +1,20 @@
1
- require_relative './request_id_store'
1
+ require 'rails_distributed_tracing/trace_id_store'
2
2
 
3
3
  module DistributedTracing
4
- REQUEST_HEADER_KEY = 'Request-ID'
4
+ TRACE_ID = 'Request-ID'.freeze
5
5
 
6
- def self.request_id_tag
6
+ def self.log_tag
7
7
  lambda do |request|
8
- request_id = request.headers[REQUEST_HEADER_KEY] || request.request_id
9
- RequestIDStore.request_id = request_id
8
+ request_id = request.headers[TRACE_ID] || request.request_id
9
+ TraceIdStore.trace_id = request_id
10
10
  end
11
11
  end
12
12
 
13
- def self.request_id_header
14
- {REQUEST_HEADER_KEY => RequestIDStore.request_id}
13
+ def self.trace_id
14
+ TraceIdStore.trace_id
15
15
  end
16
16
 
17
- def self.current_request_id
18
- RequestIDStore.request_id
17
+ def self.trace_id=(id)
18
+ TraceIdStore.trace_id = id
19
19
  end
20
20
  end
@@ -0,0 +1,8 @@
1
+ module DistributedTracing
2
+ class FaradayMiddleware < ::Faraday::Middleware
3
+ def call(env)
4
+ env[:request_headers].merge!({DistributedTracing::TRACE_ID => DistributedTracing.trace_id})
5
+ @app.call(env)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,29 @@
1
+ module DistributedTracing
2
+ module SidekiqMiddleware
3
+ class Client
4
+ def call(worker_class, job, queue, redis_pool)
5
+ job[DistributedTracing::TRACE_ID] = trace_id
6
+ yield
7
+ end
8
+
9
+ private
10
+ def trace_id
11
+ DistributedTracing.trace_id || SecureRandom.uuid
12
+ end
13
+ end
14
+
15
+ class Server
16
+ def call(worker, job, queue)
17
+ logger = worker.logger
18
+
19
+ if logger.respond_to?(:tagged)
20
+ DistributedTracing.trace_id = job[DistributedTracing::TRACE_ID]
21
+ logger.tagged(DistributedTracing.trace_id) {yield}
22
+ DistributedTracing.trace_id= nil
23
+ else
24
+ yield
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ module DistributedTracing
2
+ class TraceIdStore
3
+ def self.trace_id=(id)
4
+ @trace_id = id
5
+ end
6
+
7
+ def self.trace_id
8
+ @trace_id
9
+ end
10
+
11
+ def self.clear!
12
+ @trace_id = nil
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module DistributedTracing
2
- VERSION = '0.0.2'
2
+ VERSION = '1.0'
3
3
  end
@@ -7,16 +7,16 @@ describe DistributedTracing do
7
7
  expect(request).to receive(:request_id).and_return(request_id)
8
8
  expect(request).to receive(:headers).and_return({})
9
9
 
10
- expect(DistributedTracing.request_id_tag.call(request)).to eq(request_id)
10
+ expect(DistributedTracing.log_tag.call(request)).to eq(request_id)
11
11
  end
12
12
 
13
13
  it 'should return request id from header' do
14
14
  request = double('request')
15
15
  request_id = '00bfc934-b429-4606-b0c8-318ffa82e884'
16
16
 
17
- expect(request).to receive(:headers).and_return({DistributedTracing::REQUEST_HEADER_KEY => request_id})
17
+ expect(request).to receive(:headers).and_return({DistributedTracing::TRACE_ID => request_id})
18
18
 
19
- expect(DistributedTracing.request_id_tag.call(request)).to eq(request_id)
19
+ expect(DistributedTracing.log_tag.call(request)).to eq(request_id)
20
20
  end
21
21
  end
22
22
 
@@ -25,24 +25,11 @@ describe DistributedTracing do
25
25
  request = double('request')
26
26
  request_id = '00bfc934-b429-4606-b0c8-318ffa82e884'
27
27
 
28
- expect(request).to receive(:headers).and_return({DistributedTracing::REQUEST_HEADER_KEY => request_id})
28
+ expect(request).to receive(:headers).and_return({DistributedTracing::TRACE_ID => request_id})
29
29
 
30
- DistributedTracing.request_id_tag.call(request)
30
+ DistributedTracing.log_tag.call(request)
31
31
 
32
- expect(DistributedTracing.current_request_id).to eq(request_id)
33
- end
34
- end
35
-
36
- describe '#request_id_header' do
37
- it 'should return request id in a header' do
38
- request = double('request')
39
- request_id = '00bfc934-b429-4606-b0c8-318ffa82e884'
40
-
41
- expect(request).to receive(:headers).and_return({DistributedTracing::REQUEST_HEADER_KEY => request_id})
42
-
43
- DistributedTracing.request_id_tag.call(request)
44
-
45
- expect(DistributedTracing.request_id_header).to eq({DistributedTracing::REQUEST_HEADER_KEY => request_id})
32
+ expect(DistributedTracing.trace_id).to eq(request_id)
46
33
  end
47
34
  end
48
35
  end
@@ -0,0 +1,18 @@
1
+ module Faraday; end
2
+ class Faraday::Middleware
3
+ attr_accessor :app
4
+ end
5
+
6
+ load 'lib/rails_distributed_tracing.rb'
7
+
8
+ describe DistributedTracing::FaradayMiddleware do
9
+ it 'should add trace id header to request headers' do
10
+ DistributedTracing::TraceIdStore.trace_id = '00bfc934-b429-4606-b0c8-318ffa82e884'
11
+ middleware = DistributedTracing::FaradayMiddleware.new
12
+ middleware.app = double(:app)
13
+
14
+ expect(middleware.app).to receive(:call).with({request_headers: {DistributedTracing::TRACE_ID => DistributedTracing.trace_id}})
15
+
16
+ middleware.call({request_headers: {}})
17
+ end
18
+ end
@@ -0,0 +1,55 @@
1
+ module Sidekiq; end
2
+
3
+ load 'lib/rails_distributed_tracing.rb'
4
+
5
+ describe DistributedTracing::SidekiqMiddleware do
6
+ describe DistributedTracing::SidekiqMiddleware::Client do
7
+ it 'should add trace id parameter to job' do
8
+ DistributedTracing::TraceIdStore.trace_id = '00bfc934-b429-4606-b0c8-318ffa82e884'
9
+ middleware = DistributedTracing::SidekiqMiddleware::Client.new
10
+
11
+ job = {}
12
+ middleware.call(nil, job, nil, nil) {}
13
+
14
+ expect(job).to eq({DistributedTracing::TRACE_ID => DistributedTracing.trace_id})
15
+ end
16
+
17
+ it 'should add random trace id parameter to job when request id is not present' do
18
+ middleware = DistributedTracing::SidekiqMiddleware::Client.new
19
+
20
+ job = {}
21
+ middleware.call(nil, job, nil, nil) {}
22
+
23
+ expect(job[DistributedTracing::TRACE_ID]).to_not be_nil
24
+ end
25
+ end
26
+
27
+ describe DistributedTracing::SidekiqMiddleware::Server do
28
+ let(:worker) {double(:worker)}
29
+ let(:logger) {double(:logger)}
30
+ let(:trace_id) {'00bfc934-b429-4606-b0c8-318ffa82e884'}
31
+
32
+ it 'should log trace id as tag for tagger logger' do
33
+ middleware = DistributedTracing::SidekiqMiddleware::Server.new
34
+ job = {DistributedTracing::TRACE_ID => trace_id}
35
+
36
+ expect(worker).to receive(:logger).and_return(logger)
37
+
38
+ expect(DistributedTracing).to receive(:trace_id=).with(trace_id).ordered
39
+ expect(logger).to receive(:tagged).with(trace_id).ordered
40
+ expect(DistributedTracing).to receive(:trace_id=).with(nil).ordered
41
+
42
+ middleware.call(worker, job, nil) {}
43
+ end
44
+
45
+ it 'should skip trace id logging for a non tagged logger' do
46
+ middleware = DistributedTracing::SidekiqMiddleware::Server.new
47
+ job = {DistributedTracing::TRACE_ID => trace_id}
48
+
49
+ expect(worker).to receive(:logger).and_return(double(:logger))
50
+ expect(logger).to_not receive(:tagged)
51
+
52
+ middleware.call(worker, job, nil) {}
53
+ end
54
+ end
55
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_distributed_tracing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: '1.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ajit Singh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-17 00:00:00.000000000 Z
11
+ date: 2018-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -46,14 +46,21 @@ extra_rdoc_files: []
46
46
  files:
47
47
  - ".gitignore"
48
48
  - ".rspec"
49
+ - ".travis.yml"
49
50
  - Gemfile
50
51
  - Gemfile.lock
52
+ - LICENSE
53
+ - README.md
51
54
  - lib/rails_distributed_tracing.rb
52
55
  - lib/rails_distributed_tracing/distributed_tracing.rb
53
- - lib/rails_distributed_tracing/request_id_store.rb
56
+ - lib/rails_distributed_tracing/plugins/faraday.rb
57
+ - lib/rails_distributed_tracing/plugins/sidekiq.rb
58
+ - lib/rails_distributed_tracing/trace_id_store.rb
54
59
  - lib/rails_distributed_tracing/version.rb
55
60
  - rails_distributed_tracing.gemspec
56
61
  - spec/lib/distributed_tracing_spec.rb
62
+ - spec/lib/plugins/faraday_spec.rb
63
+ - spec/lib/plugins/sidekiq_spec.rb
57
64
  - spec/spec_helper.rb
58
65
  homepage: https://github.com/ajitsing/rails_distributed_tracing
59
66
  licenses:
@@ -83,4 +90,6 @@ summary: Microservices distributed tracing The gem generates a request id which
83
90
  of this gem.
84
91
  test_files:
85
92
  - spec/lib/distributed_tracing_spec.rb
93
+ - spec/lib/plugins/faraday_spec.rb
94
+ - spec/lib/plugins/sidekiq_spec.rb
86
95
  - spec/spec_helper.rb
@@ -1,15 +0,0 @@
1
- module DistributedTracing
2
- class RequestIDStore
3
- def self.request_id=(id)
4
- @request_id = id
5
- end
6
-
7
- def self.request_id
8
- @request_id
9
- end
10
-
11
- def self.clear!
12
- @request_id = nil
13
- end
14
- end
15
- end