Class: OpticsAgent::Reporting::Report

Inherits:
Object
  • Object
show all
Includes:
Apollo::Optics::Proto, Normalization, OpticsAgent::Reporting
Defined in:
lib/optics-agent/reporting/report.rb

Overview

This class represents a complete report that we send to the optics server It pretty closely wraps the StatsReport protobuf message with a few convenience methods

Constant Summary

Constants included from OpticsAgent::Reporting

OPTICS_URL

Constants included from Apollo::Optics::Proto

Apollo::Optics::Proto::Error, Apollo::Optics::Proto::Field, Apollo::Optics::Proto::FieldStat, Apollo::Optics::Proto::Id128, Apollo::Optics::Proto::ReportHeader, Apollo::Optics::Proto::SchemaReport, Apollo::Optics::Proto::StatsPerClientName, Apollo::Optics::Proto::StatsPerSignature, Apollo::Optics::Proto::StatsReport, Apollo::Optics::Proto::Timestamp, Apollo::Optics::Proto::Trace, Apollo::Optics::Proto::TracesReport, Apollo::Optics::Proto::Type, Apollo::Optics::Proto::TypeStat

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Normalization

#empty_latency_count, #latency_bucket

Methods included from OpticsAgent::Reporting

#add_latency, #client_info, #duration_nanos, #generate_report_header, #generate_timestamp, #send_message

Constructor Details

#initializeReport

Returns a new instance of Report.



17
18
19
20
21
22
23
24
25
# File 'lib/optics-agent/reporting/report.rb', line 17

def initialize
  # internal report that we encapsulate
  @report = StatsReport.new({
    header: ReportHeader.new({
      agent_version: '1'
    }),
    start_time: generate_timestamp(Time.now)
  })
end

Instance Attribute Details

#reportObject

Returns the value of attribute report.



15
16
17
# File 'lib/optics-agent/reporting/report.rb', line 15

def report
  @report
end

Instance Method Details

#add_client_stats(signature_stats, rack_env, start_time, end_time) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/optics-agent/reporting/report.rb', line 46

def add_client_stats(signature_stats, rack_env, start_time, end_time)
  info = client_info(rack_env)
  signature_stats.per_client_name[info[:client_name]] ||= StatsPerClientName.new({
    latency_count: empty_latency_count,
    error_count: empty_latency_count
  })
  client_stats = signature_stats.per_client_name[info[:client_name]]

  # XXX: handle errors
  add_latency(client_stats.latency_count, start_time, end_time)

  client_stats.count_per_version[info[:client_version]] ||= 0
  client_stats.count_per_version[info[:client_version]] += 1
end

#add_query(query, rack_env, start_time, end_time) ⇒ Object

XXX: record timing / client



38
39
40
41
42
43
44
# File 'lib/optics-agent/reporting/report.rb', line 38

def add_query(query, rack_env, start_time, end_time)
  @report.per_signature[query.signature] ||= StatsPerSignature.new
  signature_stats = @report.per_signature[query.signature]

  add_client_stats(signature_stats, rack_env, start_time, end_time)
  query.add_to_stats(signature_stats)
end

#decorate_from_schema(schema) ⇒ Object

take a graphql schema and add returnTypes to all the fields on our report



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/optics-agent/reporting/report.rb', line 62

def decorate_from_schema(schema)
  each_field do |type_stat, field_stat|
    # short circuit for special fields
    field_stat.returnType = type_stat.name if field_stat.name == '__typename'

    if type_stat.name == 'Query'
      field_stat.returnType = '__Type' if field_stat.name == '__type'
      field_stat.returnType = '__Schema' if field_stat.name == '__schema'
    end

    if field_stat.returnType.empty?
      type = schema.types[type_stat.name]
      throw "Type #{type_stat.name} not found!" unless type

      field = type.fields[field_stat.name]
      throw "Field #{type_stat.name}.#{field_stat.name} not found!" unless field

      field_stat.returnType = field.type.to_s
    end
  end
end

#each_fieldObject

do something once per field we’ve collected



85
86
87
88
89
90
91
92
93
# File 'lib/optics-agent/reporting/report.rb', line 85

def each_field
  @report.per_signature.values.each do |sps|
    sps.per_type.each do |type|
      type.field.each do |field|
        yield type, field
      end
    end
  end
end

#finish!Object



27
28
29
30
# File 'lib/optics-agent/reporting/report.rb', line 27

def finish!
  @report.end_time ||= generate_timestamp(Time.now)
  @report.realtime_duration || duration_nanos(@report.start_time, @report.end_time)
end

#sendObject



32
33
34
35
# File 'lib/optics-agent/reporting/report.rb', line 32

def send
  self.finish!
  send_message('/api/ss/stats', @report)
end