stellate 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/stellate.rb +83 -35
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf645f43b4d1c0d62fd71ce6739b62c5046f84387a4687d34f0dbe5155d16150
4
- data.tar.gz: bea394e5b879a938810d0d0555071032fedd117494af2452be7ad67f9ee4fa6b
3
+ metadata.gz: 1c1a2d292de035b6fce0fd0caa8d9e2c1a03aa5034e8b18e3da3e212f5c1690b
4
+ data.tar.gz: 4e71e1ec928e81c737083c48766644d606180bdb83dee4f41989f201bc8bc135
5
5
  SHA512:
6
- metadata.gz: 87209538300252aa2fde91ebe1fa8b97ed64346aa90d7740fcd07fd5493490326a012d63b13a87b4c1d304f22be283f05ac5d55f9fe2a8b8f308ab41324ff843
7
- data.tar.gz: 247e1efc7ca6bf954e482af75b3dccd587ba7ace9393e699358a936e0fc04d507a9219d9c61db125d6b53c62b692a7bcf15f9f5234c2b9b42a0b388b66cee55a
6
+ metadata.gz: 021e9f325d3434df6ee2d004a06b543cbe475e9784ffc068c544f0d48d45eb44978642d41bf0eda20482629012435d049ccedac9d0c7be39f5ae810aa6652e08
7
+ data.tar.gz: b74619cf8782d5afac11d2f32330ae33dcaa3269b51f5876d01df30884502847160031b49f8445cc50cb02ff43f9b05f4c1c3f140c5d4b418f07762ff1bcf826
data/lib/stellate.rb CHANGED
@@ -4,7 +4,7 @@ require 'uri'
4
4
  require 'net/http'
5
5
 
6
6
  module Stellate
7
- VERSION = '0.0.2'
7
+ VERSION = '1.0.0'
8
8
 
9
9
  # Extend your GraphQL::Schema with this module to enable easy Stellate
10
10
  # Metrics Logging.
@@ -18,14 +18,25 @@ module Stellate
18
18
  # arguments as `GraphQL::Schema.execute()`, and also the following:
19
19
  # - `headers` (`ActionDispatch::Http::Headers`): The HTTP headers from the
20
20
  # incoming request
21
+ # - `callback` (`Method`): If passed, this will be called with a lambda as
22
+ # argument. Calling the passed lambda will log the request to Stellate
23
+ # via HTTP. This is useful if you want to move this request into a non-
24
+ # blocking process (e.g. using Sidekiq) rather than the default behavior
25
+ # of performing a blocking HTTP request which can increase overall
26
+ # response times of your API.
21
27
  def execute_with_logging(query_str = nil, **kwargs)
22
28
  starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
23
29
 
24
- result = execute(query_str, **kwargs.except(:service_name, :token, :headers))
30
+ result = execute(query_str, **kwargs.except(:headers, :callback))
25
31
 
26
32
  ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
27
33
  elapsed = (ending - starting) * 1000
28
34
 
35
+ headers = kwargs[:headers]
36
+ has_headers = headers.is_a?(ActionDispatch::Http::Headers)
37
+
38
+ return result if has_headers && headers['Gcdn-Request-Id'].is_a?(String)
39
+
29
40
  unless @stellate_service_name.is_a?(String)
30
41
  puts 'Missing service name in order to log metrics to Stellate'
31
42
  return result
@@ -43,41 +54,46 @@ module Stellate
43
54
 
44
55
  response = result.to_json
45
56
  payload = {
46
- "operation": query_str,
47
- "variableHash": create_blake3_hash(kwargs[:variables].to_json),
48
- "method": kwargs[:method].is_a?(String) ? kwargs[:method] : 'POST',
49
- "elapsed": elapsed.round,
50
- "responseSize": response.length,
51
- "responseHash": create_blake3_hash(response),
52
- "statusCode": 200,
53
- "operationName": kwargs[:operation_name]
57
+ 'operation' => query_str,
58
+ 'variableHash' => create_blake3_hash(kwargs[:variables].to_json),
59
+ 'method' => kwargs[:method].is_a?(String) ? kwargs[:method] : 'POST',
60
+ 'elapsed' => elapsed.round,
61
+ 'responseSize' => response.length,
62
+ 'responseHash' => create_blake3_hash(response),
63
+ 'statusCode' => 200,
64
+ 'operationName' => kwargs[:operation_name]
54
65
  }
55
66
 
56
67
  errors = result['errors']
57
68
  payload[:errors] = errors if errors.is_a?(Array)
58
69
 
59
- headers = kwargs[:headers]
60
- if headers.is_a?(ActionDispatch::Http::Headers)
70
+ if has_headers
61
71
  forwarded_for = headers['X-Forwarded-For']
62
72
  ips = forwarded_for.is_a?(String) ? forwarded_for.split(',') : []
63
73
 
64
- payload[:id] = ips[0] || headers['True-Client-Ip'] || headers['X-Real-Ip']
65
- payload[:userAgent] = headers['User-Agent']
66
- payload[:referer] = headers['referer']
67
-
74
+ payload['ip'] = ips[0] || headers['True-Client-Ip'] || headers['X-Real-Ip']
75
+ payload['userAgent'] = headers['User-Agent']
76
+ payload['referer'] = headers['referer']
68
77
  end
69
78
 
70
- # TODO: make this an async request to avoid blocking the response
71
- begin
72
- res = Net::HTTP.post(
73
- URI("https://#{@stellate_service_name}.stellate.sh/log"),
74
- payload.to_json,
79
+ stellate_request = {
80
+ 'url' => "https://#{@stellate_service_name}.stellate.sh/log",
81
+ 'headers' => {
75
82
  'Content-Type' => 'application/json',
76
83
  'Stellate-Logging-Token' => @stellate_token
77
- )
78
- puts "Failed to log metrics to Stellate: #{res.body}" if res.code.to_i >= 300
79
- rescue StandardError => e
80
- puts "Failed to log metrics to Stellate: #{e}"
84
+ },
85
+ 'body' => payload.to_json
86
+ }
87
+
88
+ callback = kwargs[:callback]
89
+ # The former check handles methods, the latter handles lambdas
90
+ if callback.is_a?(Method) || callback.respond_to?(:call)
91
+ callback.call(stellate_request)
92
+ # This handles symbols that contain methods
93
+ elsif callback.is_a?(Symbol) && method(callback).is_a?(Method)
94
+ method(callback).call(stellate_request)
95
+ else
96
+ run_stellate_request(stellate_request)
81
97
  end
82
98
 
83
99
  result
@@ -95,7 +111,15 @@ module Stellate
95
111
  # Use this plugin in your GraphQL::Schema to automatically sync your GraphQL
96
112
  # schema with your Stellate service.
97
113
  class SchemaSyncing
98
- def self.use(schema)
114
+ # The first argument is the GraphQLSchema class that this plugin is used
115
+ # on. It accepts the following names arguments:
116
+ # - `callback` (`Method`): If passed, this will be called with a lambda as
117
+ # argument. Calling the passed lambda will sync the schema to Stellate
118
+ # via HTTP. This is useful if you want to move this request into a non-
119
+ # blocking process (e.g. using Sidekiq) rather than the default behavior
120
+ # of performing a blocking HTTP request which can increase overall
121
+ # response times of your API.
122
+ def self.use(schema, **kwargs)
99
123
  unless schema.stellate_service_name.is_a?(String)
100
124
  puts 'Missing service name in order to sync schema to Stellate'
101
125
  return
@@ -108,20 +132,44 @@ module Stellate
108
132
 
109
133
  introspection = JSON.parse(schema.to_json)['data']
110
134
 
111
- # TODO: make this an async request to avoid blocking the request
112
- begin
113
- res = Net::HTTP.post(
114
- URI("https://#{schema.stellate_service_name}.stellate.sh/schema"),
115
- { schema: introspection }.to_json,
135
+ stellate_request = {
136
+ 'url' => "https://#{schema.stellate_service_name}.stellate.sh/schema",
137
+ 'headers' => {
116
138
  'Content-Type' => 'application/json',
117
139
  'Stellate-Schema-Token' => schema.stellate_token
118
- )
119
- puts "Failed to sync schema to Stellate: #{res.body}" if res.code.to_i >= 300
120
- rescue StandardError => e
121
- puts "Failed to sync schema to Stellate: #{e}"
140
+ },
141
+ 'body' => { schema: introspection }.to_json
142
+ }
143
+
144
+ callback = kwargs[:callback]
145
+ # The former check handles methods, the latter handles lambdas
146
+ if callback.is_a?(Method) || callback.respond_to?(:call)
147
+ callback.call(stellate_request)
148
+ # This handles symbols that contain methods
149
+ elsif callback.is_a?(Symbol) && method(callback).is_a?(Method)
150
+ method(callback).call(stellate_request)
151
+ else
152
+ run_stellate_request(stellate_request)
122
153
  end
123
154
  end
124
155
  end
156
+
157
+ def self.run_stellate_request(stellate_request)
158
+ url = URI.parse(stellate_request['url'])
159
+
160
+ http = Net::HTTP.new(url.host, url.port)
161
+ http.use_ssl = true
162
+
163
+ req = Net::HTTP::Post.new(url)
164
+ stellate_request['headers'].each do |key, value|
165
+ req[key] = value
166
+ end
167
+ req.body = stellate_request['body']
168
+ res = http.request(req)
169
+ puts "HTTP request to Stellate failed: #{res.body}" if res.code.to_i >= 300
170
+ rescue StandardError => e
171
+ puts "HTTP request to Stellate failed: #{e}"
172
+ end
125
173
  end
126
174
 
127
175
  def create_blake3_hash(str)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stellate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stellate
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-13 00:00:00.000000000 Z
11
+ date: 2024-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-http