lib/opentelemetry/exporters/datadog/exporter/span_encoder.rb in opentelemetry-exporters-datadog-0.1.0 vs lib/opentelemetry/exporters/datadog/exporter/span_encoder.rb in opentelemetry-exporters-datadog-0.2.0

- old
+ new

@@ -30,10 +30,13 @@ SAMPLE_RATE_METRIC_KEY = '_sample_rate' SAMPLING_PRIORITY_KEY = '_sampling_priority_v1' ORIGIN_REGEX = /#{DD_ORIGIN}\=(.*?)($|,)/.freeze PROBABILITY_REGEX = /\d[.]\d{1,6}/.freeze TRUNCATION_HELPER = ::Datadog::DistributedTracing::Headers::Headers.new({}) + RESOURCE_SERVICE_TAG = 'service.name' + RESOURCE_VERSION_TAG = 'service.version' + RESOURCE_ENVIRONMENT_TAG = 'deployment.environment' INSTRUMENTATION_SPAN_TYPES = { 'OpenTelemetry::Instrumentation::Ethon' => ::Datadog::Ext::HTTP::TYPE_OUTBOUND, 'OpenTelemetry::Instrumentation::Excon' => ::Datadog::Ext::HTTP::TYPE_OUTBOUND, 'OpenTelemetry::Instrumentation::Faraday' => ::Datadog::Ext::HTTP::TYPE_OUTBOUND, @@ -54,24 +57,27 @@ otel_spans.each do |span| trace_id, span_id, parent_id = get_trace_ids(span) span_type = get_span_type(span) span_name = get_span_name(span) + # this excludes service.name, which we get seperately + span_resource_tags, resource_service_name, resource_environment_name, resource_version_name = get_resource_tags_and_service(span) + + default_tags_including_resource = default_tags.merge(span_resource_tags) datadog_span = ::Datadog::Span.new(nil, span_name, - service: service, + service: resource_service_name || service, trace_id: trace_id, parent_id: parent_id, resource: get_resource(span), span_type: span_type) - # span_id is autogenerated so have to override datadog_span.span_id = span_id datadog_span.start_time = span.start_timestamp datadog_span.end_time = span.end_timestamp # set span.error, span tag error.msg/error.type - if span.status && span.status.canonical_code != OpenTelemetry::Trace::Status::OK + if span.status && !span.status.ok? datadog_span.status = 1 exception_type, exception_msg, exception_stack = get_exception_info(span) if exception_type && exception_msg && exception_stack @@ -80,18 +86,18 @@ datadog_span.set_tag('error.stack', exception_stack) end end # set default tags - default_tags&.keys&.each do |attribute| - datadog_span.set_tag(attribute, span.attributes[attribute]) + default_tags_including_resource&.keys&.each do |attribute| + datadog_span.set_tag(attribute, default_tags_including_resource[attribute]) end origin = get_origin_string(span) datadog_span.set_tag(DD_ORIGIN, origin) if origin && parent_id.zero? - datadog_span.set_tag(VERSION_KEY, version) if version && parent_id.zero? - datadog_span.set_tag(ENV_KEY, env) if env + datadog_span.set_tag(VERSION_KEY, resource_version_name || version) if (resource_version_name || version) && parent_id.zero? + datadog_span.set_tag(ENV_KEY, resource_environment_name || env) if resource_version_name || env # set tags - takes precedence over env vars span.attributes&.keys&.each do |attribute| datadog_span.set_tag(attribute, span.attributes[attribute]) end @@ -101,11 +107,10 @@ if filter_internal_request?(span) datadog_span.set_metric(SAMPLE_RATE_METRIC_KEY, USER_REJECT) elsif sampling_rate datadog_span.set_metric(SAMPLE_RATE_METRIC_KEY, sampling_rate) end - datadog_spans << datadog_span end datadog_spans end @@ -179,9 +184,37 @@ instrumentation_name = span.instrumentation_library&.name kind = span.kind instrumentation_name && kind ? "#{instrumentation_name.to_s.gsub(':', '_')}.#{kind}" : span.name rescue NoMethodError span.name + end + + def get_resource_tags_and_service(span) + resource_tags = {} + service_name = nil + environment_name = nil + version_name = nil + # this is open to change in new versions so being extra defensive here + return resource_tags unless (resource_attributes = begin + span.resource.attribute_enumerator.to_h + rescue StandardError + nil + end) + + # grab service name seperately since it has significance + resource_attributes.each do |rattribute_key, rattribute_value| + if rattribute_key == RESOURCE_SERVICE_TAG + service_name = rattribute_value + elsif rattribute_key == RESOURCE_ENVIRONMENT_TAG + environment_name = rattribute_value + elsif rattribute_key == RESOURCE_VERSION_TAG + version_name = rattribute_value + else + resource_tags[rattribute_key] = rattribute_value + end + end + + [resource_tags, service_name, environment_name, version_name] end def get_origin_string(span) tracestate = begin span.tracestate