Skip to content

Commit 8287af1

Browse files
authored
fix: validate opentelemetry span job attributes have values (#1327)
fix: validate opentelemetry span job attributes have values There are several job properties that are optional. Existing opentelemetry instrumentation disallows span attribute keys without appropriate values, so this change validates field presence before propagating.
1 parent a3f4351 commit 8287af1

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

google/cloud/bigquery/opentelemetry_tracing.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,7 @@ def _set_client_attributes(client):
107107
def _set_job_attributes(job_ref):
108108
job_attributes = {
109109
"db.name": job_ref.project,
110-
"location": job_ref.location,
111-
"num_child_jobs": job_ref.num_child_jobs,
112110
"job_id": job_ref.job_id,
113-
"parent_job_id": job_ref.parent_job_id,
114111
"state": job_ref.state,
115112
}
116113

@@ -125,4 +122,13 @@ def _set_job_attributes(job_ref):
125122
if job_ref.ended is not None:
126123
job_attributes["timeEnded"] = job_ref.ended.isoformat()
127124

125+
if job_ref.location is not None:
126+
job_attributes["location"] = job_ref.location
127+
128+
if job_ref.parent_job_id is not None:
129+
job_attributes["parent_job_id"] = job_ref.parent_job_id
130+
131+
if job_ref.num_child_jobs is not None:
132+
job_attributes["num_child_jobs"] = job_ref.num_child_jobs
133+
128134
return job_attributes

tests/unit/test_opentelemetry_tracing.py

+26
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,32 @@ def test_default_job_attributes(setup):
164164
assert span.attributes == expected_attributes
165165

166166

167+
@pytest.mark.skipif(opentelemetry is None, reason="Require `opentelemetry`")
168+
def test_optional_job_attributes(setup):
169+
# This test ensures we don't propagate unset values into span attributes
170+
import google.cloud._helpers
171+
172+
time_created = datetime.datetime(
173+
2010, 5, 19, 16, 0, 0, tzinfo=google.cloud._helpers.UTC
174+
)
175+
176+
with mock.patch("google.cloud.bigquery.job._AsyncJob") as test_job_ref:
177+
test_job_ref.job_id = "test_job_id"
178+
test_job_ref.location = None
179+
test_job_ref.project = "test_project_id"
180+
test_job_ref.created = time_created
181+
test_job_ref.state = "some_job_state"
182+
test_job_ref.num_child_jobs = None
183+
test_job_ref.parent_job_id = None
184+
185+
with opentelemetry_tracing.create_span(
186+
TEST_SPAN_NAME, attributes=TEST_SPAN_ATTRIBUTES, job_ref=test_job_ref
187+
) as span:
188+
assert span is not None
189+
for val in span.attributes.values():
190+
assert val is not None
191+
192+
167193
@pytest.mark.skipif(opentelemetry is None, reason="Require `opentelemetry`")
168194
def test_default_no_data_leakage(setup):
169195
import google.auth.credentials

0 commit comments

Comments
 (0)