From 852c92d3812972fb56f1e7f67d7044430f124030 Mon Sep 17 00:00:00 2001 From: Marco Costa Date: Thu, 9 Jan 2025 15:07:57 -0800 Subject: [PATCH] Update Span and SpanOperation pretty print --- lib/datadog/tracing/span.rb | 99 +++++++++++++++------ lib/datadog/tracing/span_event.rb | 17 ++++ lib/datadog/tracing/span_link.rb | 20 +++++ lib/datadog/tracing/span_operation.rb | 32 +------ sig/datadog/tracing/span.rbs | 2 + spec/datadog/tracing/span_operation_spec.rb | 17 ++++ spec/datadog/tracing/span_spec.rb | 10 +++ 7 files changed, 137 insertions(+), 60 deletions(-) diff --git a/lib/datadog/tracing/span.rb b/lib/datadog/tracing/span.rb index be827c78c65..2c411eade6f 100644 --- a/lib/datadog/tracing/span.rb +++ b/lib/datadog/tracing/span.rb @@ -27,12 +27,15 @@ class Span :resource, :service, :links, - :events, :type, :start_time, :status, :trace_id + def events + @span_events + end + attr_writer \ :duration @@ -93,7 +96,7 @@ def initialize( @links = links || [] - @events = events || [] + @span_events = events || [] # Mark with the service entry span metric, if applicable set_metric(Metadata::Ext::TAG_TOP_LEVEL, 1.0) if service_entry @@ -154,43 +157,81 @@ def to_hash h[:duration] = duration_nano end - h[:meta]['events'] = @events.map(&:to_hash).to_json unless @events.empty? + h[:meta]['events'] = @span_events.map(&:to_hash).to_json unless @span_events.empty? h end - # Return a human readable version of the span - def pretty_print(q) - start_time = (self.start_time.to_f * 1e9).to_i - end_time = (self.end_time.to_f * 1e9).to_i - q.group 0 do - q.breakable - q.text "Name: #{@name}\n" - q.text "Span ID: #{@id}\n" - q.text "Parent ID: #{@parent_id}\n" - q.text "Trace ID: #{@trace_id}\n" - q.text "Type: #{@type}\n" - q.text "Service: #{@service}\n" - q.text "Resource: #{@resource}\n" - q.text "Error: #{@status}\n" - q.text "Start: #{start_time}\n" - q.text "End: #{end_time}\n" - q.text "Duration: #{duration.to_f}\n" - q.group(2, 'Tags: [', "]\n") do - q.breakable - q.seplist @meta.each do |key, value| - q.text "#{key} => #{value}" + module PrettyPrint + # Return a human-readable version of this object + # + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/MethodLength + # rubocop:disable Metrics/BlockLength + def pretty_print(q) + start_time = (self.start_time.to_f * 1e9).to_i + end_time = (self.end_time.to_f * 1e9).to_i + q.group 0 do + q.text "Name: #{@name}\n" + q.text "Span ID: #{@id}\n" + q.text "Parent ID: #{@parent_id}\n" + q.text "Trace ID: #{@trace_id}\n" + q.text "Type: #{@type}\n" if @type + q.text "Service: #{@service}\n" + q.text "Resource: #{@resource}\n" + q.text "Error: #{@status}\n" + q.text "Start: #{start_time}\n" + q.text "End: #{end_time}\n" + q.text "Duration: #{duration.to_f}\n" + unless @meta.empty? + q.group(2, 'Tags: [', "]") do + q.breakable + q.seplist @meta.each do |key, value| + q.text "#{key}=#{value}" + end + q.breakable + end + q.breakable end - end - q.group(2, 'Metrics: [', ']') do - q.breakable - q.seplist @metrics.each do |key, value| - q.text "#{key} => #{value}" + unless @metrics.empty? + q.group(2, 'Metrics: [', ']') do + q.breakable + q.seplist @metrics.each do |key, value| + q.text "#{key}=#{value}" + end + q.breakable + end + q.breakable + end + unless @links.empty? + q.group(2, 'Links: [', ']') do + q.breakable + q.seplist @links.each do |link| + q.pp link + end + q.breakable + end + q.breakable + end + unless @span_events.empty? + q.group(2, 'Events: [', ']') do + q.breakable + q.seplist @span_events.each do |event| + q.pp event + end + q.breakable + end + q.breakable end end end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/MethodLength + # rubocop:enable Metrics/BlockLength end + include PrettyPrint + private # Used for serialization diff --git a/lib/datadog/tracing/span_event.rb b/lib/datadog/tracing/span_event.rb index 4a0685e7b15..5f92af5d1eb 100644 --- a/lib/datadog/tracing/span_event.rb +++ b/lib/datadog/tracing/span_event.rb @@ -67,6 +67,23 @@ def to_native_format h end + def pretty_print(q) + q.group 0 do + q.text "Name: #{@name}\n" + q.text "Time: #{@time_unix_nano} ns\n" + unless @attributes.empty? + q.group(2, 'Attributes: [', "]") do + q.breakable + q.seplist @attributes.each do |key, value| + q.text "#{key}=#{value}" + end + q.breakable + end + q.breakable + end + end + end + private MIN_INT64_SIGNED = -2**63 diff --git a/lib/datadog/tracing/span_link.rb b/lib/datadog/tracing/span_link.rb index 4e702a50234..e9dfa979557 100644 --- a/lib/datadog/tracing/span_link.rb +++ b/lib/datadog/tracing/span_link.rb @@ -87,6 +87,26 @@ def to_hash end h end + + def pretty_print(q) + q.group 0 do + q.text "span_id: #{@span_id}," + q.text "trace_id: #{@trace_id}," + q.text "trace_flags: #{@trace_flags}," + q.text "trace_state: #{@trace_state}," + q.text "dropped_attributes: #{@dropped_attributes}" if @dropped_attributes != 0 + unless @attributes.empty? + q.group(2, 'attributes: [', "]") do + q.breakable + q.seplist @attributes.each do |key, value| + q.text "#{key}=#{value}" + end + q.breakable + end + q.breakable + end + end + end end end end diff --git a/lib/datadog/tracing/span_operation.rb b/lib/datadog/tracing/span_operation.rb index 52a8fc469af..62cb0331b4e 100644 --- a/lib/datadog/tracing/span_operation.rb +++ b/lib/datadog/tracing/span_operation.rb @@ -301,37 +301,7 @@ def to_hash h end - # Return a human readable version of the span - def pretty_print(q) - start_time = (self.start_time.to_f * 1e9).to_i - end_time = (self.end_time.to_f * 1e9).to_i - q.group 0 do - q.breakable - q.text "Name: #{@name}\n" - q.text "Span ID: #{@id}\n" - q.text "Parent ID: #{@parent_id}\n" - q.text "Trace ID: #{@trace_id}\n" - q.text "Type: #{@type}\n" - q.text "Service: #{@service}\n" - q.text "Resource: #{@resource}\n" - q.text "Error: #{@status}\n" - q.text "Start: #{start_time}\n" - q.text "End: #{end_time}\n" - q.text "Duration: #{duration.to_f if stopped?}\n" - q.group(2, 'Tags: [', "]\n") do - q.breakable - q.seplist meta.each do |key, value| - q.text "#{key} => #{value}" - end - end - q.group(2, 'Metrics: [', ']') do - q.breakable - q.seplist metrics.each do |key, value| - q.text "#{key} => #{value}" - end - end - end - end + include Span::PrettyPrint # Callback behavior class Events diff --git a/sig/datadog/tracing/span.rbs b/sig/datadog/tracing/span.rbs index 9adb31f126a..f5b87a3d149 100644 --- a/sig/datadog/tracing/span.rbs +++ b/sig/datadog/tracing/span.rbs @@ -3,6 +3,8 @@ module Datadog class Span attr_accessor span_id: Integer + def events: -> SpanEvent + def set_tag: (String key, ?untyped? value) -> void end end diff --git a/spec/datadog/tracing/span_operation_spec.rb b/spec/datadog/tracing/span_operation_spec.rb index 5eef0d6a69c..ea353f3ec05 100644 --- a/spec/datadog/tracing/span_operation_spec.rb +++ b/spec/datadog/tracing/span_operation_spec.rb @@ -995,6 +995,23 @@ end end end + + describe '#pretty_print' do + subject(:pretty_print) { PP.pp(span_op) } + + # Populate list/hash fields + let(:options) do + { + tags: { "meta1" => "1", "meta2" => "2", "metric1" => 1, "metric2" => 2 }, + links: [Datadog::Tracing::SpanLink.new(Datadog::Tracing::TraceDigest.new)], + span_events: [Datadog::Tracing::SpanEvent.new('event')], + } + end + + it 'output without errors' do + expect { pretty_print }.to output.to_stdout + end + end end RSpec.describe Datadog::Tracing::SpanOperation::Events do diff --git a/spec/datadog/tracing/span_spec.rb b/spec/datadog/tracing/span_spec.rb index 0c6bca7f3f0..873a5c39f20 100644 --- a/spec/datadog/tracing/span_spec.rb +++ b/spec/datadog/tracing/span_spec.rb @@ -267,6 +267,16 @@ describe '#pretty_print' do subject(:pretty_print) { PP.pp(span) } + # Populate list/hash fields + let(:span_options) do + { + meta: { "meta1" => "1", "meta2" => "2" }, + metrics: { "metric1" => 1, "metric2" => 2 }, + links: [Datadog::Tracing::SpanLink.new(Datadog::Tracing::TraceDigest.new)], + events: [Datadog::Tracing::SpanEvent.new('event')], + } + end + it 'output without errors' do expect { pretty_print }.to output.to_stdout end