Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 9a6f2be

Browse files
Opentrace e2e keys (#5855)
Add opentracing tags and logs for e2e keys
1 parent c9f11d0 commit 9a6f2be

File tree

7 files changed

+142
-7
lines changed

7 files changed

+142
-7
lines changed

changelog.d/5855.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Opentracing for room and e2e keys.

synapse/federation/federation_server.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
from synapse.federation.units import Edu, Transaction
4444
from synapse.http.endpoint import parse_server_name
4545
from synapse.logging.context import nested_logging_context
46+
from synapse.logging.opentracing import log_kv, trace
4647
from synapse.logging.utils import log_function
4748
from synapse.replication.http.federation import (
4849
ReplicationFederationSendEduRestServlet,
@@ -507,6 +508,7 @@ def on_query_client_keys(self, origin, content):
507508
def on_query_user_devices(self, origin, user_id):
508509
return self.on_query_request("user_devices", user_id)
509510

511+
@trace
510512
@defer.inlineCallbacks
511513
@log_function
512514
def on_claim_client_keys(self, origin, content):
@@ -515,6 +517,7 @@ def on_claim_client_keys(self, origin, content):
515517
for device_id, algorithm in device_keys.items():
516518
query.append((user_id, device_id, algorithm))
517519

520+
log_kv({"message": "Claiming one time keys.", "user, device pairs": query})
518521
results = yield self.store.claim_e2e_one_time_keys(query)
519522

520523
json_result = {}

synapse/handlers/e2e_keys.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
from synapse.api.errors import CodeMessageException, SynapseError
2626
from synapse.logging.context import make_deferred_yieldable, run_in_background
27+
from synapse.logging.opentracing import log_kv, set_tag, tag_args, trace
2728
from synapse.types import UserID, get_domain_from_id
2829
from synapse.util import unwrapFirstError
2930
from synapse.util.retryutils import NotRetryingDestination
@@ -46,6 +47,7 @@ def __init__(self, hs):
4647
"client_keys", self.on_federation_query_client_keys
4748
)
4849

50+
@trace
4951
@defer.inlineCallbacks
5052
def query_devices(self, query_body, timeout):
5153
""" Handle a device key query from a client
@@ -81,6 +83,9 @@ def query_devices(self, query_body, timeout):
8183
else:
8284
remote_queries[user_id] = device_ids
8385

86+
set_tag("local_key_query", local_query)
87+
set_tag("remote_key_query", remote_queries)
88+
8489
# First get local devices.
8590
failures = {}
8691
results = {}
@@ -121,6 +126,7 @@ def query_devices(self, query_body, timeout):
121126
r[user_id] = remote_queries[user_id]
122127

123128
# Now fetch any devices that we don't have in our cache
129+
@trace
124130
@defer.inlineCallbacks
125131
def do_remote_query(destination):
126132
"""This is called when we are querying the device list of a user on
@@ -185,6 +191,8 @@ def do_remote_query(destination):
185191
except Exception as e:
186192
failure = _exception_to_failure(e)
187193
failures[destination] = failure
194+
set_tag("error", True)
195+
set_tag("reason", failure)
188196

189197
yield make_deferred_yieldable(
190198
defer.gatherResults(
@@ -198,6 +206,7 @@ def do_remote_query(destination):
198206

199207
return {"device_keys": results, "failures": failures}
200208

209+
@trace
201210
@defer.inlineCallbacks
202211
def query_local_devices(self, query):
203212
"""Get E2E device keys for local users
@@ -210,13 +219,22 @@ def query_local_devices(self, query):
210219
defer.Deferred: (resolves to dict[string, dict[string, dict]]):
211220
map from user_id -> device_id -> device details
212221
"""
222+
set_tag("local_query", query)
213223
local_query = []
214224

215225
result_dict = {}
216226
for user_id, device_ids in query.items():
217227
# we use UserID.from_string to catch invalid user ids
218228
if not self.is_mine(UserID.from_string(user_id)):
219229
logger.warning("Request for keys for non-local user %s", user_id)
230+
log_kv(
231+
{
232+
"message": "Requested a local key for a user which"
233+
" was not local to the homeserver",
234+
"user_id": user_id,
235+
}
236+
)
237+
set_tag("error", True)
220238
raise SynapseError(400, "Not a user here")
221239

222240
if not device_ids:
@@ -241,6 +259,7 @@ def query_local_devices(self, query):
241259
r["unsigned"]["device_display_name"] = display_name
242260
result_dict[user_id][device_id] = r
243261

262+
log_kv(results)
244263
return result_dict
245264

246265
@defer.inlineCallbacks
@@ -251,6 +270,7 @@ def on_federation_query_client_keys(self, query_body):
251270
res = yield self.query_local_devices(device_keys_query)
252271
return {"device_keys": res}
253272

273+
@trace
254274
@defer.inlineCallbacks
255275
def claim_one_time_keys(self, query, timeout):
256276
local_query = []
@@ -265,6 +285,9 @@ def claim_one_time_keys(self, query, timeout):
265285
domain = get_domain_from_id(user_id)
266286
remote_queries.setdefault(domain, {})[user_id] = device_keys
267287

288+
set_tag("local_key_query", local_query)
289+
set_tag("remote_key_query", remote_queries)
290+
268291
results = yield self.store.claim_e2e_one_time_keys(local_query)
269292

270293
json_result = {}
@@ -276,8 +299,10 @@ def claim_one_time_keys(self, query, timeout):
276299
key_id: json.loads(json_bytes)
277300
}
278301

302+
@trace
279303
@defer.inlineCallbacks
280304
def claim_client_keys(destination):
305+
set_tag("destination", destination)
281306
device_keys = remote_queries[destination]
282307
try:
283308
remote_result = yield self.federation.claim_client_keys(
@@ -290,6 +315,8 @@ def claim_client_keys(destination):
290315
except Exception as e:
291316
failure = _exception_to_failure(e)
292317
failures[destination] = failure
318+
set_tag("error", True)
319+
set_tag("reason", failure)
293320

294321
yield make_deferred_yieldable(
295322
defer.gatherResults(
@@ -313,9 +340,11 @@ def claim_client_keys(destination):
313340
),
314341
)
315342

343+
log_kv({"one_time_keys": json_result, "failures": failures})
316344
return {"one_time_keys": json_result, "failures": failures}
317345

318346
@defer.inlineCallbacks
347+
@tag_args
319348
def upload_keys_for_user(self, user_id, device_id, keys):
320349

321350
time_now = self.clock.time_msec()
@@ -329,19 +358,38 @@ def upload_keys_for_user(self, user_id, device_id, keys):
329358
user_id,
330359
time_now,
331360
)
361+
log_kv(
362+
{
363+
"message": "Updating device_keys for user.",
364+
"user_id": user_id,
365+
"device_id": device_id,
366+
}
367+
)
332368
# TODO: Sign the JSON with the server key
333369
changed = yield self.store.set_e2e_device_keys(
334370
user_id, device_id, time_now, device_keys
335371
)
336372
if changed:
337373
# Only notify about device updates *if* the keys actually changed
338374
yield self.device_handler.notify_device_update(user_id, [device_id])
339-
375+
else:
376+
log_kv({"message": "Not updating device_keys for user", "user_id": user_id})
340377
one_time_keys = keys.get("one_time_keys", None)
341378
if one_time_keys:
379+
log_kv(
380+
{
381+
"message": "Updating one_time_keys for device.",
382+
"user_id": user_id,
383+
"device_id": device_id,
384+
}
385+
)
342386
yield self._upload_one_time_keys_for_user(
343387
user_id, device_id, time_now, one_time_keys
344388
)
389+
else:
390+
log_kv(
391+
{"message": "Did not update one_time_keys", "reason": "no keys given"}
392+
)
345393

346394
# the device should have been registered already, but it may have been
347395
# deleted due to a race with a DELETE request. Or we may be using an
@@ -352,6 +400,7 @@ def upload_keys_for_user(self, user_id, device_id, keys):
352400

353401
result = yield self.store.count_e2e_one_time_keys(user_id, device_id)
354402

403+
set_tag("one_time_key_counts", result)
355404
return {"one_time_key_counts": result}
356405

357406
@defer.inlineCallbacks
@@ -395,6 +444,7 @@ def _upload_one_time_keys_for_user(
395444
(algorithm, key_id, encode_canonical_json(key).decode("ascii"))
396445
)
397446

447+
log_kv({"message": "Inserting new one_time_keys.", "keys": new_keys})
398448
yield self.store.add_e2e_one_time_keys(user_id, device_id, time_now, new_keys)
399449

400450

synapse/handlers/e2e_room_keys.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
StoreError,
2727
SynapseError,
2828
)
29+
from synapse.logging.opentracing import log_kv, trace
2930
from synapse.util.async_helpers import Linearizer
3031

3132
logger = logging.getLogger(__name__)
@@ -49,6 +50,7 @@ def __init__(self, hs):
4950
# changed.
5051
self._upload_linearizer = Linearizer("upload_room_keys_lock")
5152

53+
@trace
5254
@defer.inlineCallbacks
5355
def get_room_keys(self, user_id, version, room_id=None, session_id=None):
5456
"""Bulk get the E2E room keys for a given backup, optionally filtered to a given
@@ -84,8 +86,10 @@ def get_room_keys(self, user_id, version, room_id=None, session_id=None):
8486
user_id, version, room_id, session_id
8587
)
8688

89+
log_kv(results)
8790
return results
8891

92+
@trace
8993
@defer.inlineCallbacks
9094
def delete_room_keys(self, user_id, version, room_id=None, session_id=None):
9195
"""Bulk delete the E2E room keys for a given backup, optionally filtered to a given
@@ -107,6 +111,7 @@ def delete_room_keys(self, user_id, version, room_id=None, session_id=None):
107111
with (yield self._upload_linearizer.queue(user_id)):
108112
yield self.store.delete_e2e_room_keys(user_id, version, room_id, session_id)
109113

114+
@trace
110115
@defer.inlineCallbacks
111116
def upload_room_keys(self, user_id, version, room_keys):
112117
"""Bulk upload a list of room keys into a given backup version, asserting
@@ -186,7 +191,14 @@ def _upload_room_key(self, user_id, version, room_id, session_id, room_key):
186191
session_id(str): the session whose room_key we're setting
187192
room_key(dict): the room_key being set
188193
"""
189-
194+
log_kv(
195+
{
196+
"message": "Trying to upload room key",
197+
"room_id": room_id,
198+
"session_id": session_id,
199+
"user_id": user_id,
200+
}
201+
)
190202
# get the room_key for this particular row
191203
current_room_key = None
192204
try:
@@ -195,14 +207,23 @@ def _upload_room_key(self, user_id, version, room_id, session_id, room_key):
195207
)
196208
except StoreError as e:
197209
if e.code == 404:
198-
pass
210+
log_kv(
211+
{
212+
"message": "Room key not found.",
213+
"room_id": room_id,
214+
"user_id": user_id,
215+
}
216+
)
199217
else:
200218
raise
201219

202220
if self._should_replace_room_key(current_room_key, room_key):
221+
log_kv({"message": "Replacing room key."})
203222
yield self.store.set_e2e_room_key(
204223
user_id, version, room_id, session_id, room_key
205224
)
225+
else:
226+
log_kv({"message": "Not replacing room_key."})
206227

207228
@staticmethod
208229
def _should_replace_room_key(current_room_key, room_key):
@@ -236,6 +257,7 @@ def _should_replace_room_key(current_room_key, room_key):
236257
return False
237258
return True
238259

260+
@trace
239261
@defer.inlineCallbacks
240262
def create_version(self, user_id, version_info):
241263
"""Create a new backup version. This automatically becomes the new
@@ -294,6 +316,7 @@ def get_version_info(self, user_id, version=None):
294316
raise
295317
return res
296318

319+
@trace
297320
@defer.inlineCallbacks
298321
def delete_version(self, user_id, version=None):
299322
"""Deletes a given version of the user's e2e_room_keys backup
@@ -314,6 +337,7 @@ def delete_version(self, user_id, version=None):
314337
else:
315338
raise
316339

340+
@trace
317341
@defer.inlineCallbacks
318342
def update_version(self, user_id, version, version_info):
319343
"""Update the info about a given version of the user's backup

synapse/rest/client/v2_alpha/keys.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
parse_json_object_from_request,
2525
parse_string,
2626
)
27+
from synapse.logging.opentracing import log_kv, set_tag, trace_using_operation_name
2728
from synapse.types import StreamToken
2829

2930
from ._base import client_patterns
@@ -68,6 +69,7 @@ def __init__(self, hs):
6869
self.auth = hs.get_auth()
6970
self.e2e_keys_handler = hs.get_e2e_keys_handler()
7071

72+
@trace_using_operation_name("upload_keys")
7173
@defer.inlineCallbacks
7274
def on_POST(self, request, device_id):
7375
requester = yield self.auth.get_user_by_req(request, allow_guest=True)
@@ -78,6 +80,14 @@ def on_POST(self, request, device_id):
7880
# passing the device_id here is deprecated; however, we allow it
7981
# for now for compatibility with older clients.
8082
if requester.device_id is not None and device_id != requester.device_id:
83+
set_tag("error", True)
84+
log_kv(
85+
{
86+
"message": "Client uploading keys for a different device",
87+
"logged_in_id": requester.device_id,
88+
"key_being_uploaded": device_id,
89+
}
90+
)
8191
logger.warning(
8292
"Client uploading keys for a different device "
8393
"(logged in as %s, uploading for %s)",
@@ -178,10 +188,11 @@ def on_GET(self, request):
178188
requester = yield self.auth.get_user_by_req(request, allow_guest=True)
179189

180190
from_token_string = parse_string(request, "from")
191+
set_tag("from", from_token_string)
181192

182193
# We want to enforce they do pass us one, but we ignore it and return
183194
# changes after the "to" as well as before.
184-
parse_string(request, "to")
195+
set_tag("to", parse_string(request, "to"))
185196

186197
from_token = StreamToken.from_string(from_token_string)
187198

0 commit comments

Comments
 (0)