Skip to content

Commit

Permalink
Initial implementation of SDK correlation context
Browse files Browse the repository at this point in the history
  • Loading branch information
mwear committed Nov 13, 2019
1 parent b567d98 commit eef67cb
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 1 deletion.
2 changes: 1 addition & 1 deletion api/lib/opentelemetry/distributed_context/label.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Label
# @param [Key] key The name of the label
# @param [Value] value The value associated with key
# @param [Metadata] metadata Properties associated with the label
def initialize(key:, value:, metadata:)
def initialize(key:, value:, metadata: Metadata::NO_PROPAGATION)
@key = key
@value = value
@metadata = metadata
Expand Down
1 change: 1 addition & 0 deletions sdk/lib/opentelemetry/sdk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module SDK
end

require 'opentelemetry/sdk/baggage'
require 'opentelemetry/sdk/distributed_context'
require 'opentelemetry/sdk/internal'
require 'opentelemetry/sdk/resources'
require 'opentelemetry/sdk/trace'
Expand Down
18 changes: 18 additions & 0 deletions sdk/lib/opentelemetry/sdk/distributed_context.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

# Copyright 2019 OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require 'opentelemetry/sdk/distributed_context/correlation_context'

module OpenTelemetry
module SDK
# DistributedContext is an abstract data type that represents a collection of entries. Each key of a DistributedContext is
# associated with exactly one value. DistributedContext is serializable, to facilitate propagating it not only inside the
# process but also across process boundaries. DistributedContext is used to annotate telemetry with the name:value pair
# Entry. Those values can be used to add dimensions to the metric or additional context properties to logs and traces.
module DistributedContext
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

# Copyright 2019 OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

module OpenTelemetry
module SDK
module DistributedContext
# SDK implementation of CorrelationContext
class CorrelationContext
attr_reader :entries

# Returns a new CorrelationContext. If a parent is provided, entries
# will be inherited by the new context, but can be overridden or removed
# by specifiying +entries+ or +remove_keys+.
#
# @param [optional CorrelationContext] parent An optional parent context
# @param [optional Hash<Label::key,Label>] entries A hash of
# Label::Key-Label pairs for this context
# @param [optional Array<Label::Key>] remove_keys Keys to be removed
# from this context
def initialize(parent: nil, entries: {}, remove_keys: nil)
@parent = parent
@entries = if @parent
entries.merge!(parent.entries) { |_, v, _| v }
else
@entries = entries
end
remove_keys&.each { |key| @entries.delete(key) }
@entries.freeze
end

# Returns the label associated with key
#
# @param key
# @return [Label]
def [](key)
@entries[key]
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# frozen_string_literal: true

# Copyright 2019 OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require 'test_helper'

describe OpenTelemetry::SDK::DistributedContext::CorrelationContext do
CorrelationContext = OpenTelemetry::SDK::DistributedContext::CorrelationContext
Label = OpenTelemetry::DistributedContext::Label
Key = OpenTelemetry::DistributedContext::Label::Key
Value = OpenTelemetry::DistributedContext::Label::Value
Metadata = OpenTelemetry::DistributedContext::Label::Metadata

let(:foo_key) { Key.new('foo') }
let(:bar_key) { Key.new('bar') }
let(:baz_key) { Key.new('baz') }
let(:foo_label) do
Label.new(
key: foo_key,
value: Value.new('bar')
)
end
let(:bar_label) do
Label.new(
key: bar_key,
value: Value.new('baz')
)
end
let(:baz_label) do
Label.new(
key: baz_key,
value: Value.new('quux')
)
end

describe '.new' do
it 'does not require any defaults' do
ctx = CorrelationContext.new
_(ctx.entries).must_be(:empty?)
end

it 'reflects entries passed in' do
entries = {
foo_key => foo_label,
bar_key => bar_label
}

ctx = CorrelationContext.new(entries: entries)

_(ctx.entries).must_equal(entries)
end

it 'removes keys specified' do
entries = {
foo_key => foo_label,
bar_key => bar_label
}

ctx = CorrelationContext.new(entries: entries, remove_keys: [bar_key])

_(ctx.entries).must_equal(foo_key => foo_label)
end

describe 'with parent' do
let(:parent_ctx) do
CorrelationContext.new(entries: { baz_key => baz_label })
end

it 'inherits entries' do
ctx = CorrelationContext.new(parent: parent_ctx)
_(ctx.entries).must_equal(parent_ctx.entries)
end

it 'merges entries' do
ctx = CorrelationContext.new(
parent: parent_ctx,
entries: {
foo_key => foo_label,
bar_key => bar_label
}
)
_(ctx.entries).must_equal(
foo_key => foo_label,
bar_key => bar_label,
baz_key => baz_label
)
end

it 'replaces entries on merge' do
ctx = CorrelationContext.new(
parent: parent_ctx,
entries: {
foo_key => foo_label,
baz_key => bar_label
}
)
_(ctx.entries).must_equal(
foo_key => foo_label,
baz_key => bar_label
)
end

it 'removes keys specified' do
ctx = CorrelationContext.new(
parent: parent_ctx,
entries: {
foo_key => foo_label,
bar_key => bar_label
},
remove_keys: [baz_key]
)
_(ctx.entries).must_equal(
foo_key => foo_label,
bar_key => bar_label
)
end
end
end
end

0 comments on commit eef67cb

Please sign in to comment.