Skip to content

fix: missing agent_id in ReportHeader #195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 129 additions & 6 deletions proto/reports.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ syntax = "proto3";

import "google/protobuf/timestamp.proto";



package Report;

message Trace {
Expand Down Expand Up @@ -198,6 +200,26 @@ message Trace {
}
}

// The cost of the operation
message Limits {
// The result of the operation.
string result = 1;
// The strategy used in cost calculations.
string strategy = 2;
// The estimated cost as calculated via the strategy specified in strategy
uint64 cost_estimated = 3;
// The actual cost using the strategy specified in strategy
uint64 cost_actual = 4;
// The depth of the query
uint64 depth = 5;
// The height of the query
uint64 height = 6;
// The number of aliases in the query
uint64 alias_count = 7;
// The number of root fields in the query
uint64 root_field_count = 8;
}

// Wallclock time when the trace began.
google.protobuf.Timestamp start_time = 4; // required
// Wallclock time when the trace ended.
Expand Down Expand Up @@ -285,6 +307,9 @@ message Trace {
// 0 is treated as 1 for backwards compatibility.
double field_execution_weight = 31;

// The limits information of the query.
Limits limits = 32;


// removed: Node parse = 12; Node validate = 13;
// Id128 server_id = 1; Id128 client_id = 2;
Expand Down Expand Up @@ -320,6 +345,9 @@ message ReportHeader {
// attached to a schema in the backend.
string executable_schema_id = 11;

// The unique reporting agent that generated this report.
string agent_id = 13;

reserved 3; // removed string service = 3;
}

Expand Down Expand Up @@ -371,6 +399,29 @@ message QueryLatencyStats {
reserved 1, 6, 9, 10;
}

// Stats on the query that can be populated by the gateway or router.
message LimitsStats {
// The strategy used in cost calculations.
string strategy = 1;
// The estimated cost as calculated via the strategy specified in stats context
// The reason that this is a histogram rather than fixed cost is that it can be affected by paging variables.
repeated sint64 cost_estimated = 2 ;
// The maximum estimated cost of the query
uint64 max_cost_estimated = 3;
// The actual cost using the strategy specified in stats context
repeated sint64 cost_actual = 4 ;
// The maximum estimated cost of the query
uint64 max_cost_actual = 5;
// The total depth of the query
uint64 depth = 6;
// The height of the query
uint64 height = 7;
// The number of aliases in the query
uint64 alias_count = 8;
// The number of root fields in the query
uint64 root_field_count = 9;
}

// The context around a block of stats and traces indicating from which client the operation was executed and its
// operation type. Operation type and subtype are only used by Apollo Router.
message StatsContext {
Expand All @@ -379,6 +430,12 @@ message StatsContext {
string client_version = 3;
string operation_type = 4;
string operation_subtype = 5;
// The result of the operation. Either OK or the error code that caused the operation to fail.
// This will not contain all errors from a query, only the primary reason the operation failed. e.g. a limits failure or an auth failure.
string result = 6;
// Client awareness contexts
string client_library_name = 7;
string client_library_version = 8;
}

message ContextualizedQueryLatencyStats {
Expand Down Expand Up @@ -426,12 +483,27 @@ message FieldStat {
reserved 1, 2, 7, 8;
}

// As FieldStat only gets returned for FTV1 payloads this is a separate message that can be used to collect stats in the router or gateway obtained directly from the request schema and response.
message LocalFieldStat {
string return_type = 1; // required; eg "String!" for User.email:String!
// Histogram of returned array sizes
repeated sint64 array_size = 2 ;
}

message TypeStat {
// Key is (eg) "email" for User.email:String!
map<string, FieldStat> per_field_stat = 3;

reserved 1, 2;
}

message LocalTypeStat {
// Key is (eg) "email" for User.email:String!
// Unlike FieldStat, this is populated outside of FTV1 requests.
map<string, LocalFieldStat> local_per_field_stat = 1;
}


message ReferencedFieldsForType {
// Contains (eg) "email" for User.email:String!
repeated string field_names = 1;
Expand Down Expand Up @@ -482,25 +554,77 @@ message Report {
// operations. If this is false, each operation is described in precisely
// one of those two fields.
bool traces_pre_aggregated = 7;

// This indicates whether or not extended references are enabled, which are within the stats with context and contain
// input type and enum value references. We need this flag so we can tell if the option is enabled even when there are
// no extended references to report.
bool extended_references_enabled = 9;

// A list of features enabled by router at the time this report was generated.
// It is expected to be included only by Apollo Router, not by any other reporting agent.
repeated string router_features_enabled = 10;
}


message ContextualizedStats {
StatsContext context = 1;
QueryLatencyStats query_latency_stats = 2;
// Key is type name. This structure provides data for the count and latency of individual
// field executions and thus only reflects operations for which field-level tracing occurred.
map<string, TypeStat> per_type_stat = 3;

// Extended references including input types and enum values.
ExtendedReferences extended_references = 6;

// Per type stats that are obtained directly by the router or gateway rather than FTV1.
map<string, LocalTypeStat> local_per_type_stat = 7;

// Stats that contain limits information for the query.
LimitsStats limits_stats = 8;

// Total number of operations processed during this period for this context. This includes all operations, even if they are sampled
// and not included in the query latency stats.
uint64 operation_count = 9;

reserved 4, 5;
}

message QueryMetadata {
// The operation name. For now this is a required field if QueryMetadata is present.
// The operation name. For operations with a PQ ID as the stats report key, either name or signature must be present in the metadata.
string name = 1;
// the operation signature. For now this is a required field if QueryMetadata is present.
// the operation signature. For operations with a PQ ID as the stats report key, either name or signature must be present in the metadata.
string signature = 2;
// (Optional) Persisted query ID that was used to request this operation.
string pq_id = 3;

}

message ExtendedReferences {
map<string, InputTypeStats> input_types = 1;

// Map of enum name to stats about that enum.
map<string, EnumStats> enum_values = 2;
}

message InputTypeStats {
// Map of input object type to the stats about the fields within that object.
map<string, InputFieldStats> field_names = 1;
}

message InputFieldStats {
// The total number of operations that reference the input object field.
uint64 refs = 1;

// The number of operations that reference the input object field as a null value.
uint64 null_refs = 2;

// The number of operations that don't reference this input object field (the field is missing or undefined).
uint64 missing = 3;
}

message EnumStats {
// Map of enum value name to the number of referencing operations.
map<string, uint64> enum_values = 1;
}

// A sequence of traces and stats. If Report.traces_pre_aggregated (at the top
Expand All @@ -518,12 +642,11 @@ message TracesAndStats {
// (as FieldStats will include the concrete object type for fields referenced
// via an interface type).
map<string, ReferencedFieldsForType> referenced_fields_by_type = 4;
// This field is used to validate that the algorithm used to construct `stats_with_context`
// matches similar algorithms in Apollo's servers. It is otherwise ignored and should not
// be included in reports.
repeated Trace internal_traces_contributing_to_stats = 3 ;

// This is an optional field that is used to provide more context to the key of this object within the
// traces_per_query map. If it's omitted, we assume the key is a standard operation name and signature key.
QueryMetadata query_metadata = 5;

reserved 3;
}

12 changes: 8 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ mod proto;
pub mod register;
mod report_aggregator;

mod runtime;
mod packages;
mod runtime;

use futures::SinkExt;
use packages::serde_json;
use protobuf::{well_known_types::timestamp::Timestamp, EnumOrUnknown, MessageField};
use report_aggregator::ReportAggregator;
use runtime::spawn;
use packages::serde_json;

#[macro_use]
extern crate tracing;
Expand Down Expand Up @@ -126,13 +126,15 @@ impl ApolloTracing {
graph_id: String,
variant: String,
service_version: String,
agent_id: String,
) -> ApolloTracing {
let report = ReportAggregator::initialize(
authorization_token,
hostname,
graph_id,
variant,
service_version,
agent_id,
);

ApolloTracing {
Expand Down Expand Up @@ -186,8 +188,10 @@ impl Extension for ApolloTracingExtension {
.filter(|(_, operation)| operation.node.ty == OperationType::Query)
.any(|(_, operation)| operation.node.selection_set.node.items.iter().any(|selection| matches!(&selection.node, Selection::Field(field) if field.node.name.node == "__schema")));
if !is_schema {
let result: String =
ctx.stringify_execute_doc(&document, &Variables::from_json(serde_json::from_str("{}").unwrap()));
let result: String = ctx.stringify_execute_doc(
&document,
&Variables::from_json(serde_json::from_str("{}").unwrap()),
);
let name = document
.operations
.iter()
Expand Down
1 change: 0 additions & 1 deletion src/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#[allow(unknown_lints)]
#[allow(unused_attributes)]
#[cfg_attr(rustfmt, rustfmt::skip)]
#[allow(box_pointers)]
#[allow(dead_code)]
#[allow(missing_docs)]
#[allow(non_camel_case_types)]
Expand Down
4 changes: 3 additions & 1 deletion src/report_aggregator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use futures::{
use protobuf::Message;

use crate::{
proto::reports::{Report, ReportHeader, Trace, TracesAndStats},
packages::uname,
proto::reports::{Report, ReportHeader, Trace, TracesAndStats},
runtime::{abort, spawn, Instant, JoinHandle},
};

Expand All @@ -33,10 +33,12 @@ impl ReportAggregator {
graph_id: String,
variant: String,
service_version: String,
agent_id: String,
) -> Self {
let (tx, mut rx) = mpsc::channel::<(String, Trace)>(BUFFER_SLOTS);

let reported_header = ReportHeader {
agent_id,
uname: uname::uname()
.ok()
.unwrap_or_else(|| "No uname provided".to_string()),
Expand Down