Skip to content

Commit

Permalink
Change Metastruct from module to class
Browse files Browse the repository at this point in the history
  • Loading branch information
vpellan committed Feb 6, 2025
1 parent 26f1f6d commit b29e3fb
Show file tree
Hide file tree
Showing 19 changed files with 81 additions and 70 deletions.
1 change: 0 additions & 1 deletion lib/datadog/tracing/metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ module Metadata
def self.included(base)
base.include(Metadata::Tagging)
base.include(Metadata::Errors)
base.include(Metadata::Metastruct)

# Additional extensions
base.prepend(Metadata::Analytics)
Expand Down
40 changes: 33 additions & 7 deletions lib/datadog/tracing/metadata/metastruct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,24 @@ module Datadog
module Tracing
module Metadata
# Adds complex structures tagging behavior through metastruct
module Metastruct
def metastruct=(second)
@metastruct = second
class Metastruct
def initialize(metastruct = nil)
@metastruct = metastruct
end

def deep_merge_metastruct!(second)
# Deep merge two metastructs
# If the types are not both Arrays or Hashes, the second one will overwrite the first one
#
# Example with same types:
# metastruct = { a: { b: [1, 2] } }
# second = { a: { b: [3, 4], c: 5 } }
# result = { a: { b: [1, 2, 3, 4], c: 5 } }
#
# Example with different types:
# metastruct = { a: { b: 1 } }
# second = { a: { b: [2, 3] } }
# result = { a: { b: [2, 3] } }
def deep_merge!(second)
merger = proc do |_, v1, v2|
if v1.is_a?(Hash) && v2.is_a?(Hash)
v1.merge(v2, &merger)
Expand All @@ -24,15 +36,29 @@ def deep_merge_metastruct!(second)
metastruct.merge!(second.to_h, &merger) # steep:ignore BlockTypeMismatch
end

def get_metastruct_field(key)
def [](key)
metastruct[key]
end

def set_metastruct_field(key, value)
def []=(key, value)
metastruct[key] = value
end

protected
def pretty_print(q)
q.seplist metastruct.each do |key, value|
q.text "#{key} => #{value}\n"
end
end

def to_h
metastruct.to_h
end

def to_msgpack(packer = nil)
packer.write(metastruct.transform_values(&:to_msgpack))
end

private

def metastruct
@metastruct ||= {}
Expand Down
6 changes: 3 additions & 3 deletions lib/datadog/tracing/span.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def initialize(
@trace_id = trace_id || Tracing::Utils.next_id

@meta = meta || {}
@metastruct = metastruct || {}
@metastruct = Tracing::Metadata::Metastruct.new(metastruct)
@metrics = metrics || {}
@status = status || 0

Expand Down Expand Up @@ -147,7 +147,7 @@ def to_hash
error: @status,
meta: @meta,
metrics: @metrics,
meta_struct: @metastruct,
meta_struct: @metastruct.to_h,
name: @name,
parent_id: @parent_id,
resource: @resource,
Expand Down Expand Up @@ -195,7 +195,7 @@ def pretty_print(q)
q.text "#{key} => #{value}"
end
end
q.group(2, 'Metastruct: [', ']') do
q.group(2, 'Metastruct: ') do
q.breakable
q.pp metastruct
end
Expand Down
10 changes: 6 additions & 4 deletions lib/datadog/tracing/span_operation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class SpanOperation
:service,
:start_time,
:trace_id,
:type
:type,
:metastruct
attr_accessor :links, :status, :span_events

def initialize(
Expand Down Expand Up @@ -88,6 +89,7 @@ def initialize(

# Set tags if provided.
set_tags(tags) if tags
@metastruct = Tracing::Metadata::Metastruct.new # steep:ignore InsufficientPositionalArguments

# Some other SpanOperation-specific behavior
@events = events || Events.new
Expand Down Expand Up @@ -289,7 +291,7 @@ def to_hash
id: @id,
meta: meta,
metrics: metrics,
metastruct: metastruct,
metastruct: @metastruct.to_h,
name: @name,
parent_id: @parent_id,
resource: @resource,
Expand Down Expand Up @@ -335,7 +337,7 @@ def pretty_print(q)
q.text "#{key} => #{value}"
end
end
q.group(2, 'Metastruct: [', ']') do
q.group(2, 'Metastruct: ') do
q.breakable
q.pp metastruct
end
Expand Down Expand Up @@ -461,7 +463,7 @@ def build_span
id: @id,
meta: Core::Utils::SafeDup.frozen_or_dup(meta),
metrics: Core::Utils::SafeDup.frozen_or_dup(metrics),
metastruct: Core::Utils::SafeDup.frozen_or_dup(metastruct),
metastruct: @metastruct.to_h.dup,
parent_id: @parent_id,
resource: @resource,
service: @service,
Expand Down
9 changes: 5 additions & 4 deletions lib/datadog/tracing/trace_operation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class TraceOperation
:max_length,
:parent_span_id,
:trace_state,
:trace_state_unknown_fields
:trace_state_unknown_fields,
:metastruct

attr_writer \
:name,
Expand Down Expand Up @@ -106,7 +107,7 @@ def initialize(
# Generic tags
set_tags(tags) if tags
set_tags(metrics) if metrics
self.metastruct = metastruct if metastruct
@metastruct = Tracing::Metadata::Metastruct.new(metastruct)

# State
@root_span = nil
Expand Down Expand Up @@ -371,7 +372,7 @@ def fork_clone
trace_state_unknown_fields: (@trace_state_unknown_fields && @trace_state_unknown_fields.dup),
tags: meta.dup,
metrics: metrics.dup,
metastruct: metastruct.dup,
metastruct: @metastruct.to_h.dup,
remote_parent: @remote_parent
)
end
Expand Down Expand Up @@ -511,7 +512,7 @@ def build_trace(spans, partial = false)
service: service,
tags: meta,
metrics: metrics,
metastruct: metastruct,
metastruct: @metastruct.to_h,
root_span_id: !partial ? root_span && root_span.id : nil,
profiling_enabled: @profiling_enabled,
)
Expand Down
2 changes: 1 addition & 1 deletion lib/datadog/tracing/trace_segment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def initialize(
# The caller is expected to have done that
@meta = (tags && tags.dup) || {}
@metrics = (metrics && metrics.dup) || {}
@metastruct = (metastruct && metastruct.dup) || {}
@metastruct = Tracing::Metadata::Metastruct.new(metastruct)

# Set well-known tags, defaulting to getting the values from tags
@agent_sample_rate = agent_sample_rate || agent_sample_rate_tag
Expand Down
2 changes: 1 addition & 1 deletion lib/datadog/tracing/transport/serializable_trace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def to_msgpack(packer = nil)
packer.write(span.metrics)
packer.write('meta_struct')
# We encapsulate the resulting msgpack in a binary msgpack
packer.write(span.metastruct.transform_values(&:to_msgpack))
packer.write(span.metastruct)
packer.write('span_links')
packer.write(span.links.map(&:to_hash))
packer.write('error')
Expand Down
2 changes: 1 addition & 1 deletion lib/datadog/tracing/transport/trace_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def set_trace_tags!
def set_metastruct!
return if partial?

root_span.deep_merge_metastruct!(trace.send(:metastruct))
root_span.metastruct.deep_merge!(trace.send(:metastruct))
end

def tag_agent_sample_rate!
Expand Down
1 change: 0 additions & 1 deletion sig/datadog/tracing/metadata.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module Datadog
module Metadata
include Metadata::Tagging
include Metadata::Errors
include Metadata::Metastruct
prepend Metadata::Analytics
end
end
Expand Down
14 changes: 9 additions & 5 deletions sig/datadog/tracing/metadata/metastruct.rbs
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
module Datadog
module Tracing
module Metadata
module Metastruct
class Metastruct
type metastruct = Hash[String, untyped]

def metastruct=: (metastruct second) -> void
def initialize: (metastruct? second) -> void

def deep_merge_metastruct!: (metastruct second) -> void
def deep_merge!: (metastruct second) -> void

def get_metastruct_field: (String key) -> untyped
def []: (String key) -> untyped

def set_metastruct_field: (String key, untyped value) -> void
def []=: (String key, untyped value) -> void

def to_h: () -> metastruct

private

def metastruct: () -> metastruct
end
Expand Down
2 changes: 1 addition & 1 deletion sig/datadog/tracing/span.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Datadog
attr_accessor end_time: (Time | nil)
attr_accessor id: Integer
attr_accessor meta: Hash[String, String]
attr_accessor metastruct: Metadata::Metastruct::metastruct
attr_accessor metastruct: Metadata::Metastruct
attr_accessor metrics: Hash[String, Float]
attr_accessor name: String
attr_accessor parent_id: Integer
Expand Down
2 changes: 2 additions & 0 deletions sig/datadog/tracing/span_operation.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ module Datadog

attr_reader type: untyped

attr_reader metastruct: Metadata::Metastruct

attr_accessor status: untyped

def initialize: (
Expand Down
1 change: 1 addition & 0 deletions sig/datadog/tracing/trace_operation.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module Datadog
attr_reader id: untyped
attr_reader max_length: untyped
attr_reader parent_span_id: untyped
attr_reader metastruct: Metadata::Metastruct
attr_writer name: untyped
attr_writer resource: untyped
attr_writer sampled: untyped
Expand Down
2 changes: 1 addition & 1 deletion sig/datadog/tracing/trace_segment.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ module Datadog
attr_reader root_span_id: untyped
attr_reader meta: untyped
attr_reader metrics: untyped
attr_reader metastruct: Metadata::Metastruct::metastruct
attr_reader metastruct: Metadata::Metastruct

private

Expand Down
43 changes: 10 additions & 33 deletions spec/datadog/tracing/metadata/metastruct_spec.rb
Original file line number Diff line number Diff line change
@@ -1,51 +1,28 @@
require 'datadog/tracing/metadata/metastruct'

RSpec.describe Datadog::Tracing::Metadata::Metastruct do
subject(:test_object) { test_class.new }
let(:test_class) { Class.new { include Datadog::Tracing::Metadata::Metastruct } }

describe '#metastruct=' do
subject(:metastruct_instance_var) { test_object.send(:metastruct) }
subject(:metastruct) { test_object.send(:metastruct) }
let(:test_object) { described_class.new(preexisting_metastruct) }
let(:preexisting_metastruct) { nil }

describe '#initialize' do
context 'when setting meta struct' do
before do
test_object.instance_variable_set(:@metastruct, preexisting_metastruct)
test_object.metastruct = new_metastruct
context 'with empty metastruct' do
it { is_expected.to eq({}) }
end

let(:preexisting_metastruct) { nil }

context 'with empty preexisting metastruct' do
let(:new_metastruct) { { 'key' => 'value' } }
context 'with not empty metastruct' do
let(:preexisting_metastruct) { { 'key' => 'value' } }

it { is_expected.to eq({ 'key' => 'value' }) }
end

context 'with preexisting metastruct' do
let(:preexisting_metastruct) { { 'old_key' => 'old_value' } }

context 'with new key' do
let(:new_metastruct) { { 'new_key' => 'new_value' } }

it { is_expected.to eq({ 'new_key' => 'new_value' }) }
end

context 'with existing key' do
let(:new_metastruct) { { 'old_key' => 'new_value' } }

it { is_expected.to eq({ 'old_key' => 'new_value' }) }
end
end
end
end

describe '#deep_merge_metastruct!' do
subject(:metastruct_instance_var) { test_object.send(:metastruct) }

describe '#deep_merge!' do
context 'when merging meta struct' do
before do
test_object.instance_variable_set(:@metastruct, preexisting_metastruct)
test_object.deep_merge_metastruct!(new_metastruct)
test_object.deep_merge!(new_metastruct)
end

let(:preexisting_metastruct) { nil }
Expand Down
1 change: 0 additions & 1 deletion spec/datadog/tracing/metadata_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
described_class::Analytics,
described_class::Tagging,
described_class::Errors,
described_class::Metastruct
)
end
end
Expand Down
5 changes: 3 additions & 2 deletions spec/datadog/tracing/trace_operation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
require 'datadog/tracing/trace_operation'
require 'datadog/tracing/trace_segment'
require 'datadog/tracing/utils'
require 'datadog/tracing/metadata/metastruct'

RSpec.describe Datadog::Tracing::TraceOperation do
subject(:trace_op) { described_class.new(**options) }
Expand Down Expand Up @@ -103,7 +104,7 @@
end

it do
expect(trace_op.send(:metastruct)).to eq({})
expect(trace_op.send(:metastruct).to_h).to eq({})
end

context 'when 128 bit trace id generation enabled' do
Expand Down Expand Up @@ -281,7 +282,7 @@
subject(:options) { { metastruct: metastruct } }
let(:metastruct) { { 'foo' => 'bar' } }

it { expect(trace_op.send(:metastruct)).to eq({ 'foo' => 'bar' }) }
it { expect(trace_op.send(:metastruct).to_h).to eq({ 'foo' => 'bar' }) }
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/datadog/tracing/trace_segment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
let(:options) { { metastruct: metastruct } }
let(:metastruct) { { 'foo' => 'bar' } }

it { expect(trace_segment.send(:metastruct)).to eq({ 'foo' => 'bar' }) }
it { expect(trace_segment.send(:metastruct).to_h).to eq({ 'foo' => 'bar' }) }
end

context ':profiling_enabled' do
Expand Down
6 changes: 3 additions & 3 deletions spec/datadog/tracing/transport/trace_formatter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@
context 'metastruct' do
it 'sets root span metastruct from trace metastruct' do
format!
expect(root_span.metastruct).to include(
expect(root_span.metastruct.to_h).to include(
{
'foo' => 'bar',
'baz' => { 'value' => 42 }
Expand All @@ -239,8 +239,8 @@
end

context 'metastruct' do
it { expect(root_span.metastruct).to_not include('foo') }
it { expect(root_span.metastruct).to_not include('baz') }
it { expect(root_span.metastruct.to_h).to_not include('foo') }
it { expect(root_span.metastruct.to_h).to_not include('baz') }
end
end

Expand Down

0 comments on commit b29e3fb

Please sign in to comment.