Skip to content

Commit 1e50252

Browse files
committed
Add temporary support for aiplatform.googleapis.com/ReasoningEngine monitored resource in logging exporter
1 parent c9ae87a commit 1e50252

File tree

4 files changed

+92
-9
lines changed

4 files changed

+92
-9
lines changed

opentelemetry-exporter-gcp-logging/src/opentelemetry/exporter/cloud_logging/__init__.py

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
149149
def _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+
215254
class 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
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[
2+
{
3+
"entries": [
4+
{
5+
"logName": "projects/fakeproject/logs/test",
6+
"resource": {
7+
"labels": {
8+
"location": "europe-west3",
9+
"reasoning_engine_id": "8477639270431981568",
10+
"resource_container": "some-project123-321"
11+
},
12+
"type": "aiplatform.googleapis.com/ReasoningEngine"
13+
},
14+
"timestamp": "2025-01-15T21:25:10.997977393Z"
15+
}
16+
],
17+
"partialSuccess": true
18+
}
19+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
{
3+
"logging.googleapis.com/labels": {},
4+
"logging.googleapis.com/spanId": "",
5+
"logging.googleapis.com/trace": "",
6+
"logging.googleapis.com/trace_sampled": false,
7+
"severity": "DEFAULT",
8+
"time": "2025-01-15T21:25:10.997977393Z"
9+
}
10+
]

opentelemetry-exporter-gcp-logging/tests/test_cloud_logging.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,25 @@ def test_user_agent(cloudloggingfake: CloudLoggingFake) -> None:
165165
)
166166

167167

168+
def test_agent_engine_monitored_resources(
169+
export_and_assert_snapshot: ExportAndAssertSnapshot,
170+
) -> None:
171+
log_data = [
172+
LogData(
173+
log_record=LogRecord(
174+
timestamp=1736976310997977393,
175+
resource=Resource(
176+
{
177+
"cloud.resource_id": "//aiplatform.googleapis.com/projects/some-project123-321/locations/europe-west3/reasoningEngines/8477639270431981568"
178+
}
179+
),
180+
),
181+
instrumentation_scope=InstrumentationScope("test"),
182+
),
183+
]
184+
export_and_assert_snapshot(log_data)
185+
186+
168187
def test_convert_otlp_dict_body(
169188
export_and_assert_snapshot: ExportAndAssertSnapshot,
170189
) -> None:

0 commit comments

Comments
 (0)