code: func StartSpanFromContext(ctx context.Context, tracer opentracing.Tracer, name string, opts ...opentracing.StartSpanOption) (context.Context, opentracing.Span, error) {
  	md, ok := metadata.FromContext(ctx)
  	if !ok {
  		md = make(map[string]string)
  	}
  
  	// copy the metadata to prevent race
  	md = metadata.Copy(md)
  
  	// find trace in go-micro metadata
  	if spanCtx, err := tracer.Extract(opentracing.TextMap, opentracing.TextMapCarrier(md)); err == nil {
  		opts = append(opts, opentracing.ChildOf(spanCtx))
  	}
  
  	// find span context in opentracing library
  	if parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil {
  		opts = append(opts, opentracing.ChildOf(parentSpan.Context()))
  	}
  
  	sp := tracer.StartSpan(name, opts...)
  
  	if err := sp.Tracer().Inject(sp.Context(), opentracing.TextMap, opentracing.TextMapCarrier(md)); err != nil {
  		return nil, nil, err
  	}
  
  	ctx = opentracing.ContextWithSpan(ctx, sp)
  	ctx = metadata.NewContext(ctx, md)
  	return ctx, sp, nil
  }
docs: // StartSpanFromContext returns a new span with the given operation name and options. If a span
  // is found in the context, it will be used as the parent of the resulting span.