optics-agent 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NzExZTA5Mzc0OGMyNGVhZjkyYjk1ZjViMzlmMmVkMmVhYjNmODI0OA==
5
- data.tar.gz: !binary |-
6
- OGFkMjdjNmJkNTI2M2U2N2NjMzYyMDAxNTdmNWJlOTA4NWNiNDJmZg==
2
+ SHA1:
3
+ metadata.gz: 75440b51ee6807fa478559568ca0fc7934e38c5f
4
+ data.tar.gz: 6c7302b7b48ff60c89f92602663b680502318af0
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NjExNTA5NzE5NTMwOGZlZTMwMWYxMjZkZDJiM2IwY2Y0MDI0NGM0Mjc4NWVh
10
- ZTNmZWU3ODQwODI3YjU3YWFiNmM5NTE4ODBlYjQ3MWViZDlmZmRlYTQ1ZTM3
11
- ZGUxYTczMjVmMzZlZmY0NDUxZWUwNWQ1NzgxNjJkZjEyMWFhYTM=
12
- data.tar.gz: !binary |-
13
- MmJmN2NhYTg2ZGRlNjFmYjRmMDFhYWYyZGQyMGUxMDIxZjZkZDE0MjdhZTg5
14
- NGZkZmRkZmQ4OTIyNjdlODM0ZGI4OWViNGM2OWE4OWM0MmJiYzcxMzFhMzE2
15
- NjY1NjdiMGJiNDc5NTE5Yjg4MjdiZTQ5MTIwZjAwY2U0ZGQ0NDM=
6
+ metadata.gz: d201e91158930766f7efd34210b9af68d4575c658672209363dc8614746577256a66da8e854f5b314b376988f72f65070aa9e898e93dc0e58b4485858d4ba728
7
+ data.tar.gz: 2593d4184b7766bd232f0d950a004ab70b8556af248c2bda482c1eb7e268b20b9f307c0bcc07dd61192b43821df57d492df24e6258e3d0bbf79f299769940696
data/README.md CHANGED
@@ -20,7 +20,25 @@ To your `Gemfile`
20
20
 
21
21
  ### API key
22
22
 
23
- You'll need to run your app with the `OPTICS_API_KEY` environment variable set to the API key of your Apollo Optics service; at the moment Optics is in early access alpha--[get in touch](http://www.apollostack.com/optics) if you want to be part of our early access program.
23
+ You'll need to run your app with the `OPTICS_API_KEY` environment variable set (or set via options) to the API key of your Apollo Optics service; you can get an API key by setting up a service at https://optics.apollodata.com.
24
+
25
+ ### Configuration
26
+
27
+ After creating an agent (see below), you can configure it with
28
+
29
+ ```rb
30
+ agent.set_options(option: value)
31
+ ```
32
+
33
+ Possible options are:
34
+
35
+ - `api_key` - Your API key for the Optics service. This defaults to the OPTICS_API_KEY environment variable, but can be overridden here.
36
+ - `endpoint_url ['https://optics-report.apollodata.com']` - Where to send the reports. Defaults to the production Optics endpoint, or the `OPTICS_ENDPOINT_URL` environment variable if it is set. You shouldn't need to set this unless you are debugging
37
+ - `debug [false]` - Log detailed debugging messages
38
+ - `disable_reporting [false]` - Don't report anything to Optics (useful for testing)
39
+ - `print_reports [false]` - Print JSON versions of the data sent to Optics to the log
40
+ - `schema_report_delay_ms [10000]` - How long to wait before sending a schema report after startup, in, milliseconds
41
+ - `report_interval_ms [60000]` - How often to send reports in milliseconds. Defaults to 1 minute. Minimum 10 seconds. You shouldn't need to set this unless you are debugging.
24
42
 
25
43
  ### Basic Rack/Sinatra
26
44
 
@@ -37,7 +55,7 @@ Register the Rack middleware (say in a `config.ru`):
37
55
  use agent.rack_middleware
38
56
  ```
39
57
 
40
- Register the Graphql middleware:
58
+ Register the GraphQL middleware:
41
59
 
42
60
  ```ruby
43
61
  agent.instrument_schema(YourSchema)
@@ -66,7 +84,7 @@ end
66
84
 
67
85
  The equivalent of the above for Rails is:
68
86
 
69
- Create an agent in `config/apllication.rb`, and register the rack middleware:
87
+ Create an agent in `config/application.rb`, and register the rack middleware:
70
88
 
71
89
  ```ruby
72
90
  module YourApplicationRails
@@ -80,7 +98,7 @@ end
80
98
 
81
99
  ```
82
100
 
83
- Register the Graphql middleware when you create your schema:
101
+ Register the GraphQL middleware when you create your schema:
84
102
 
85
103
  ```ruby
86
104
  Rails.application.config.optics_agent.instrument_schema(YourSchema)
@@ -4,6 +4,7 @@ require 'optics-agent/graphql-middleware'
4
4
  require 'optics-agent/reporting/report_job'
5
5
  require 'optics-agent/reporting/schema_job'
6
6
  require 'optics-agent/reporting/query-trace'
7
+ require 'net/http'
7
8
 
8
9
  module OpticsAgent
9
10
  # XXX: this is a class but acts as a singleton right now.
@@ -20,27 +21,53 @@ module OpticsAgent
20
21
  @query_queue = []
21
22
  @semaphone = Mutex.new
22
23
 
23
- # TODO: make these configurable
24
- @schema_report_delay = 10
25
- @report_interval = 60
24
+ # set defaults
25
+ self.set_options
26
+ end
27
+
28
+ def set_options(
29
+ debug: false,
30
+ disable_reporting: false,
31
+ print_reports: false,
32
+ schema_report_delay_ms: 10 * 1000,
33
+ report_interval_ms: 60 * 1000,
34
+ api_key: ENV['OPTICS_API_KEY'],
35
+ endpoint_url: ENV['OPTICS_ENDPOINT_URL'] || 'https://optics-report.apollodata.com'
36
+ )
37
+ @debug = debug
38
+ @disable_reporting = disable_reporting || !endpoint_url || endpoint_url.nil?
39
+ @print_reports = print_reports
40
+ @schema_report_delay_ms = schema_report_delay_ms
41
+ @report_interval_ms = report_interval_ms
42
+ @api_key = api_key
43
+ @endpoint_url = endpoint_url
26
44
  end
27
45
 
28
46
  def instrument_schema(schema)
29
47
  @schema = schema
48
+ debug "adding middleware to schema"
30
49
  schema.middleware << graphql_middleware
31
50
 
32
- Thread.new do
33
- sleep @schema_report_delay
34
- SchemaJob.new.perform(self)
35
- end
51
+ unless @disable_reporting
52
+ debug "spawning schema thread"
53
+ Thread.new do
54
+ debug "schema thread spawned"
55
+ sleep @schema_report_delay_ms / 1000
56
+ debug "running schema job"
57
+ SchemaJob.new.perform(self)
58
+ end
36
59
 
37
- schedule_report
60
+ schedule_report
61
+ end
38
62
  end
39
63
 
40
64
  def schedule_report
65
+ debug "spawning reporting thread"
41
66
  Thread.new do
67
+ debug "reporting thread spawned"
42
68
  while true
43
- sleep @report_interval
69
+ sleep @report_interval_ms / 1000
70
+ debug "running reporting job"
44
71
  ReportJob.new.perform(self)
45
72
  end
46
73
  end
@@ -48,12 +75,14 @@ module OpticsAgent
48
75
 
49
76
  def add_query(query, rack_env, start_time, end_time)
50
77
  @semaphone.synchronize {
78
+ debug { "adding query to queue, queue length was #{@query_queue.length}" }
51
79
  @query_queue << [query, rack_env, start_time, end_time]
52
80
  }
53
81
  end
54
82
 
55
83
  def clear_query_queue
56
84
  @semaphone.synchronize {
85
+ debug { "clearing query queue, queue length was #{@query_queue.length}" }
57
86
  queue = @query_queue
58
87
  @query_queue = []
59
88
  queue
@@ -68,5 +97,38 @@ module OpticsAgent
68
97
  # graphql middleware doesn't seem to need the agent but certainly could have it
69
98
  OpticsAgent::GraphqlMiddleware.new
70
99
  end
100
+
101
+ def send_message(path, message)
102
+ req = Net::HTTP::Post.new(path)
103
+ req['x-api-key'] = @api_key
104
+ req['user-agent'] = "optics-agent-rb"
105
+
106
+ req.body = message.class.encode(message)
107
+ if @debug || @print_reports
108
+ log "sending message: #{message.class.encode_json(message)}"
109
+ end
110
+
111
+ uri = URI.parse(@endpoint_url)
112
+ http = Net::HTTP.new(uri.host, uri.port)
113
+ http.use_ssl = true
114
+ res = http.request(req)
115
+
116
+ if @debug || @print_reports
117
+ log "got response: #{res.inspect}"
118
+ log "response body: #{res.body.inspect}"
119
+ end
120
+ end
121
+
122
+ def log(message = nil)
123
+ message = yield unless message
124
+ puts "optics-agent: #{message}"
125
+ end
126
+
127
+ def debug(message = nil)
128
+ if @debug
129
+ message = yield unless message
130
+ log "DEBUG: #{message} <#{Process.pid} | #{Thread.current.object_id}>"
131
+ end
132
+ end
71
133
  end
72
134
  end
@@ -9,7 +9,7 @@ module OpticsAgent
9
9
  result = next_middleware.call
10
10
  end_time = Time.now
11
11
 
12
- query = query_context[:optics_agent][:query]
12
+ query = query_context[:optics_agent].query
13
13
  query.report_field(parent_type.to_s, field_definition.name, start_time, end_time)
14
14
 
15
15
  result
@@ -12,27 +12,36 @@ module OpticsAgent
12
12
 
13
13
  # XXX: figure out a way to pass this in here
14
14
  agent = OpticsAgent::Agent.instance
15
+ agent.debug { "rack-middleware: request started" }
15
16
  query = OpticsAgent::Reporting::Query.new
16
17
 
17
18
  # Attach so resolver middleware can access
18
- env[:optics_agent] = {
19
- agent: agent,
20
- query: query
21
- }
22
- env[:optics_agent].define_singleton_method(:with_document) do |document|
23
- self[:query].document = document
24
- self
25
- end
19
+ env[:optics_agent] = RackAgent.new(agent, query)
26
20
 
27
21
  result = @app.call(env)
28
22
 
29
23
  # XXX: this approach means if the user forgets to call with_document
30
24
  # we just never log queries. Can we detect if the request is a graphql one?
25
+ agent.debug { "rack-middleware: request finished" }
31
26
  if (query.document)
27
+ agent.debug { "rack-middleware: adding query to agent" }
32
28
  agent.add_query(query, env, start_time, Time.now)
33
29
  end
34
30
 
35
31
  result
36
32
  end
37
33
  end
34
+
35
+ class RackAgent
36
+ attr_reader :agent, :query
37
+ def initialize(agent, query)
38
+ @agent = agent
39
+ @query = query
40
+ end
41
+
42
+ def with_document(query_string)
43
+ @query.document = query_string
44
+ self
45
+ end
46
+ end
38
47
  end
@@ -1,6 +1,5 @@
1
1
  require 'apollo/optics/proto/reports_pb'
2
2
  require 'optics-agent/reporting/helpers'
3
- require 'optics-agent/reporting/send-message'
4
3
 
5
4
  module OpticsAgent::Reporting
6
5
  # A trace is just a different view of a single query report, with full
@@ -49,8 +48,8 @@ module OpticsAgent::Reporting
49
48
  })
50
49
  end
51
50
 
52
- def send
53
- send_message('/api/ss/traces', @report)
51
+ def send_with(agent)
52
+ agent.send_message('/api/ss/traces', @report)
54
53
  end
55
54
  end
56
55
  end
@@ -1,5 +1,4 @@
1
1
  require 'apollo/optics/proto/reports_pb'
2
- require 'optics-agent/reporting/send-message'
3
2
  require 'optics-agent/reporting/helpers'
4
3
  require 'optics-agent/normalization/latency'
5
4
 
@@ -29,9 +28,9 @@ module OpticsAgent::Reporting
29
28
  @report.realtime_duration || duration_nanos(@report.start_time, @report.end_time)
30
29
  end
31
30
 
32
- def send
31
+ def send_with(agent)
33
32
  self.finish!
34
- send_message('/api/ss/stats', @report)
33
+ agent.send_message('/api/ss/stats', @report)
35
34
  end
36
35
 
37
36
  # XXX: record timing / client
@@ -9,11 +9,11 @@ module OpticsAgent::Reporting
9
9
 
10
10
  # XXX: don't send *every* trace
11
11
  query_trace = QueryTrace.new(*item)
12
- query_trace.send
12
+ query_trace.send_with(agent)
13
13
  end
14
14
 
15
15
  report.decorate_from_schema(agent.schema)
16
- report.send
16
+ report.send_with(agent)
17
17
  end
18
18
  end
19
19
  end
@@ -3,7 +3,6 @@ require 'graphql'
3
3
 
4
4
  require 'apollo/optics/proto/reports_pb'
5
5
  require 'optics-agent/reporting/helpers'
6
- require 'optics-agent/reporting/send-message'
7
6
  require 'optics-agent/instrumentation/query-schema'
8
7
 
9
8
  module OpticsAgent::Reporting
@@ -49,8 +48,8 @@ module OpticsAgent::Reporting
49
48
  types
50
49
  end
51
50
 
52
- def send
53
- send_message('/api/ss/schema', @message)
51
+ def send_with(agent)
52
+ agent.send_message('/api/ss/schema', @message)
54
53
  end
55
54
  end
56
55
  end
@@ -4,7 +4,7 @@ module OpticsAgent::Reporting
4
4
  class SchemaJob
5
5
  def perform(agent)
6
6
  schema = OpticsAgent::Reporting::Schema.new agent.schema
7
- schema.send
7
+ schema.send_with(agent)
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,32 @@
1
+ require 'benchmark'
2
+ require 'graphql'
3
+ require 'optics-agent'
4
+
5
+ require_relative '../support/create_starwars_schema.rb';
6
+
7
+ basic_schema = create_starwars_schema
8
+
9
+ agent = OpticsAgent::Agent.instance
10
+ instrumented_schema = create_starwars_schema
11
+ agent.instrument_schema(instrumented_schema)
12
+
13
+ # just drop reports on the floor
14
+ null_reporter = {}
15
+ null_reporter.define_singleton_method :report_field, lambda { |x,y,z,w| }
16
+
17
+ query_string = GraphQL::Introspection::INTROSPECTION_QUERY
18
+
19
+ Benchmark.bm(7) do |x|
20
+ x.report("No agent") do
21
+ 20.times do
22
+ basic_schema.execute(query_string)
23
+ end
24
+ end
25
+ x.report("With agent") do
26
+ 20.times do
27
+ instrumented_schema.execute(query_string, context: {
28
+ optics_agent: { query: null_reporter }
29
+ })
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,4 @@
1
+ require 'ostruct'
1
2
  require 'optics-agent/graphql-middleware'
2
3
  require 'graphql'
3
4
 
@@ -32,7 +33,7 @@ describe GraphqlMiddleware do
32
33
 
33
34
  query = spy("query")
34
35
  schema.execute('{ person { firstName lastName } }', {
35
- context: { optics_agent: { query: query } }
36
+ context: { optics_agent: OpenStruct.new(query: query) }
36
37
  })
37
38
 
38
39
  expect(query).to have_received(:report_field).exactly(3).times
@@ -0,0 +1,219 @@
1
+ # Adapted from https://github.com/rmosolgo/graphql-ruby/blob/master/spec/support/star_wars_schema.rb
2
+
3
+ class CustomBaseEdge < GraphQL::Relay::Edge
4
+ def upcased_name
5
+ node.name.upcase
6
+ end
7
+
8
+ def upcased_parent_name
9
+ parent.name.upcase
10
+ end
11
+ end
12
+
13
+ def create_starwars_schema
14
+ ship = GraphQL::ObjectType.define do
15
+ name "Ship"
16
+ interfaces [GraphQL::Relay::Node.interface]
17
+ global_id_field :id
18
+ field :name, types.String
19
+ end
20
+
21
+ baseType = GraphQL::ObjectType.define do
22
+ name "Base"
23
+ interfaces [GraphQL::Relay::Node.interface]
24
+ global_id_field :id
25
+ field :name, types.String
26
+ field :planet, types.String
27
+ end
28
+
29
+ # Use an optional block to add fields to the connection type:
30
+ baseConnectionWithTotalCountType = baseType.define_connection do
31
+ name "BasesConnectionWithTotalCount"
32
+ field :totalCount do
33
+ type types.Int
34
+ resolve ->(obj, args, ctx) { obj.nodes.count }
35
+ end
36
+ end
37
+
38
+ customBaseEdgeType = baseType.define_edge do
39
+ name "CustomBaseEdge"
40
+ field :upcasedName, types.String, property: :upcased_name
41
+ field :upcasedParentName, types.String, property: :upcased_parent_name
42
+ field :edgeClassName, types.String do
43
+ resolve ->(obj, args, ctx) { obj.class.name }
44
+ end
45
+ end
46
+
47
+ customEdgeBaseConnectionType = baseType.define_connection(edge_class: CustomBaseEdge, edge_type: customBaseEdgeType) do
48
+ name "CustomEdgeBaseConnection"
49
+
50
+ field :totalCountTimes100 do
51
+ type types.Int
52
+ resolve ->(obj, args, ctx) { obj.nodes.count * 100 }
53
+ end
54
+
55
+ field :fieldName, types.String, resolve: ->(obj, args, ctx) { obj.field.name }
56
+ end
57
+
58
+ faction = GraphQL::ObjectType.define do
59
+ name "Faction"
60
+ interfaces [GraphQL::Relay::Node.interface]
61
+
62
+ field :id, !types.ID, resolve: GraphQL::Relay::GlobalIdResolve.new(type: faction)
63
+ field :name, types.String
64
+ connection :ships, ship.connection_type do
65
+ resolve ->(obj, args, ctx) {
66
+ all_ships = obj.ships.map {|ship_id| STAR_WARS_DATA["Ship"][ship_id] }
67
+ if args[:nameIncludes]
68
+ all_ships = all_ships.select { |ship| ship.name.include?(args[:nameIncludes])}
69
+ end
70
+ all_ships
71
+ }
72
+ # You can define arguments here and use them in the connection
73
+ argument :nameIncludes, types.String
74
+ end
75
+ connection :shipsWithMaxPageSize, ship.connection_type, max_page_size: 2 do
76
+ resolve ->(obj, args, ctx) {
77
+ all_ships = obj.ships.map {|ship_id| STAR_WARS_DATA["Ship"][ship_id] }
78
+ if args[:nameIncludes]
79
+ all_ships = all_ships.select { |ship| ship.name.include?(args[:nameIncludes])}
80
+ end
81
+ all_ships
82
+ }
83
+ # You can define arguments here and use them in the connection
84
+ argument :nameIncludes, types.String
85
+ end
86
+
87
+ connection :bases, baseConnectionWithTotalCountType do
88
+ # Resolve field should return an Array, the Connection
89
+ # will do the rest!
90
+ resolve ->(obj, args, ctx) {
91
+ all_bases = Base.where(id: obj.bases)
92
+ if args[:nameIncludes]
93
+ all_bases = all_bases.where("name LIKE ?", "%#{args[:nameIncludes]}%")
94
+ end
95
+ all_bases
96
+ }
97
+ argument :nameIncludes, types.String
98
+ end
99
+
100
+ connection :basesClone, baseType.connection_type
101
+ connection :basesByName, baseType.connection_type, property: :bases do
102
+ argument :order, types.String, default_value: "name"
103
+ resolve ->(obj, args, ctx) {
104
+ if args[:order].present?
105
+ obj.bases.order(args[:order])
106
+ else
107
+ obj.bases
108
+ end
109
+ }
110
+ end
111
+
112
+ connection :basesWithMaxLimitRelation, baseType.connection_type, max_page_size: 2 do
113
+ resolve ->(object, args, context) { Base.all }
114
+ end
115
+
116
+ connection :basesWithMaxLimitArray, baseType.connection_type, max_page_size: 2 do
117
+ resolve ->(object, args, context) { Base.all.to_a }
118
+ end
119
+
120
+ connection :basesAsSequelDataset, baseConnectionWithTotalCountType do
121
+ argument :nameIncludes, types.String
122
+ resolve ->(obj, args, ctx) {
123
+ all_bases = SequelBase.where(faction_id: obj.id)
124
+ if args[:nameIncludes]
125
+ all_bases = all_bases.where("name LIKE ?", "%#{args[:nameIncludes]}%")
126
+ end
127
+ all_bases
128
+ }
129
+ end
130
+
131
+ connection :basesWithCustomEdge, customEdgeBaseConnectionType, property: :bases
132
+ end
133
+
134
+ # Define a mutation. It will also:
135
+ # - define a derived InputObjectType
136
+ # - define a derived ObjectType (for return)
137
+ # - define a field, accessible from {Mutation#field}
138
+ #
139
+ # The resolve proc takes `inputs, ctx`, where:
140
+ # - `inputs` has the keys defined with `input_field`
141
+ # - `ctx` is the Query context (like normal fields)
142
+ #
143
+ # Notice that you leave out clientMutationId.
144
+ introduceShipMutation = GraphQL::Relay::Mutation.define do
145
+ # Used as the root for derived types:
146
+ name "IntroduceShip"
147
+ description "Add a ship to this faction"
148
+
149
+ # Nested under `input` in the query:
150
+ input_field :shipName, !types.String
151
+ input_field :factionId, !types.ID
152
+
153
+ # Result may have access to these fields:
154
+ return_field :shipEdge, ship.edge_type
155
+ return_field :faction, faction
156
+
157
+ # Here's the mutation operation:
158
+ resolve ->(root_obj, inputs, ctx) {
159
+ faction_id = inputs["factionId"]
160
+ ship = STAR_WARS_DATA.create_ship(inputs["shipName"], faction_id)
161
+ faction = STAR_WARS_DATA["Faction"][faction_id]
162
+ connection_class = GraphQL::Relay::BaseConnection.connection_for_nodes(faction.ships)
163
+ ships_connection = connection_class.new(faction.ships, inputs)
164
+ ship_edge = GraphQL::Relay::Edge.new(ship, ships_connection)
165
+ { shipEdge: ship_edge, faction: faction }
166
+ }
167
+ end
168
+
169
+ queryType = GraphQL::ObjectType.define do
170
+ name "Query"
171
+ field :rebels, faction do
172
+ resolve ->(obj, args, ctx) { STAR_WARS_DATA["Faction"]["1"]}
173
+ end
174
+
175
+ field :empire, faction do
176
+ resolve ->(obj, args, ctx) { STAR_WARS_DATA["Faction"]["2"]}
177
+ end
178
+
179
+ field :largestBase, baseType do
180
+ resolve ->(obj, args, ctx) { Base.find(3) }
181
+ end
182
+
183
+ field :node, GraphQL::Relay::Node.field
184
+ end
185
+
186
+ mutationType = GraphQL::ObjectType.define do
187
+ name "Mutation"
188
+ # The mutation object exposes a field:
189
+ field :introduceShip, field: introduceShipMutation.field
190
+ end
191
+
192
+ starWarsSchema = GraphQL::Schema.define do
193
+ query(queryType)
194
+ mutation(mutationType)
195
+
196
+ resolve_type ->(object, ctx) {
197
+ if object == :test_error
198
+ :not_a_type
199
+ elsif object.is_a?(Base)
200
+ baseType
201
+ elsif STAR_WARS_DATA["Faction"].values.include?(object)
202
+ faction
203
+ elsif STAR_WARS_DATA["Ship"].values.include?(object)
204
+ ship
205
+ else
206
+ nil
207
+ end
208
+ }
209
+
210
+ object_from_id ->(node_id, ctx) do
211
+ type_name, id = GraphQL::Schema::UniqueWithinType.decode(node_id)
212
+ STAR_WARS_DATA[type_name][id]
213
+ end
214
+
215
+ id_from_object ->(object, type, ctx) do
216
+ GraphQL::Schema::UniqueWithinType.encode(type.name, object.id)
217
+ end
218
+ end
219
+ end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: optics-agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
- - ! 'Tom Coleman '
7
+ - 'Tom Coleman '
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
@@ -14,56 +14,56 @@ dependencies:
14
14
  name: graphql
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.19.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.19.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: google-protobuf
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: 3.1.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 3.1.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: 11.3.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 11.3.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: 3.5.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 3.5.0
69
69
  description: An Agent for Apollo Optics, http://optics.apollodata.com
@@ -90,7 +90,7 @@ files:
90
90
  - lib/optics-agent/reporting/report_job.rb
91
91
  - lib/optics-agent/reporting/schema.rb
92
92
  - lib/optics-agent/reporting/schema_job.rb
93
- - lib/optics-agent/reporting/send-message.rb
93
+ - spec/benchmark/benchmark.rb
94
94
  - spec/graphql-middleware_spec.rb
95
95
  - spec/latency_spec.rb
96
96
  - spec/query-normalization_spec.rb
@@ -99,6 +99,7 @@ files:
99
99
  - spec/schema-introspection_spec.rb
100
100
  - spec/schema_spec.rb
101
101
  - spec/spec_helper.rb
102
+ - spec/support/create_starwars_schema.rb
102
103
  homepage: http://rubygems.org/gems/optics-agent
103
104
  licenses:
104
105
  - MIT
@@ -109,12 +110,12 @@ require_paths:
109
110
  - lib
110
111
  required_ruby_version: !ruby/object:Gem::Requirement
111
112
  requirements:
112
- - - ! '>='
113
+ - - ">="
113
114
  - !ruby/object:Gem::Version
114
115
  version: '0'
115
116
  required_rubygems_version: !ruby/object:Gem::Requirement
116
117
  requirements:
117
- - - ! '>='
118
+ - - ">="
118
119
  - !ruby/object:Gem::Version
119
120
  version: '0'
120
121
  requirements: []
@@ -124,6 +125,7 @@ signing_key:
124
125
  specification_version: 4
125
126
  summary: An Agent for Apollo Optics
126
127
  test_files:
128
+ - spec/benchmark/benchmark.rb
127
129
  - spec/graphql-middleware_spec.rb
128
130
  - spec/latency_spec.rb
129
131
  - spec/query-normalization_spec.rb
@@ -132,3 +134,4 @@ test_files:
132
134
  - spec/schema-introspection_spec.rb
133
135
  - spec/schema_spec.rb
134
136
  - spec/spec_helper.rb
137
+ - spec/support/create_starwars_schema.rb
@@ -1,23 +0,0 @@
1
- require 'net/http'
2
-
3
- module OpticsAgent
4
- module Reporting
5
- OPTICS_URL = 'https://optics-report.apollodata.com'
6
- def send_message(path, message)
7
-
8
- req = Net::HTTP::Post.new(path)
9
- req['x-api-key'] = ENV['OPTICS_API_KEY']
10
- req['user-agent'] = "optics-agent-rb"
11
-
12
- req.body = message.class.encode(message)
13
- puts message.class.encode_json(message)
14
-
15
- uri = URI.parse(OPTICS_URL)
16
- http = Net::HTTP.new(uri.host, uri.port)
17
- http.use_ssl = true
18
- res = http.request(req)
19
- p res
20
- p res.body
21
- end
22
- end
23
- end