@@ -41,7 +41,6 @@ def traced_method(wrapped, instance, args, kwargs):
4141 api = APIS [operation_name ]
4242 service_provider = SERVICE_PROVIDERS .get ("NEO4J" , "neo4j" )
4343 extra_attributes = baggage .get_baggage (LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY )
44-
4544 span_attributes = {
4645 "langtrace.sdk.name" : "langtrace-python-sdk" ,
4746 "langtrace.service.name" : service_provider ,
@@ -50,7 +49,7 @@ def traced_method(wrapped, instance, args, kwargs):
5049 "langtrace.version" : v (LANGTRACE_SDK_NAME ),
5150 "db.system" : "neo4j" ,
5251 "db.operation" : api ["OPERATION" ],
53- "db.query" : json .dumps (kwargs ) ,
52+ "db.query" : json .dumps (args [ 0 ]) if args and len ( args ) > 0 else "" ,
5453 ** (extra_attributes if extra_attributes is not None else {}),
5554 }
5655
@@ -70,6 +69,14 @@ def traced_method(wrapped, instance, args, kwargs):
7069
7170 try :
7271 result = wrapped (* args , ** kwargs )
72+
73+ if isinstance (result , tuple ) and len (result ) == 3 :
74+ records , result_summary , keys = result
75+ _set_result_attributes (span , records , result_summary , keys )
76+ else :
77+ res = json .dumps (result )
78+ set_span_attribute (span , "neo4j.result.query_response" , res )
79+
7380 span .set_status (StatusCode .OK )
7481 return result
7582 except Exception as err :
@@ -85,14 +92,12 @@ def _set_execute_query_attributes(span, args, kwargs):
8592 query = args [0 ] if args else kwargs .get ("query_" , None )
8693 if query :
8794 if hasattr (query , "text" ):
88- set_span_attribute (span , "db.statement" , query .text )
8995 set_span_attribute (span , "db.query" , query .text )
9096 if hasattr (query , "metadata" ) and query .metadata :
9197 set_span_attribute (span , "db.query.metadata" , json .dumps (query .metadata ))
9298 if hasattr (query , "timeout" ) and query .timeout :
9399 set_span_attribute (span , "db.query.timeout" , query .timeout )
94100 else :
95- set_span_attribute (span , "db.statement" , query )
96101 set_span_attribute (span , "db.query" , query )
97102
98103 parameters = kwargs .get ("parameters_" , None )
@@ -104,8 +109,72 @@ def _set_execute_query_attributes(span, args, kwargs):
104109
105110 database = kwargs .get ("database_" , None )
106111 if database :
107- set_span_attribute (span , "db.name" , database )
112+ set_span_attribute (span , "neo4j. db.name" , database )
108113
109114 routing = kwargs .get ("routing_" , None )
110115 if routing :
111- set_span_attribute (span , "db.routing" , str (routing ))
116+ set_span_attribute (span , "neo4j.db.routing" , str (routing ))
117+
118+
119+ @silently_fail
120+ def _set_result_attributes (span , records , result_summary , keys ):
121+ """
122+ Set attributes related to the query result and summary
123+ """
124+ if records is not None :
125+ record_count = len (records )
126+ set_span_attribute (span , "neo4j.result.record_count" , record_count )
127+ if record_count > 0 :
128+ set_span_attribute (span , "neo4j.result.records" , json .dumps (records ))
129+
130+ if keys is not None :
131+ set_span_attribute (span , "neo4j.result.keys" , json .dumps (keys ))
132+
133+ if result_summary :
134+ if hasattr (result_summary , "database" ) and result_summary .database :
135+ set_span_attribute (span , "neo4j.db.name" , result_summary .database )
136+
137+ if hasattr (result_summary , "query_type" ) and result_summary .query_type :
138+ set_span_attribute (span , "neo4j.result.query_type" , result_summary .query_type )
139+
140+ if hasattr (result_summary , "parameters" ) and result_summary .parameters :
141+ try :
142+ set_span_attribute (span , "neo4j.result.parameters" , json .dumps (result_summary .parameters ))
143+ except (TypeError , ValueError ):
144+ pass
145+
146+ if hasattr (result_summary , "result_available_after" ) and result_summary .result_available_after is not None :
147+ set_span_attribute (span , "neo4j.result.available_after_ms" , result_summary .result_available_after )
148+
149+ if hasattr (result_summary , "result_consumed_after" ) and result_summary .result_consumed_after is not None :
150+ set_span_attribute (span , "neo4j.result.consumed_after_ms" , result_summary .result_consumed_after )
151+
152+ if hasattr (result_summary , "counters" ) and result_summary .counters :
153+ counters = result_summary .counters
154+ if hasattr (counters , "nodes_created" ) and counters .nodes_created :
155+ set_span_attribute (span , "neo4j.result.nodes_created" , counters .nodes_created )
156+
157+ if hasattr (counters , "nodes_deleted" ) and counters .nodes_deleted :
158+ set_span_attribute (span , "neo4j.result.nodes_deleted" , counters .nodes_deleted )
159+
160+ if hasattr (counters , "relationships_created" ) and counters .relationships_created :
161+ set_span_attribute (span , "neo4j.result.relationships_created" , counters .relationships_created )
162+
163+ if hasattr (counters , "relationships_deleted" ) and counters .relationships_deleted :
164+ set_span_attribute (span , "neo4j.result.relationships_deleted" , counters .relationships_deleted )
165+
166+ if hasattr (counters , "properties_set" ) and counters .properties_set :
167+ set_span_attribute (span , "neo4j.result.properties_set" , counters .properties_set )
168+
169+ if hasattr (result_summary , "plan" ) and result_summary .plan :
170+ try :
171+ set_span_attribute (span , "neo4j.result.plan" , json .dumps (result_summary .plan ))
172+ except (TypeError , ValueError ):
173+ pass
174+
175+ if hasattr (result_summary , "notifications" ) and result_summary .notifications :
176+ try :
177+ set_span_attribute (span , "neo4j.result.notification_count" , len (result_summary .notifications ))
178+ set_span_attribute (span , "neo4j.result.notifications" , json .dumps (result_summary .notifications ))
179+ except (AttributeError , TypeError ):
180+ pass
0 commit comments