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 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

Constructor Details

#initializeReport

Returns a new instance of Report.



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

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.



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

def report
  @report
end

Instance Method Details

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



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

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



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

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



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

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



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

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



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

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

#send_with(agent) ⇒ Object



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

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