stellate 0.0.3 → 1.1.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 +79 -32
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e0373037e16a2f147c83f1083499e75f740ec4e92e426ca4382d9855227b1eb
4
- data.tar.gz: a1e8ecf717260acb276e5ae32d7997f823830278b48c24f487ab552aed75a77d
3
+ metadata.gz: 809048748b55d20deecab44e78b8bcb941f4cfd641c841d8757aef749483c8fc
4
+ data.tar.gz: a6c0540e65c193d0782d5360ac1024fcf8a44a11d81c45072bafc8875058ea30
5
5
  SHA512:
6
- metadata.gz: 6060f2aa4eed8b6d52f0494496cb9a16bd5471cc88b0c04b1f6d230439071cee1ad228950aaaf819e70755624e74062f19d216b8d3c1a535493a3318808ede28
7
- data.tar.gz: 77328738460721879b96ca8fdcd1a45defe31501e6bbaac4e442f31723107d5daae16b46f99feeb8ca47488b9e578d9e72c8019139e4aac26f8514f5a9dc4e3b
6
+ metadata.gz: 12df26863fbdfe982e1ad5a764504307b7d681d605bc014f248e5aeac273a5b936e54698f99129b738f682182563681ee5331939ec29b55154f570029de94cec
7
+ data.tar.gz: d6239d0fcabdab1736ec238ea7a0de6faf567251c584e3198ccb4585a805aef3df22a756345fec9a1f2c6f36a70afd342e9994b4fca1117c05fa924837196851
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.3'
7
+ VERSION = '1.1.0'
8
8
 
9
9
  # Extend your GraphQL::Schema with this module to enable easy Stellate
10
10
  # Metrics Logging.
@@ -18,10 +18,16 @@ 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
@@ -48,14 +54,14 @@ module Stellate
48
54
 
49
55
  response = result.to_json
50
56
  payload = {
51
- "operation": query_str,
52
- "variableHash": create_blake3_hash(kwargs[:variables].to_json),
53
- "method": kwargs[:method].is_a?(String) ? kwargs[:method] : 'POST',
54
- "elapsed": elapsed.round,
55
- "responseSize": response.length,
56
- "responseHash": create_blake3_hash(response),
57
- "statusCode": 200,
58
- "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]
59
65
  }
60
66
 
61
67
  errors = result['errors']
@@ -65,22 +71,31 @@ module Stellate
65
71
  forwarded_for = headers['X-Forwarded-For']
66
72
  ips = forwarded_for.is_a?(String) ? forwarded_for.split(',') : []
67
73
 
68
- payload[:id] = ips[0] || headers['True-Client-Ip'] || headers['X-Real-Ip']
69
- payload[:userAgent] = headers['User-Agent']
70
- payload[:referer] = headers['referer']
74
+ payload['ip'] = ips[0] || headers['True-Client-Ip'] || headers['X-Real-Ip']
75
+ payload['userAgent'] = headers['User-Agent']
76
+ payload['referer'] = headers['referer']
77
+ payload['graphqlClientName'] = headers['x-graphql-client-name']
78
+ payload['graphqlClientVersion'] = headers['x-graphql-client-version']
71
79
  end
72
80
 
73
- # TODO: make this an async request to avoid blocking the response
74
- begin
75
- res = Net::HTTP.post(
76
- URI("https://#{@stellate_service_name}.stellate.sh/log"),
77
- payload.to_json,
81
+ stellate_request = {
82
+ 'url' => "https://#{@stellate_service_name}.stellate.sh/log",
83
+ 'headers' => {
78
84
  'Content-Type' => 'application/json',
79
85
  'Stellate-Logging-Token' => @stellate_token
80
- )
81
- puts "Failed to log metrics to Stellate: #{res.body}" if res.code.to_i >= 300
82
- rescue StandardError => e
83
- puts "Failed to log metrics to Stellate: #{e}"
86
+ },
87
+ 'body' => payload.to_json
88
+ }
89
+
90
+ callback = kwargs[:callback]
91
+ # The former check handles methods, the latter handles lambdas
92
+ if callback.is_a?(Method) || callback.respond_to?(:call)
93
+ callback.call(stellate_request)
94
+ # This handles symbols that contain methods
95
+ elsif callback.is_a?(Symbol) && method(callback).is_a?(Method)
96
+ method(callback).call(stellate_request)
97
+ else
98
+ run_stellate_request(stellate_request)
84
99
  end
85
100
 
86
101
  result
@@ -98,7 +113,15 @@ module Stellate
98
113
  # Use this plugin in your GraphQL::Schema to automatically sync your GraphQL
99
114
  # schema with your Stellate service.
100
115
  class SchemaSyncing
101
- def self.use(schema)
116
+ # The first argument is the GraphQLSchema class that this plugin is used
117
+ # on. It accepts the following names arguments:
118
+ # - `callback` (`Method`): If passed, this will be called with a lambda as
119
+ # argument. Calling the passed lambda will sync the schema to Stellate
120
+ # via HTTP. This is useful if you want to move this request into a non-
121
+ # blocking process (e.g. using Sidekiq) rather than the default behavior
122
+ # of performing a blocking HTTP request which can increase overall
123
+ # response times of your API.
124
+ def self.use(schema, **kwargs)
102
125
  unless schema.stellate_service_name.is_a?(String)
103
126
  puts 'Missing service name in order to sync schema to Stellate'
104
127
  return
@@ -111,20 +134,44 @@ module Stellate
111
134
 
112
135
  introspection = JSON.parse(schema.to_json)['data']
113
136
 
114
- # TODO: make this an async request to avoid blocking the request
115
- begin
116
- res = Net::HTTP.post(
117
- URI("https://#{schema.stellate_service_name}.stellate.sh/schema"),
118
- { schema: introspection }.to_json,
137
+ stellate_request = {
138
+ 'url' => "https://#{schema.stellate_service_name}.stellate.sh/schema",
139
+ 'headers' => {
119
140
  'Content-Type' => 'application/json',
120
141
  'Stellate-Schema-Token' => schema.stellate_token
121
- )
122
- puts "Failed to sync schema to Stellate: #{res.body}" if res.code.to_i >= 300
123
- rescue StandardError => e
124
- puts "Failed to sync schema to Stellate: #{e}"
142
+ },
143
+ 'body' => { schema: introspection }.to_json
144
+ }
145
+
146
+ callback = kwargs[:callback]
147
+ # The former check handles methods, the latter handles lambdas
148
+ if callback.is_a?(Method) || callback.respond_to?(:call)
149
+ callback.call(stellate_request)
150
+ # This handles symbols that contain methods
151
+ elsif callback.is_a?(Symbol) && method(callback).is_a?(Method)
152
+ method(callback).call(stellate_request)
153
+ else
154
+ run_stellate_request(stellate_request)
125
155
  end
126
156
  end
127
157
  end
158
+
159
+ def self.run_stellate_request(stellate_request)
160
+ url = URI.parse(stellate_request['url'])
161
+
162
+ http = Net::HTTP.new(url.host, url.port)
163
+ http.use_ssl = true
164
+
165
+ req = Net::HTTP::Post.new(url)
166
+ stellate_request['headers'].each do |key, value|
167
+ req[key] = value
168
+ end
169
+ req.body = stellate_request['body']
170
+ res = http.request(req)
171
+ puts "HTTP request to Stellate failed: #{res.body}" if res.code.to_i >= 300
172
+ rescue StandardError => e
173
+ puts "HTTP request to Stellate failed: #{e}"
174
+ end
128
175
  end
129
176
 
130
177
  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.3
4
+ version: 1.1.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-14 00:00:00.000000000 Z
11
+ date: 2024-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-http