You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: tracer_jaeger.go
    path of file: ./repos/benthos/internal/impl/jaeger
    
    the code of the file until where you have to start completion: package jaeger

import (
	"fmt"
	"net"
	"strings"
	"time"

	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/exporters/jaeger" // nolint:staticcheck
	"go.opentelemetry.io/otel/sdk/resource"
	tracesdk "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
	"go.opentelemetry.io/otel/trace"

	"github.com/benthosdev/benthos/v4/internal/cli"
	"github.com/benthosdev/benthos/v4/public/service"
)

const (
	jtFieldAgentAddress  = "agent_address"
	jtFieldCollectorURL  = "collector_url"
	jtFieldSamplerType   = "sampler_type"
	jtFieldSamplerParam  = "sampler_param"
	jtFieldTags          = "tags"
	jtFieldFlushInterval = "flush_interval"
)

type jaegerConfig struct {
	AgentAddress  string
	CollectorURL  string
	SamplerType   string
	SamplerParam  float64
	Tags          map[string]string
	FlushInterval string
}

func jaegerConfigSpec() *service.ConfigSpec {
	return service.NewConfigSpec().
		Stable().
		Summary("Send tracing events to a [Jaeger](https://www.jaegertracing.io/) agent or collector.").
		Fields(
			service.NewStringField(jtFieldAg
    
func NewJaeger(config jaegerConfig) (trace.TracerProvider, error) {
	var sampler tracesdk.Sampler
	if sType := config.SamplerType; len(sType) > 0 {
		// TODO: https://github.com/open-telemetry/opentelemetry-go-contrib/pull/936
		switch strings.ToLower(sType) {
		case "const":
			sampler = tracesdk.TraceIDRatioBased(config.SamplerParam)
		case "probabilistic":
			return nil, fmt.Errorf("probabalistic sampling is no longer available")
		case "ratelimiting":
			return nil, fmt.Errorf("rate limited sampling is no longer available")
		case "remote":
			return nil, fmt.Errorf("remote sampling is no longer available")
		default:
			return nil, fmt.Errorf("unrecognised sampler type: %v", sType)
		}
	}

	// Create the Jaeger exporter
	var epOpt jaeger.EndpointOption
	if config.CollectorURL != "" {
		epOpt = jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(config.CollectorURL))
	} else {
		agentOpts, err := getAgentOpts(config.AgentAddress)
		if err != nil {
			return nil, err
		}

		epOpt = jaeger.WithAgentEndpoint(agentOpts...)
	}

	exp, err := exporterInitFn(epOpt)
	if err != nil {
		return nil, err
	}

	var attrs []attribute.KeyValue
	for k, v := range config.Tags {
		attrs = append(attrs, attribute.String(k, v))
	}

	if _, ok := config.Tags[string(semconv.ServiceNameKey)]; !ok {
		attrs = append(attrs, semconv.ServiceNameKey.String("benthos"))

		// Only set the default service version tag if the user doesn't provide
		// a custom service name tag.
		if _, ok := config.Tags[string(semconv.ServiceVersionKey)]; !ok {
			attrs = append(attrs, semconv.ServiceVersionKey.String(cli.Version))
		}
	}

	var batchOpts []tracesdk.BatchSpanProcessorOption
	if i := config.FlushInterval; len(i) > 0 {
		flushInterval, err := time.ParseDuration(i)
		if err != nil {
			return nil, fmt.Errorf("failed to parse flush interval '%s': %v", i, err)
		}
		batchOpts = append(batchOpts, tracesdk.WithBatchTimeout(flushInterval))
	}

	return tracesdk.NewTracerProvider(
		tracesdk.WithBatcher(exp, batchOpts...),
		tracesdk.WithResource(resource.NewWithAttributes(semconv.SchemaURL, attrs...)),
		tracesdk.WithSampler(sampler),
	), nil
}