Skip to content

Commit 73b6eb8

Browse files
ckoehnbeniwohlibasepi
authored
[GRPC] Handle non-existent transaction in server interceptor (#1761)
* Handle non-existent transaction in gRPC server interceptor * add test for when transactions are not created in GRPC * CHANGELOG --------- Co-authored-by: Benjamin Wohlwend <[email protected]> Co-authored-by: Colton Myers <[email protected]>
1 parent ef9e5bb commit 73b6eb8

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

CHANGELOG.asciidoc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ endif::[]
2929
//===== Bug fixes
3030
//
3131
32+
=== Unreleased
33+
34+
// Unreleased changes go here
35+
// When the next release happens, nest these changes under the "Python Agent version 6.x" heading
36+
//[float]
37+
//===== Features
38+
39+
[float]
40+
===== Bug fixes
41+
42+
* Fix a bug in the GRPC instrumentation when the agent is disabled or not recording {pull}1761[#1761]
43+
44+
3245
[[release-notes-6.x]]
3346
=== Python Agent version 6.x
3447

elasticapm/contrib/grpc/server_interceptor.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,12 @@ def _interceptor(request_or_iterator, context):
101101
transaction = client.begin_transaction("request", trace_parent=tp)
102102
try:
103103
result = behavior(request_or_iterator, _ServicerContextWrapper(context, transaction))
104-
if not transaction.outcome:
104+
if transaction and not transaction.outcome:
105105
transaction.set_success()
106106
return result
107107
except Exception:
108-
transaction.set_failure()
108+
if transaction:
109+
transaction.set_failure()
109110
client.capture_exception(handled=False)
110111
raise
111112
finally:

tests/contrib/grpc/grpc_client_tests.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,16 @@
5050

5151

5252
@pytest.fixture()
53-
def grpc_server(validating_httpserver):
53+
def grpc_server(validating_httpserver, request):
54+
config = getattr(request, "param", {})
55+
env = {f"ELASTIC_APM_{k.upper()}": str(v) for k, v in config.items()}
56+
env.setdefault("ELASTIC_APM_SERVER_URL", validating_httpserver.url)
5457
free_port = get_free_port()
5558
server_proc = subprocess.Popen(
5659
[os.path.join(sys.prefix, "bin", "python"), "-m", "tests.contrib.grpc.grpc_app.server", str(free_port)],
5760
stdout=sys.stdout,
5861
stderr=sys.stdout,
59-
env={"ELASTIC_APM_SERVER_URL": validating_httpserver.url},
62+
env=env,
6063
)
6164
wait_for_open_port(free_port)
6265
yield f"localhost:{free_port}"
@@ -178,7 +181,7 @@ def test_grpc_client_server_exception(instrument, sending_elasticapm_client, grp
178181
assert error["transaction_id"] == server_transactions[0]["id"]
179182

180183

181-
def test_grpc_client_unsampled_transaction(instrument, sending_elasticapm_client, grpc_client_and_server_url):
184+
def test_grpc_client_unsampled_span(instrument, sending_elasticapm_client, grpc_client_and_server_url):
182185
grpc_client, grpc_server_url = grpc_client_and_server_url
183186
grpc_server_host, grpc_server_port = grpc_server_url.split(":")
184187
transaction = sending_elasticapm_client.begin_transaction("request")
@@ -196,6 +199,26 @@ def test_grpc_client_unsampled_transaction(instrument, sending_elasticapm_client
196199
assert transaction_data["span_count"]["started"] == 0
197200

198201

202+
@pytest.mark.parametrize(
203+
"grpc_server",
204+
[
205+
{
206+
"recording": "False",
207+
}
208+
],
209+
indirect=True,
210+
)
211+
def test_grpc_client_unsampled_transaction(instrument, sending_elasticapm_client, grpc_client_and_server_url):
212+
grpc_client, grpc_server_url = grpc_client_and_server_url
213+
grpc_client.GetServerResponse(Message(message="foo"))
214+
payloads = sending_elasticapm_client.httpserver.payloads
215+
for i in range(100):
216+
if len(sending_elasticapm_client.httpserver.payloads) > 1:
217+
break
218+
time.sleep(0.01)
219+
assert len(payloads) == 1 # only the server_version request
220+
221+
199222
def extract_events_from_payload(service_name, payloads):
200223
payloads = [
201224
payload for payload in payloads if payload and payload[0]["metadata"]["service"]["name"] == service_name

0 commit comments

Comments
 (0)