1414
1515from collections import namedtuple
1616
17- import newrelic .core .attribute as attribute
1817import newrelic .core .trace_node
1918
20- from newrelic .common import system_info
2119from newrelic .core .metric import TimeMetric
2220
2321from newrelic .core .node_mixin import GenericNodeMixin
2422
2523
26- _GraphQLNode = namedtuple ('_GraphQLNode' ,
27- [ 'field_name ' , 'children ' , 'start_time ' , 'end_time' ,
28- 'duration ' , 'exclusive ' , 'guid ' , 'agent_attributes' ,
29- 'user_attributes' ])
24+ _GraphQLOperationNode = namedtuple ('_GraphQLNode' ,
25+ [ 'operation_type ' , 'operation_name ' , 'deepest_path ' ,
26+ 'children' , 'start_time ' , 'end_time ' , 'duration ' , 'exclusive' ,
27+ 'guid' , 'agent_attributes' , 'user_attributes' ])
3028
29+ _GraphQLResolverNode = namedtuple ('_GraphQLNode' ,
30+ ['field_name' , 'children' , 'start_time' , 'end_time' , 'duration' ,
31+ 'exclusive' , 'guid' , 'agent_attributes' , 'user_attributes' ])
3132
32- class GraphQLNode (_GraphQLNode , GenericNodeMixin ):
33-
33+ class GraphQLNodeMixin (GenericNodeMixin ):
3434 @property
3535 def product (self ):
3636 return "GraphQL"
3737
38+ def trace_node (self , stats , root , connections ):
39+ name = root .string_table .cache (self .name )
40+
41+ start_time = newrelic .core .trace_node .node_start_time (root , self )
42+ end_time = newrelic .core .trace_node .node_end_time (root , self )
43+
44+ root .trace_node_count += 1
45+
46+ children = []
47+
48+ # Now for the children
49+
50+ for child in self .children :
51+ if root .trace_node_count > root .trace_node_limit :
52+ break
53+ children .append (child .trace_node (stats , root , connections ))
54+
55+ # Agent attributes
56+ params = self .get_trace_segment_params (root .settings )
57+
58+ return newrelic .core .trace_node .TraceNode (start_time = start_time ,
59+ end_time = end_time , name = name , params = params , children = children ,
60+ label = None )
61+
62+ class GraphQLResolverNode (_GraphQLResolverNode , GraphQLNodeMixin ):
3863 @property
39- def operation (self ):
40- return "select"
64+ def name (self ):
65+ field_name = self .field_name or "<unknown>"
66+ product = self .product
4167
68+ name = 'GraphQL/resolve/%s/%s' % (product , field_name )
69+
70+ return name
4271
4372 def time_metrics (self , stats , root , parent ):
4473 """Return a generator yielding the timed metrics for this
4574 database node as well as all the child nodes.
4675 """
4776
48- field_name = self .field_name
77+ field_name = self .field_name or "<unknown>"
4978 product = self .product
50- operation = self .operation or 'other'
5179
5280 # Determine the scoped metric
53- operation_metric_name = 'GraphQL/operation/%s/%s' % (product ,
54- operation )
5581
5682 field_resolver_metric_name = 'GraphQL/resolve/%s/%s' % (product , field_name )
5783
58- scoped_metric_name = operation_metric_name
59-
6084 yield TimeMetric (name = field_resolver_metric_name , scope = root .path , duration = self .duration ,
6185 exclusive = self .exclusive )
6286
87+ yield TimeMetric (name = field_resolver_metric_name , scope = '' , duration = self .duration ,
88+ exclusive = self .exclusive )
89+
90+ # Now for the children
91+
92+ for child in self .children :
93+ for metric in child .time_metrics (stats , root , self ):
94+ yield metric
95+
96+
97+ class GraphQLOperationNode (_GraphQLOperationNode , GraphQLNodeMixin ):
98+ @property
99+ def name (self ):
100+ operation_type = self .operation_type or "<unknown>"
101+ operation_name = self .operation_name or "<anonymous>"
102+ deepest_path = self .deepest_path or "<unknown>"
103+ product = self .product
104+
105+ name = 'GraphQL/operation/%s/%s/%s/%s' % (product , operation_type ,
106+ operation_name , deepest_path )
107+
108+ return name
109+
110+ def time_metrics (self , stats , root , parent ):
111+ """Return a generator yielding the timed metrics for this
112+ database node as well as all the child nodes.
113+
114+ """
115+
116+ operation_type = self .operation_type or "<unknown>"
117+ operation_name = self .operation_name or "<anonymous>"
118+ deepest_path = self .deepest_path or "<unknown>"
119+ product = self .product
120+
121+ # Determine the scoped metric
122+
123+ operation_metric_name = 'GraphQL/operation/%s/%s/%s/%s' % (product ,
124+ operation_type , operation_name , deepest_path )
125+
126+ scoped_metric_name = operation_metric_name
127+
63128 yield TimeMetric (name = scoped_metric_name , scope = root .path ,
64129 duration = self .duration , exclusive = self .exclusive )
65130
@@ -89,37 +154,8 @@ def time_metrics(self, stats, root, parent):
89154 yield TimeMetric (name = operation_metric_name , scope = '' ,
90155 duration = self .duration , exclusive = self .exclusive )
91156
92- yield TimeMetric (name = field_resolver_metric_name , scope = '' , duration = self .duration ,
93- exclusive = self .exclusive )
94-
95-
96- def trace_node (self , stats , root , connections ):
97- name = root .string_table .cache (self .name )
98-
99- start_time = newrelic .core .trace_node .node_start_time (root , self )
100- end_time = newrelic .core .trace_node .node_end_time (root , self )
101-
102- root .trace_node_count += 1
103-
104- children = []
105-
106- # Agent attributes
107- params = self .get_trace_segment_params (root .settings )
108-
109- return newrelic .core .trace_node .TraceNode (start_time = start_time ,
110- end_time = end_time , name = name , params = params , children = children ,
111- label = None )
112-
113- @property
114- def name (self ):
115- product = self .product
116- target = "test"
117- operation = self .operation or 'other'
118-
119- if target :
120- name = 'GraphQL/statement/%s/%s/%s' % (product , target ,
121- operation )
122- else :
123- name = 'GraphQL/operation/%s/%s' % (product , operation )
157+ # Now for the children
124158
125- return name
159+ for child in self .children :
160+ for metric in child .time_metrics (stats , root , self ):
161+ yield metric
0 commit comments