code: def before_request(request, tracer=None):
      
      if tracer is None:  # pragma: no cover
          tracer = opentracing.tracer
  
      # we need to prepare tags upfront, mainly because RPC_SERVER tag must be
      # set when starting the span, to support Zipkin's one-span-per-RPC model
      tags_dict = {
          tags.SPAN_KIND: tags.SPAN_KIND_RPC_SERVER,
          tags.HTTP_URL: request.full_url,
      }
  
      remote_ip = request.remote_ip
      if remote_ip:
          tags_dict[tags.PEER_HOST_IPV4] = remote_ip
  
      caller_name = request.caller_name
      if caller_name:
          tags_dict[tags.PEER_SERVICE] = caller_name
  
      remote_port = request.remote_port
      if remote_port:
          tags_dict[tags.PEER_PORT] = remote_port
  
      operation = request.operation
      try:
          carrier = {}
          for key, value in six.iteritems(request.headers):
              carrier[key] = value
          parent_ctx = tracer.extract(
              format=Format.HTTP_HEADERS, carrier=carrier
          )
      except Exception as e:
          logging.exception('trace extract failed: %s' % e)
          parent_ctx = None
  
      span = tracer.start_span(
          operation_name=operation,
          child_of=parent_ctx,
          tags=tags_dict)
  
      return span
docs: Attempts to extract a tracing span from incoming request.
      If no tracing context is passed in the headers, or the data
      cannot be parsed, a new root span is started.
  
      :param request: HTTP request with `.headers` property exposed
          that satisfies a regular dictionary interface
      :param tracer: optional tracer instance to use. If not specified
          the global opentracing.tracer will be used.
      :return: returns a new, already started span.