optics-agent 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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