@@ -147,7 +147,7 @@ def _convert_any_value_to_string(value: Any) -> str:
147147
148148# Be careful not to mutate original body. Make copies of anything that needs to change.
149149def _sanitized_body (
150- body : Mapping [str , AnyValue ]
150+ body : Mapping [str , AnyValue ],
151151) -> MutableMapping [str , AnyValue ]:
152152 new_body : MutableMapping [str , AnyValue ] = {}
153153 for key , value in body .items ():
@@ -212,6 +212,45 @@ def is_log_id_valid(log_id: str) -> bool:
212212 )
213213
214214
215+ def _get_monitored_resource (
216+ resource : Optional [Resource ],
217+ ) -> MonitoredResource | None :
218+ if not resource :
219+ return None
220+
221+ # TODO: Remove temporary special case for Vertex Agent Engine
222+ # https://github.com/GoogleCloudPlatform/opentelemetry-operations-python/issues/444
223+ cloud_resource_id = resource .attributes .get ("cloud.resource_id" )
224+ if isinstance (cloud_resource_id , str ) and (
225+ match := re .match (
226+ r"//aiplatform\.googleapis\.com/projects/(?P<project_id>[^/]+)"
227+ r"/locations/(?P<location>[^/]+)"
228+ r"/reasoningEngines/(?P<agent_engine_id>[^/]+)" ,
229+ cloud_resource_id ,
230+ )
231+ ):
232+ project_id = match .group ("project_id" )
233+ location = match .group ("location" )
234+ agent_engine_id = match .group ("agent_engine_id" )
235+ return MonitoredResource (
236+ type = "aiplatform.googleapis.com/ReasoningEngine" ,
237+ labels = {
238+ "resource_container" : project_id ,
239+ "location" : location ,
240+ "reasoning_engine_id" : agent_engine_id ,
241+ },
242+ )
243+
244+ monitored_resource_data = get_monitored_resource (resource )
245+ if not monitored_resource_data :
246+ return None
247+
248+ return MonitoredResource (
249+ type = monitored_resource_data .type ,
250+ labels = monitored_resource_data .labels ,
251+ )
252+
253+
215254class CloudLoggingExporter (LogExporter ):
216255 def __init__ (
217256 self ,
@@ -302,14 +341,10 @@ def export(self, batch: Sequence[LogData]):
302341 else :
303342 ts .FromDatetime (now )
304343 log_entry .timestamp = ts
305- monitored_resource_data = get_monitored_resource (
306- log_record .resource or Resource ({})
307- )
308- if monitored_resource_data :
309- log_entry .resource = MonitoredResource (
310- type = monitored_resource_data .type ,
311- labels = monitored_resource_data .labels ,
312- )
344+ if monitored_resource := _get_monitored_resource (
345+ log_record .resource
346+ ):
347+ log_entry .resource = monitored_resource
313348 log_entry .trace_sampled = (
314349 log_record .trace_flags is not None
315350 and log_record .trace_flags .sampled
@@ -366,9 +401,9 @@ def _write_log_entries_to_file(file: TextIO, log_entries: list[LogEntry]):
366401 )
367402 json_dict ["logging.googleapis.com/labels" ] = dict (entry .labels )
368403 json_dict ["logging.googleapis.com/spanId" ] = entry .span_id
369- json_dict [
370- "logging.googleapis.com/ trace_sampled"
371- ] = entry . trace_sampled
404+ json_dict ["logging.googleapis.com/trace_sampled" ] = (
405+ entry . trace_sampled
406+ )
372407 json_dict ["logging.googleapis.com/trace" ] = entry .trace
373408
374409 if entry .text_payload :
0 commit comments