in exporter/trace/trace_proto.go [87:126]
func attributeWithLabelsFromResources(sd sdktrace.ReadOnlySpan) []attribute.KeyValue {
attributes := sd.Attributes()
if sd.Resource().Len() == 0 {
return attributes
}
uniqueAttrs := make(map[attribute.Key]bool, len(sd.Attributes()))
// Span Attributes take precedence
for _, attr := range sd.Attributes() {
uniqueAttrs[attr.Key] = true
}
// Raw resource attributes are next.
for _, attr := range sd.Resource().Attributes() {
if uniqueAttrs[attr.Key] {
continue // skip resource attributes which conflict with span attributes
}
uniqueAttrs[attr.Key] = true
attributes = append(attributes, attr)
}
// Instrumentation Scope attributes come next.
if !uniqueAttrs[instrumentationScopeNameAttribute] {
uniqueAttrs[instrumentationScopeNameAttribute] = true
scopeNameAttrs := attribute.String(instrumentationScopeNameAttribute, sd.InstrumentationScope().Name)
attributes = append(attributes, scopeNameAttrs)
}
if !uniqueAttrs[instrumentationScopeVersionAttribute] && strings.Compare("", sd.InstrumentationScope().Version) != 0 {
uniqueAttrs[instrumentationScopeVersionAttribute] = true
scopeVersionAttrs := attribute.String(instrumentationScopeVersionAttribute, sd.InstrumentationScope().Version)
attributes = append(attributes, scopeVersionAttrs)
}
// Monitored resource attributes (`g.co/r/{resource_type}/{resource_label}`) come next.
gceResource := resourcemapping.ResourceAttributesToMonitoringMonitoredResource(&attrs{
Attrs: sd.Resource().Attributes(),
})
for key, value := range gceResource.Labels {
name := fmt.Sprintf("g.co/r/%v/%v", gceResource.Type, key)
attributes = append(attributes, attribute.String(name, value))
}
return attributes
}