Improve opentracing for federation requests (#11870)
The idea here is to set the parent span for incoming federation requests to the *outgoing* span on the other end. That means that you can see (most of) the full end-to-end flow when you have a process that includes federation requests. However, in order not to lose information, we still want a link to the `incoming-federation-request` span from the servlet, so we have to create another span to do exactly that.
This commit is contained in:
parent
31b554c297
commit
964f5b9324
|
@ -0,0 +1 @@
|
||||||
|
Improve opentracing for incoming federation requests.
|
|
@ -15,6 +15,7 @@
|
||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
import time
|
||||||
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Optional, Tuple, cast
|
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Optional, Tuple, cast
|
||||||
|
|
||||||
from synapse.api.errors import Codes, FederationDeniedError, SynapseError
|
from synapse.api.errors import Codes, FederationDeniedError, SynapseError
|
||||||
|
@ -24,8 +25,10 @@ from synapse.http.servlet import parse_json_object_from_request
|
||||||
from synapse.http.site import SynapseRequest
|
from synapse.http.site import SynapseRequest
|
||||||
from synapse.logging.context import run_in_background
|
from synapse.logging.context import run_in_background
|
||||||
from synapse.logging.opentracing import (
|
from synapse.logging.opentracing import (
|
||||||
|
active_span,
|
||||||
set_tag,
|
set_tag,
|
||||||
span_context_from_request,
|
span_context_from_request,
|
||||||
|
start_active_span,
|
||||||
start_active_span_follows_from,
|
start_active_span_follows_from,
|
||||||
whitelisted_homeserver,
|
whitelisted_homeserver,
|
||||||
)
|
)
|
||||||
|
@ -265,6 +268,7 @@ class BaseFederationServlet:
|
||||||
content = parse_json_object_from_request(request)
|
content = parse_json_object_from_request(request)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
with start_active_span("authenticate_request"):
|
||||||
origin: Optional[str] = await authenticator.authenticate_request(
|
origin: Optional[str] = await authenticator.authenticate_request(
|
||||||
request, content
|
request, content
|
||||||
)
|
)
|
||||||
|
@ -282,15 +286,30 @@ class BaseFederationServlet:
|
||||||
# update the active opentracing span with the authenticated entity
|
# update the active opentracing span with the authenticated entity
|
||||||
set_tag("authenticated_entity", origin)
|
set_tag("authenticated_entity", origin)
|
||||||
|
|
||||||
# if the origin is authenticated and whitelisted, link to its span context
|
# if the origin is authenticated and whitelisted, use its span context
|
||||||
|
# as the parent.
|
||||||
context = None
|
context = None
|
||||||
if origin and whitelisted_homeserver(origin):
|
if origin and whitelisted_homeserver(origin):
|
||||||
context = span_context_from_request(request)
|
context = span_context_from_request(request)
|
||||||
|
|
||||||
|
if context:
|
||||||
|
servlet_span = active_span()
|
||||||
|
# a scope which uses the origin's context as a parent
|
||||||
|
processing_start_time = time.time()
|
||||||
scope = start_active_span_follows_from(
|
scope = start_active_span_follows_from(
|
||||||
"incoming-federation-request", contexts=(context,) if context else ()
|
"incoming-federation-request",
|
||||||
|
child_of=context,
|
||||||
|
contexts=(servlet_span,),
|
||||||
|
start_time=processing_start_time,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# just use our context as a parent
|
||||||
|
scope = start_active_span(
|
||||||
|
"incoming-federation-request",
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
with scope:
|
with scope:
|
||||||
if origin and self.RATELIMIT:
|
if origin and self.RATELIMIT:
|
||||||
with ratelimiter.ratelimit(origin) as d:
|
with ratelimiter.ratelimit(origin) as d:
|
||||||
|
@ -308,6 +327,16 @@ class BaseFederationServlet:
|
||||||
response = await func(
|
response = await func(
|
||||||
origin, content, request.args, *args, **kwargs
|
origin, content, request.args, *args, **kwargs
|
||||||
)
|
)
|
||||||
|
finally:
|
||||||
|
# if we used the origin's context as the parent, add a new span using
|
||||||
|
# the servlet span as a parent, so that we have a link
|
||||||
|
if context:
|
||||||
|
scope2 = start_active_span_follows_from(
|
||||||
|
"process-federation_request",
|
||||||
|
contexts=(scope.span,),
|
||||||
|
start_time=processing_start_time,
|
||||||
|
)
|
||||||
|
scope2.close()
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
|
@ -478,6 +478,8 @@ def start_active_span(
|
||||||
def start_active_span_follows_from(
|
def start_active_span_follows_from(
|
||||||
operation_name: str,
|
operation_name: str,
|
||||||
contexts: Collection,
|
contexts: Collection,
|
||||||
|
child_of=None,
|
||||||
|
start_time: Optional[float] = None,
|
||||||
*,
|
*,
|
||||||
inherit_force_tracing=False,
|
inherit_force_tracing=False,
|
||||||
tracer=None,
|
tracer=None,
|
||||||
|
@ -487,6 +489,14 @@ def start_active_span_follows_from(
|
||||||
Args:
|
Args:
|
||||||
operation_name: name of the operation represented by the new span
|
operation_name: name of the operation represented by the new span
|
||||||
contexts: the previous spans to inherit from
|
contexts: the previous spans to inherit from
|
||||||
|
|
||||||
|
child_of: optionally override the parent span. If unset, the currently active
|
||||||
|
span will be the parent. (If there is no currently active span, the first
|
||||||
|
span in `contexts` will be the parent.)
|
||||||
|
|
||||||
|
start_time: optional override for the start time of the created span. Seconds
|
||||||
|
since the epoch.
|
||||||
|
|
||||||
inherit_force_tracing: if set, and any of the previous contexts have had tracing
|
inherit_force_tracing: if set, and any of the previous contexts have had tracing
|
||||||
forced, the new span will also have tracing forced.
|
forced, the new span will also have tracing forced.
|
||||||
tracer: override the opentracing tracer. By default the global tracer is used.
|
tracer: override the opentracing tracer. By default the global tracer is used.
|
||||||
|
@ -497,7 +507,9 @@ def start_active_span_follows_from(
|
||||||
references = [opentracing.follows_from(context) for context in contexts]
|
references = [opentracing.follows_from(context) for context in contexts]
|
||||||
scope = start_active_span(
|
scope = start_active_span(
|
||||||
operation_name,
|
operation_name,
|
||||||
|
child_of=child_of,
|
||||||
references=references,
|
references=references,
|
||||||
|
start_time=start_time,
|
||||||
tracer=tracer,
|
tracer=tracer,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue