Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.

Tag metadata ttl #103

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions lib/opencensus/stats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,20 @@ def registered_measures
#
# @param [String] name Name of the registered measure
# @param [Integer, Float] value Value of the measurement
# @param [Hash<String,String>] tags Tags to which the value is recorded
# @raise [ArgumentError] if givem measure is not register
def create_measurement name:, value:, tags:
# @param [Tags::TagMap] tags A map of tags to which the value is recorded.
# Tags could either be explicitly passed, or implicitly read from
# current tags context.
# @raise [ArgumentError]
# if given measure is not register.
# if given tags are nil and tags global context is nil.
def create_measurement name:, value:, tags: nil
measure = MeasureRegistry.get name
return measure.create_measurement(value: value, tags: tags) if measure
raise ArgumentError, "#{name} measure is not registered"
raise ArgumentError, "#{name} measure is not registered" unless measure

tags ||= OpenCensus::Tags.tag_map_context
raise ArgumentError, "pass tags or set tags global context" unless tags

measure.create_measurement value: value, tags: tags
end

# Create and register a view to current stats recorder context.
Expand Down
2 changes: 1 addition & 1 deletion lib/opencensus/stats/exemplar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Exemplar
# Create instance of the exemplar
# @param [Integer,Float] value
# @param [Time] time
# @param [Hash<String,String>] attachments. Attachments are key-value
# @param [Hash<String,String>] attachments Attachments are key-value
# pairs that describe the context in which the exemplar was recored.
def initialize value:, time:, attachments:
@value = value
Expand Down
3 changes: 2 additions & 1 deletion lib/opencensus/stats/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ def initialize name:, unit:, type:, description: nil
end

# Create new measurement
#
# @param [Integer, Float] value
# @param [Hash<String,String>] tags Tags to which the value is recorded
# @param [Tags::TagMap] tags Tags to which the value is recorded
# @return [Measurement]
def create_measurement value:, tags:
Measurement.new measure: self, value: value, tags: tags
Expand Down
11 changes: 6 additions & 5 deletions lib/opencensus/stats/measurement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ class Measurement
# @return [Integer,Float] The recorded value
attr_reader :value

# @return [TagMap] The tags to which the value is applied
# @return [Tags::TagMap] The collection of tags to which the value is
# applied
attr_reader :tags

# @return [Time] The time when measurement was created.
Expand All @@ -22,12 +23,12 @@ class Measurement
# Create a instance of measurement
#
# @param [Measure] measure A measure to which the value is applied.
# @param [Integer,Float] value Measurement value.
# @param [Hash<String,String>] tags The tags to which the value is applied
def initialize measure:, value:, tags:
# @param [Integer, Float] value Measurement value.
# @param [Tags::TagMap, nil] tags The tags to which the value is applied
def initialize measure:, value:, tags: nil
@measure = measure
@value = value
@tags = Tags::TagMap.new tags
@tags = tags || Tags::TagMap.new
@time = Time.now.utc
end
end
Expand Down
9 changes: 7 additions & 2 deletions lib/opencensus/stats/recorder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,15 @@ def register_view view
view
end

# Record measurements
# Record measurements.
#
# @param [Array<Measurement>, Measurement] measurements
# @param [Hash<String,String>] attachments
# A list of measurements to or single measurement.
# All passed measurements will be rejected If any one of the measurement
# has negative value.
# @param [Hash<String,String>] attachments The contextual information
# associated with an example value. The contextual information is
# represented as key, value string pairs.
def record *measurements, attachments: nil
return if measurements.any? { |m| m.value < 0 }

Expand Down
6 changes: 4 additions & 2 deletions lib/opencensus/stats/view_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ def stop
# @param [Measurement] measurement
# @param [Hash<String,String>] attachments
def record measurement, attachments: nil
tag_values = @view.columns.map { |column| measurement.tags[column] }
tag_values = @view.columns.map do |column|
measurement.tags[column].value if measurement.tags[column]
end

unless @data.key? tag_values
@data[tag_values] = @view.aggregation.create_aggregation_data
Expand All @@ -59,7 +61,7 @@ def record measurement, attachments: nil
)
end

# Clear recorded ata
# Clear recorded data
def clear
data.clear
end
Expand Down
14 changes: 14 additions & 0 deletions lib/opencensus/tags/formatters.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# frozen_string_literal: true

# Copyright 2019 OpenCensus Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require "opencensus/tags/formatters/binary"

module OpenCensus
Expand Down
29 changes: 23 additions & 6 deletions lib/opencensus/tags/formatters/binary.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# frozen_string_literal: true

# Copyright 2019 OpenCensus Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


module OpenCensus
module Tags
module Formatters
Expand Down Expand Up @@ -48,12 +63,14 @@ class BinaryFormatterError < StandardError; end
def serialize tags_context
binary = [int_to_varint(VERSION_ID)]

tags_context.each do |key, value|
tags_context.each do |tag|
next unless tag.propagate?

binary << int_to_varint(TAG_FIELD_ID)
binary << int_to_varint(key.length)
binary << key.encode(Encoding::UTF_8)
binary << int_to_varint(value ? value.length : 0)
binary << value.to_s.encode(Encoding::UTF_8)
binary << int_to_varint(tag.key.length)
binary << tag.key.encode(Encoding::UTF_8)
binary << int_to_varint(tag.value ? tag.value.length : 0)
binary << tag.value.to_s.encode(Encoding::UTF_8)
end

binary = binary.join
Expand Down Expand Up @@ -87,7 +104,7 @@ def deserialize binary
key = io.gets key_length
value_length = varint_to_int io
value = io.gets value_length
tag_map[key] = value
tag_map << Tag.new(key, value)
end

io.close
Expand Down
129 changes: 129 additions & 0 deletions lib/opencensus/tags/tag.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# frozen_string_literal: true

# Copyright 2019 OpenCensus Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


module OpenCensus
module Tags
# # Tag
#
# A Tag consists of key, value and tag metadata(TagTTL)
#
class Tag
# Invalid tag error.
class InvalidTagError < StandardError; end

# The maximum length for a tag key and tag value
MAX_LENGTH = 255

# A tag with no propagation is considered to have local scope and is
# used within the process where it's created.
NO_PROPAGATION = 0

# A tag unlimited propagation can propagate unlimited hops.
# It is typical used to track a request, which may be processed across
# multiple entities.
UNLIMITED_PROPAGATION = -1

# @return [String]
attr_reader :key

# @return [String]
attr_reader :value

# @return [Integer] Represents number of hops a tag can propagate.
attr_reader :ttl

# Create a tag
#
# @param [String] key Tag key
# Maximum allowed length of the key is {MAX_LENGTH} and must contains
# only printable characters.
# @param [String] value Tag value
# Maximum allowed length of the key is {MAX_LENGTH}. Value can be a
# nil value but if it present it must contains only printable
# characters.
# @param [Integer] ttl Tag Represents number of hops a tag can propagate.
# Default value is {UNLIMITED_PROPAGATION} unlimited propagation.
# Currently only two special values {NO_PROPAGATION} and
# {UNLIMITED_PROPAGATION} are supported.
# @raise [InvalidTagError] If invalid tag key or value.
# key: If key is empty, length grater then {MAX_LENGTH} characters or
# contains non printable characters
# value: If value length grater then 255 characters
# or contains non printable characters
#
def initialize key, value, ttl: nil
validate_key! key
validate_value! value
@key = key
@value = value
@ttl = ttl || UNLIMITED_PROPAGATION
end

# Check tag can propagate
# @return [Boolean]
def propagate?
@ttl == -1 || @ttl > 0
end

# Set no propagation A tag with no propagation is considered to have
# local scope and is used within the process where it's created.
def set_no_propagation
@ttl = NO_PROPAGATION
end

# Set unlimited propagation
# A tag unlimited propagation can propagate unlimited hops.
# It is typical used to track a request, which may be processed across
# multiple entities.
def set_unlimited_propagation
@ttl = UNLIMITED_PROPAGATION
end

private

# Validate tag key.
# @param [String] value
# @raise [InvalidTagError] If key is empty, length grater then 255
# characters or contains non printable characters
#
def validate_key! value
if value.empty? || value.length > MAX_LENGTH || !printable_str?(value)
raise InvalidTagError, "Invalid tag key #{key}"
end
end

# Validate tag value.
# @param [String] value
# @raise [InvalidTagError] If value length grater then 255 characters
# or contains non printable characters
#
def validate_value! value
if (value && value.length > MAX_LENGTH) || !printable_str?(value)
raise InvalidTagError, "Invalid tag value #{value}"
end
end

# Check string is printable.
# @param [String] str
# @return [Boolean]
#
def printable_str? str
str.bytes.none? { |b| b < 32 || b > 126 }
end
end
end
end
Loading