func MakeSegment()

in exporter/awsxrayexporter/internal/translator/segment.go [316:478]


func MakeSegment(span ptrace.Span, resource pcommon.Resource, indexedAttrs []string, indexAllAttrs bool, logGroupNames []string, skipTimestampValidation bool) (*awsxray.Segment, error) {
	var segmentType string

	storeResource := true
	if span.Kind() != ptrace.SpanKindServer &&
		!span.ParentSpanID().IsEmpty() {
		segmentType = "subsegment"
		// We only store the resource information for segments, the local root.
		storeResource = false
	}

	// convert trace id
	traceID, err := convertToAmazonTraceID(span.TraceID(), skipTimestampValidation)
	if err != nil {
		return nil, err
	}

	attributes := span.Attributes()

	var (
		startTime                                          = timestampToFloatSeconds(span.StartTimestamp())
		endTime                                            = timestampToFloatSeconds(span.EndTimestamp())
		httpfiltered, http                                 = makeHTTP(span)
		isError, isFault, isThrottle, causefiltered, cause = makeCause(span, httpfiltered, resource)
		origin                                             = determineAwsOrigin(resource)
		awsfiltered, aws                                   = makeAws(causefiltered, resource, logGroupNames)
		service                                            = makeService(resource)
		sqlfiltered, sql                                   = makeSQL(span, awsfiltered)
		additionalAttrs                                    = addSpecialAttributes(sqlfiltered, indexedAttrs, attributes)
		user, annotations, metadata                        = makeXRayAttributes(additionalAttrs, resource, storeResource, indexedAttrs, indexAllAttrs)
		spanLinks, makeSpanLinkErr                         = makeSpanLinks(span.Links(), skipTimestampValidation)
		name                                               string
		namespace                                          string
	)

	if makeSpanLinkErr != nil {
		return nil, makeSpanLinkErr
	}

	// X-Ray segment names are service names, unlike span names which are methods. Try to find a service name.

	// support x-ray specific service name attributes as segment name if it exists
	if span.Kind() == ptrace.SpanKindServer {
		if localServiceName, ok := attributes.Get(awsLocalService); ok {
			name = localServiceName.Str()
		}
	}

	myAwsSpanKind, _ := span.Attributes().Get(awsSpanKind)
	if span.Kind() == ptrace.SpanKindInternal && myAwsSpanKind.Str() == localRoot {
		if localServiceName, ok := attributes.Get(awsLocalService); ok {
			name = localServiceName.Str()
		}
	}

	if span.Kind() == ptrace.SpanKindClient || span.Kind() == ptrace.SpanKindProducer || span.Kind() == ptrace.SpanKindConsumer {
		if remoteServiceName, ok := attributes.Get(awsRemoteService); ok {
			name = remoteServiceName.Str()
			// only strip the prefix for AWS spans
			name = trimAwsSdkPrefix(name, span)
		}
	}

	// peer.service should always be prioritized for segment names when it set by users and
	// the new x-ray specific service name attributes are not found
	if name == "" {
		if peerService, ok := attributes.Get(conventionsv112.AttributePeerService); ok {
			name = peerService.Str()
		}
	}

	if namespace == "" {
		if isAwsSdkSpan(span) {
			namespace = conventionsv112.AttributeCloudProviderAWS
		}
	}

	if name == "" {
		if awsService, ok := attributes.Get(awsxray.AWSServiceAttribute); ok {
			// Generally spans are named something like "Method" or "Service.Method" but for AWS spans, X-Ray expects spans
			// to be named "Service"
			name = awsService.Str()

			if namespace == "" {
				namespace = conventionsv112.AttributeCloudProviderAWS
			}
		}
	}

	if name == "" {
		if dbInstance, ok := attributes.Get(conventionsv112.AttributeDBName); ok {
			// For database queries, the segment name convention is <db name>@<db host>
			name = dbInstance.Str()
			if dbURL, ok := attributes.Get(conventionsv112.AttributeDBConnectionString); ok {
				// Trim JDBC connection string if starts with "jdbc:", otherwise no change
				// jdbc:mysql://db.dev.example.com:3306
				dbURLStr := strings.TrimPrefix(dbURL.Str(), "jdbc:")
				if parsed, _ := url.Parse(dbURLStr); parsed != nil {
					if parsed.Hostname() != "" {
						name += "@" + parsed.Hostname()
					}
				}
			}
		}
	}

	if name == "" && span.Kind() == ptrace.SpanKindServer {
		// Only for a server span, we can use the resource.
		if service, ok := resource.Attributes().Get(conventionsv112.AttributeServiceName); ok {
			name = service.Str()
		}
	}

	if name == "" {
		if rpcservice, ok := attributes.Get(conventionsv112.AttributeRPCService); ok {
			name = rpcservice.Str()
		}
	}

	if name == "" {
		if host, ok := attributes.Get(conventionsv112.AttributeHTTPHost); ok {
			name = host.Str()
		}
	}

	if name == "" {
		if peer, ok := attributes.Get(conventionsv112.AttributeNetPeerName); ok {
			name = peer.Str()
		}
	}

	if name == "" {
		name = fixSegmentName(span.Name())
	}

	if namespace == "" && span.Kind() == ptrace.SpanKindClient {
		namespace = "remote"
	}

	return &awsxray.Segment{
		ID:          awsxray.String(traceutil.SpanIDToHexOrEmptyString(span.SpanID())),
		TraceID:     awsxray.String(traceID),
		Name:        awsxray.String(name),
		StartTime:   awsP.Float64(startTime),
		EndTime:     awsP.Float64(endTime),
		ParentID:    awsxray.String(traceutil.SpanIDToHexOrEmptyString(span.ParentSpanID())),
		Fault:       awsP.Bool(isFault),
		Error:       awsP.Bool(isError),
		Throttle:    awsP.Bool(isThrottle),
		Cause:       cause,
		Origin:      awsxray.String(origin),
		Namespace:   awsxray.String(namespace),
		User:        awsxray.String(user),
		HTTP:        http,
		AWS:         aws,
		Service:     service,
		SQL:         sql,
		Annotations: annotations,
		Metadata:    metadata,
		Type:        awsxray.String(segmentType),
		Links:       spanLinks,
	}, nil
}