grpc_newrelic_interceptor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4f48d560a64c635ca1a2a5766cdfeca630f653750b42e75155c05f96440ad15e
4
+ data.tar.gz: 6a3760be8b5e0d6f3661f5ff39b40e8980e91cccf2d24eb976000b9c1629fccc
5
+ SHA512:
6
+ metadata.gz: e211b44a114ae8f521c8168e48fec436b88fdc8295befc29f8b26b72f239332fcbad2f7ca4e3e65dfc98513ff3840b137a6a582a11caa3cd4f8011a48a11ca4c
7
+ data.tar.gz: 46ebb1247039200b02bb35a6d39d5282cca0a4f2f14e74b26c317382e1b155ed4b46e9337e69a92a1e7dec4faed9226f6284cf34b5f8749dbf1142f06d11068a
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.2
7
+ before_install: gem install bundler -v 2.0.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in grpc_newrelic_interceptor.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ grpc_newrelic_interceptor (0.0.1)
5
+ grpc
6
+ newrelic_rpm (~> 6.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ coderay (1.1.2)
12
+ diff-lcs (1.3)
13
+ google-protobuf (3.10.0-universal-darwin)
14
+ googleapis-common-protos-types (1.0.4)
15
+ google-protobuf (~> 3.0)
16
+ grpc (1.24.0)
17
+ google-protobuf (~> 3.8)
18
+ googleapis-common-protos-types (~> 1.0)
19
+ method_source (0.9.2)
20
+ newrelic_rpm (6.7.0.359)
21
+ pry (0.12.2)
22
+ coderay (~> 1.1.0)
23
+ method_source (~> 0.9.0)
24
+ pry-doc (1.0.0)
25
+ pry (~> 0.11)
26
+ yard (~> 0.9.11)
27
+ rake (10.5.0)
28
+ rspec (3.9.0)
29
+ rspec-core (~> 3.9.0)
30
+ rspec-expectations (~> 3.9.0)
31
+ rspec-mocks (~> 3.9.0)
32
+ rspec-core (3.9.0)
33
+ rspec-support (~> 3.9.0)
34
+ rspec-expectations (3.9.0)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.9.0)
37
+ rspec-mocks (3.9.0)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.9.0)
40
+ rspec-support (3.9.0)
41
+ yard (0.9.20)
42
+
43
+ PLATFORMS
44
+ ruby
45
+
46
+ DEPENDENCIES
47
+ bundler (~> 2.0)
48
+ google-protobuf
49
+ grpc_newrelic_interceptor!
50
+ pry
51
+ pry-doc
52
+ rake (~> 10.0)
53
+ rspec
54
+
55
+ BUNDLED WITH
56
+ 2.0.2
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Nao Minami
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # GrpcNewrelicInterceptor
2
+ An interceptor for using New Relic with gRPC.
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'grpc_newrelic_interceptor'
10
+ ```
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install grpc_newrelic_interceptor
19
+
20
+ ## Usage
21
+
22
+ ```ruby
23
+ require 'grpc'
24
+ require 'grpc_newrelic_interceptor'
25
+
26
+ NewRelic::Agent.manual_start # start newrelic agent
27
+
28
+ server = GRPC::RpcServer.new(
29
+ interceptors: [
30
+ GrpcNewrelicInterceptor.new,
31
+ ]
32
+ )
33
+ server.handle(MyHandler.new)
34
+ server.run_till_terminated_or_interrupted(['SIGINT'])
35
+ ```
36
+
37
+ ## Development
38
+
39
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
40
+
41
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
42
+
43
+ ## Contributing
44
+
45
+ Bug reports and pull requests are welcome on GitHub at https://github.com/south37/grpc_newrelic_interceptor.
46
+
47
+ ## License
48
+
49
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "grpc_newrelic_interceptor"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,36 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "grpc_newrelic_interceptor/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "grpc_newrelic_interceptor"
7
+ spec.version = GrpcNewrelicInterceptor::VERSION
8
+ spec.authors = ["Nao Minami"]
9
+ spec.email = ["south37777@gmail.com"]
10
+
11
+ spec.summary = %q{An interceptor for using New Relic with gRPC.}
12
+ spec.description = %q{An interceptor for using New Relic with gRPC.}
13
+ spec.homepage = "https://github.com/south37/grpc_newrelic_interceptor"
14
+ spec.license = "MIT"
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://github.com/south37/grpc_newrelic_interceptor"
18
+
19
+ # Specify which files should be added to the gem when it is released.
20
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ end
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.require_paths = ["lib"]
27
+
28
+ spec.add_development_dependency "bundler", "~> 2.0"
29
+ spec.add_development_dependency "rake", "~> 10.0"
30
+ spec.add_development_dependency "rspec"
31
+ spec.add_development_dependency "pry"
32
+ spec.add_development_dependency "pry-doc"
33
+ spec.add_development_dependency "google-protobuf"
34
+ spec.add_dependency "newrelic_rpm", "~> 6.0"
35
+ spec.add_dependency "grpc"
36
+ end
@@ -0,0 +1,11 @@
1
+ require "grpc_newrelic_interceptor/server_interceptor"
2
+ require "grpc_newrelic_interceptor/version"
3
+
4
+ module GrpcNewrelicInterceptor
5
+ class << self
6
+ def new(options = {})
7
+ ServerInterceptor.new(**options)
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,100 @@
1
+ require "newrelic_rpm"
2
+ require "grpc"
3
+
4
+ module GrpcNewrelicInterceptor
5
+ class ServerInterceptor < GRPC::ServerInterceptor
6
+ Request = Struct.new(:path, :user_agent, :request_method)
7
+
8
+ # @param [<#service_name>] ignored_services
9
+ # @param [#filter, nil] params_filter
10
+ def initialize(ignored_services: [], params_filter: nil)
11
+ @ignored_services = Set.new(ignored_services.map(&:service_name))
12
+ @params_filter = params_filter
13
+ end
14
+
15
+ ##
16
+ # Intercept a unary request response call.
17
+ #
18
+ # @param [Object] request
19
+ # @param [GRPC::ActiveCall::SingleReqView] call
20
+ # @param [Method] method
21
+ #
22
+ def request_response(request:, call:, method:)
23
+ return yield if !newrelic_enabled?
24
+
25
+ service_name = get_service_name(method)
26
+
27
+ return yield if @ignored_services.include?(service_name)
28
+
29
+ # NewRelic::Agent::Tracer.in_transaction is introduced in Newrelic v6.0.0.
30
+ # We can use it for custom instrumentation.
31
+ # cf. https://github.com/newrelic/rpm/blob/6.0.0.351/lib/new_relic/agent/tracer.rb#L42-L55
32
+ transaction_options = {
33
+ partial_name: get_partial_name(method),
34
+ category: :rack,
35
+ options: {
36
+ request: get_request(method, call),
37
+ filtered_params: filter(request.to_h),
38
+ }
39
+ }
40
+ NewRelic::Agent::Tracer.in_transaction(transaction_options) do
41
+ yield
42
+ end
43
+ end
44
+
45
+ # NOTE: For now, we don't support server_streamer, client_streamer and bidi_streamer
46
+
47
+ private
48
+
49
+ # @param [Method] method
50
+ # @return [String]
51
+ def get_service_name(method)
52
+ method.owner.service_name
53
+ end
54
+
55
+ # @param [Method] method
56
+ # @return [String]
57
+ def get_partial_name(method)
58
+ "#{method.owner.name}/#{method.name}"
59
+ end
60
+
61
+ # @param [Method] method
62
+ # @param [GRPC::ActiveCall::SingleReqView] call
63
+ # @return [Request]
64
+ def get_request(method, call)
65
+ service_name = get_service_name(method)
66
+
67
+ # path is represented as "/" Service-Name "/" {method name}
68
+ # e.g. /google.pubsub.v2.PublisherService/CreateTopic.
69
+ # cf. https://github.com/grpc/grpc/blob/v1.24.0/doc/PROTOCOL-HTTP2.md
70
+ path = "/#{service_name}/#{camelize(method.name.to_s)}"
71
+
72
+ # gRPC's HTTP method is always POST.
73
+ # cf. https://github.com/grpc/grpc/blob/v1.24.0/doc/PROTOCOL-HTTP2.md
74
+ method = "POST"
75
+
76
+ Request.new(path, call.metadata['user-agent'], method)
77
+ end
78
+
79
+ # @param [String] term
80
+ # @return [String]
81
+ def camelize(term)
82
+ term.split("_").map(&:capitalize).join
83
+ end
84
+
85
+ # @param [Hash] params
86
+ # @return [Hash]
87
+ def filter(params)
88
+ if !@params_filter.nil?
89
+ @params_filter.filter(params)
90
+ else
91
+ params
92
+ end
93
+ end
94
+
95
+ # @return [bool]
96
+ def newrelic_enabled?
97
+ NewRelic::Agent.instance.started?
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,3 @@
1
+ module GrpcNewrelicInterceptor
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: grpc_newrelic_interceptor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nao Minami
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-doc
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: google-protobuf
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: newrelic_rpm
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '6.0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '6.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: grpc
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: An interceptor for using New Relic with gRPC.
126
+ email:
127
+ - south37777@gmail.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".rspec"
134
+ - ".travis.yml"
135
+ - Gemfile
136
+ - Gemfile.lock
137
+ - LICENSE.txt
138
+ - README.md
139
+ - Rakefile
140
+ - bin/console
141
+ - bin/setup
142
+ - grpc_newrelic_interceptor.gemspec
143
+ - lib/grpc_newrelic_interceptor.rb
144
+ - lib/grpc_newrelic_interceptor/server_interceptor.rb
145
+ - lib/grpc_newrelic_interceptor/version.rb
146
+ homepage: https://github.com/south37/grpc_newrelic_interceptor
147
+ licenses:
148
+ - MIT
149
+ metadata:
150
+ homepage_uri: https://github.com/south37/grpc_newrelic_interceptor
151
+ source_code_uri: https://github.com/south37/grpc_newrelic_interceptor
152
+ post_install_message:
153
+ rdoc_options: []
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ requirements: []
167
+ rubygems_version: 3.0.3
168
+ signing_key:
169
+ specification_version: 4
170
+ summary: An interceptor for using New Relic with gRPC.
171
+ test_files: []