in pkg/tracegen/otlp.go [50:104]
func SendOTLPTrace(ctx context.Context, cfg Config) (EventStats, error) {
if err := cfg.validate(); err != nil {
return EventStats{}, err
}
endpointURL, err := url.Parse(cfg.apmServerURL)
if err != nil {
return EventStats{}, fmt.Errorf("failed to parse endpoint: %w", err)
}
switch endpointURL.Scheme {
case "http":
if endpointURL.Port() == "" {
endpointURL.Host = net.JoinHostPort(endpointURL.Host, "80")
}
case "https":
if endpointURL.Port() == "" {
endpointURL.Host = net.JoinHostPort(endpointURL.Host, "443")
}
default:
return EventStats{}, fmt.Errorf("endpoint must be prefixed with http:// or https://")
}
otlpExporters, err := newOTLPExporters(ctx, endpointURL, cfg)
if err != nil {
return EventStats{}, err
}
defer otlpExporters.cleanup(ctx)
resource := resource.NewSchemaless(
attribute.String("service.name", cfg.otlpServiceName),
)
tracerProvider := sdktrace.NewTracerProvider(
sdktrace.WithSyncer(otlpExporters.trace),
sdktrace.WithResource(resource),
)
// generateSpans returns ctx that contains trace context
var stats EventStats
ctx, err = generateSpans(ctx, tracerProvider.Tracer("tracegen"), &stats)
if err != nil {
return EventStats{}, err
}
if err := generateLogs(ctx, otlpExporters.log, resource, &stats); err != nil {
return EventStats{}, err
}
// Shutdown, flushing all data to the server.
if err := tracerProvider.Shutdown(ctx); err != nil {
return EventStats{}, err
}
if err := otlpExporters.cleanup(ctx); err != nil {
return EventStats{}, err
}
return stats, nil
}