opentelemetry-api 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +1 -0
- data/LICENSE +201 -0
- data/lib/opentelemetry.rb +43 -0
- data/lib/opentelemetry/context.rb +31 -0
- data/lib/opentelemetry/distributed_context.rb +19 -0
- data/lib/opentelemetry/distributed_context/distributed_context.rb +24 -0
- data/lib/opentelemetry/distributed_context/entry.rb +66 -0
- data/lib/opentelemetry/distributed_context/manager.rb +12 -0
- data/lib/opentelemetry/distributed_context/propagation.rb +19 -0
- data/lib/opentelemetry/distributed_context/propagation/binary_format.rb +26 -0
- data/lib/opentelemetry/distributed_context/propagation/text_format.rb +76 -0
- data/lib/opentelemetry/distributed_context/propagation/trace_parent.rb +124 -0
- data/lib/opentelemetry/error.rb +9 -0
- data/lib/opentelemetry/internal.rb +22 -0
- data/lib/opentelemetry/metrics.rb +16 -0
- data/lib/opentelemetry/metrics/handles.rb +54 -0
- data/lib/opentelemetry/metrics/instruments.rb +156 -0
- data/lib/opentelemetry/metrics/meter.rb +109 -0
- data/lib/opentelemetry/metrics/meter_factory.rb +22 -0
- data/lib/opentelemetry/trace.rb +53 -0
- data/lib/opentelemetry/trace/event.rb +45 -0
- data/lib/opentelemetry/trace/link.rb +45 -0
- data/lib/opentelemetry/trace/sampling_hint.rb +22 -0
- data/lib/opentelemetry/trace/span.rb +137 -0
- data/lib/opentelemetry/trace/span_context.rb +56 -0
- data/lib/opentelemetry/trace/span_kind.rb +35 -0
- data/lib/opentelemetry/trace/status.rb +109 -0
- data/lib/opentelemetry/trace/trace_flags.rb +50 -0
- data/lib/opentelemetry/trace/tracer.rb +69 -0
- data/lib/opentelemetry/trace/tracer_factory.rb +45 -0
- data/lib/opentelemetry/version.rb +10 -0
- metadata +200 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
module OpenTelemetry
|
7
|
+
module DistributedContext
|
8
|
+
module Propagation
|
9
|
+
# TextFormat is a formatter that injects and extracts a value as text into carriers that travel in-band across
|
10
|
+
# process boundaries.
|
11
|
+
# Encoding is expected to conform to the HTTP Header Field semantics. Values are often encoded as RPC/HTTP request
|
12
|
+
# headers.
|
13
|
+
#
|
14
|
+
# The carrier of propagated data on both the client (injector) and server (extractor) side is usually an http request.
|
15
|
+
# Propagation is usually implemented via library-specific request interceptors, where the client-side injects values
|
16
|
+
# and the server-side extracts them.
|
17
|
+
class TextFormat
|
18
|
+
DEFAULT_GETTER = ->(carrier, key) { carrier[key] }
|
19
|
+
DEFAULT_SETTER = ->(carrier, key, value) { carrier[key] = value }
|
20
|
+
private_constant(:DEFAULT_GETTER, :DEFAULT_SETTER)
|
21
|
+
|
22
|
+
# Returns an array with the trace context header keys used by this formatter
|
23
|
+
attr_reader :fields
|
24
|
+
|
25
|
+
# Returns a new TextFormat that injects and extracts using the specified trace context
|
26
|
+
# header keys
|
27
|
+
#
|
28
|
+
# @param [String] traceparent_header_key The traceparent header key used in the carrier
|
29
|
+
# @param [String] tracestate_header_key The tracestate header key used in the carrier
|
30
|
+
# @return [TextFormatter]
|
31
|
+
def initialize(traceparent_header_key:, tracestate_header_key:)
|
32
|
+
@traceparent_header_key = traceparent_header_key
|
33
|
+
@tracestate_header_key = tracestate_header_key
|
34
|
+
@fields = [traceparent_header_key, tracestate_header_key].freeze
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return a remote {Trace::SpanContext} extracted from the supplied carrier. Expects the
|
38
|
+
# the supplied carrier to have keys in rack normalized format (HTTP_#{UPPERCASE_KEY}).
|
39
|
+
# Invalid headers will result in a new, valid, non-remote {Trace::SpanContext}.
|
40
|
+
#
|
41
|
+
# @param [Carrier] carrier The carrier to get the header from.
|
42
|
+
# @param [optional Callable] getter An optional callable that takes a carrier and a key and
|
43
|
+
# returns the value associated with the key. If omitted the default getter will be used
|
44
|
+
# which expects the carrier to respond to [] and []=.
|
45
|
+
# @yield [Carrier, String] if an optional getter is provided, extract will yield the carrier
|
46
|
+
# and the header key to the getter.
|
47
|
+
# @return [SpanContext] the span context from the header, or a new one if parsing fails.
|
48
|
+
def extract(carrier, &getter)
|
49
|
+
getter ||= DEFAULT_GETTER
|
50
|
+
header = getter.call(carrier, @traceparent_header_key)
|
51
|
+
tp = TraceParent.from_string(header)
|
52
|
+
|
53
|
+
tracestate = getter.call(carrier, @tracestate_header_key)
|
54
|
+
|
55
|
+
Trace::SpanContext.new(trace_id: tp.trace_id, span_id: tp.span_id, trace_flags: tp.flags, tracestate: tracestate, remote: true)
|
56
|
+
rescue OpenTelemetry::Error
|
57
|
+
Trace::SpanContext.new
|
58
|
+
end
|
59
|
+
|
60
|
+
# Set the span context on the supplied carrier.
|
61
|
+
#
|
62
|
+
# @param [SpanContext] context The active {Trace::SpanContext}.
|
63
|
+
# @param [optional Callable] setter An optional callable that takes a carrier and a key and
|
64
|
+
# a value and assigns the key-value pair in the carrier. If omitted the default setter
|
65
|
+
# will be used which expects the carrier to respond to [] and []=.
|
66
|
+
# @yield [Carrier, String, String] if an optional setter is provided, inject will yield
|
67
|
+
# carrier, header key, header value to the setter.
|
68
|
+
def inject(context, carrier, &setter)
|
69
|
+
setter ||= DEFAULT_SETTER
|
70
|
+
setter.call(carrier, @traceparent_header_key, TraceParent.from_context(context).to_s)
|
71
|
+
setter.call(carrier, @tracestate_header_key, context.tracestate) unless context.tracestate.nil?
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
module OpenTelemetry
|
7
|
+
module DistributedContext
|
8
|
+
module Propagation
|
9
|
+
# A TraceParent is an implementation of the W3C trace context specification
|
10
|
+
# https://www.w3.org/TR/trace-context/
|
11
|
+
# {Trace::SpanContext}
|
12
|
+
class TraceParent
|
13
|
+
InvalidFormatError = Class.new(Error)
|
14
|
+
InvalidVersionError = Class.new(Error)
|
15
|
+
InvalidTraceIDError = Class.new(Error)
|
16
|
+
InvalidSpanIDError = Class.new(Error)
|
17
|
+
|
18
|
+
TRACE_PARENT_HEADER = 'traceparent'
|
19
|
+
SUPPORTED_VERSION = 0
|
20
|
+
private_constant :SUPPORTED_VERSION
|
21
|
+
MAX_VERSION = 254
|
22
|
+
private_constant :MAX_VERSION
|
23
|
+
|
24
|
+
REGEXP = /^(?<version>[A-Fa-f0-9]{2})-(?<trace_id>[A-Fa-f0-9]{32})-(?<span_id>[A-Fa-f0-9]{16})-(?<flags>[A-Fa-f0-9]{2})(?<ignored>-.*)?$/.freeze
|
25
|
+
private_constant :REGEXP
|
26
|
+
|
27
|
+
class << self
|
28
|
+
# Creates a new {TraceParent} from a supplied {Trace::SpanContext}
|
29
|
+
# @param [SpanContext] ctx The context
|
30
|
+
# @return [TraceParent] a trace parent
|
31
|
+
def from_context(ctx)
|
32
|
+
new(trace_id: ctx.trace_id, span_id: ctx.span_id, flags: ctx.trace_flags)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Deserializes the {TraceParent} from the string representation
|
36
|
+
# @param [String] string The serialized trace parent
|
37
|
+
# @return [TraceParent] a trace_parent
|
38
|
+
# @raise [InvalidFormatError] on an invalid format
|
39
|
+
# @raise [InvalidVerionError] on an invalid version
|
40
|
+
# @raise [InvalidTraceIDError] on an invalid trace_id
|
41
|
+
# @raise [InvalidSpanIDError] on an invalid span_id
|
42
|
+
def from_string(string)
|
43
|
+
matches = match_input(string)
|
44
|
+
|
45
|
+
version = parse_version(matches[:version])
|
46
|
+
raise InvalidFormatError if version > SUPPORTED_VERSION && string.length < 55
|
47
|
+
|
48
|
+
trace_id = parse_trace_id(matches[:trace_id])
|
49
|
+
span_id = parse_span_id(matches[:span_id])
|
50
|
+
flags = parse_flags(matches[:flags])
|
51
|
+
|
52
|
+
new(trace_id: trace_id, span_id: span_id, flags: flags)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def match_input(string)
|
58
|
+
matches = REGEXP.match(string)
|
59
|
+
raise InvalidFormatError, 'regexp match failed' if !matches || matches.length < 6
|
60
|
+
|
61
|
+
matches
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse_version(string)
|
65
|
+
v = string.to_i(16)
|
66
|
+
raise InvalidFormatError, string unless v
|
67
|
+
raise InvalidVersionError, v if v > MAX_VERSION
|
68
|
+
|
69
|
+
v
|
70
|
+
end
|
71
|
+
|
72
|
+
def parse_trace_id(string)
|
73
|
+
raise InvalidTraceIDError, string if string == OpenTelemetry::Trace::INVALID_TRACE_ID
|
74
|
+
|
75
|
+
string.downcase!
|
76
|
+
string
|
77
|
+
end
|
78
|
+
|
79
|
+
def parse_span_id(string)
|
80
|
+
raise InvalidSpanIDError, string if string == OpenTelemetry::Trace::INVALID_SPAN_ID
|
81
|
+
|
82
|
+
string.downcase!
|
83
|
+
string
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_flags(string)
|
87
|
+
OpenTelemetry::Trace::TraceFlags.from_byte(string.to_i(16))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
attr_reader :version, :trace_id, :span_id, :flags
|
92
|
+
|
93
|
+
private_class_method :new
|
94
|
+
|
95
|
+
# Returns the sampling choice from the trace_flags
|
96
|
+
# @return [Boolean] the sampling choice
|
97
|
+
def sampled?
|
98
|
+
flags.sampled?
|
99
|
+
end
|
100
|
+
|
101
|
+
# converts this object into a string according to the w3c spec
|
102
|
+
# @return [String] the serialized trace_parent
|
103
|
+
def to_s
|
104
|
+
"00-#{trace_id}-#{span_id}-#{flag_string}"
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def flag_string
|
110
|
+
# the w3c standard only dictates the one flag for this version
|
111
|
+
# therefore we can only output the one flag.
|
112
|
+
flags.sampled? ? '01' : '00'
|
113
|
+
end
|
114
|
+
|
115
|
+
def initialize(trace_id: nil, span_id: nil, version: SUPPORTED_VERSION, flags: Trace::TraceFlags::DEFAULT)
|
116
|
+
@trace_id = trace_id
|
117
|
+
@span_id = span_id
|
118
|
+
@version = version
|
119
|
+
@flags = flags
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
# @api private
|
9
|
+
#
|
10
|
+
# Internal contains helpers used by the no-op API implementation.
|
11
|
+
module Internal
|
12
|
+
extend self
|
13
|
+
|
14
|
+
def printable_ascii?(string)
|
15
|
+
return false unless string.is_a?(String)
|
16
|
+
|
17
|
+
r = 32..126
|
18
|
+
string.each_codepoint { |c| return false unless r.include?(c) }
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
require 'opentelemetry/metrics/handles'
|
8
|
+
require 'opentelemetry/metrics/instruments'
|
9
|
+
require 'opentelemetry/metrics/meter'
|
10
|
+
require 'opentelemetry/metrics/meter_factory'
|
11
|
+
|
12
|
+
module OpenTelemetry
|
13
|
+
# The Metrics API allows reporting raw measurements as well as metrics with known aggregation and labels.
|
14
|
+
module Metrics
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
module Metrics
|
9
|
+
# In situations where performance is a requirement and a metric is
|
10
|
+
# repeatedly used with the same set of labels, the developer may elect to
|
11
|
+
# use instrument {Handles} as an optimization. For handles to be a benefit,
|
12
|
+
# it requires that a specific instrument will be re-used with specific
|
13
|
+
# labels. If an instrument will be used with the same label set more than
|
14
|
+
# once, obtaining an instrument handle corresponding to the label set
|
15
|
+
# ensures the highest performance available.
|
16
|
+
#
|
17
|
+
# To obtain a handle given an instrument and label set, use the #handle
|
18
|
+
# method to return an interface that supports the #add, #set, or #record
|
19
|
+
# method of the instrument in question.
|
20
|
+
#
|
21
|
+
# Instrument handles may consume SDK resources indefinitely.
|
22
|
+
module Handles
|
23
|
+
# A float gauge handle.
|
24
|
+
class FloatGauge
|
25
|
+
def set(value); end
|
26
|
+
end
|
27
|
+
|
28
|
+
# An integer gauge handle.
|
29
|
+
class IntegerGauge
|
30
|
+
def set(value); end
|
31
|
+
end
|
32
|
+
|
33
|
+
# A float counter handle.
|
34
|
+
class FloatCounter
|
35
|
+
def add(value); end
|
36
|
+
end
|
37
|
+
|
38
|
+
# An integer counter handle.
|
39
|
+
class IntegerCounter
|
40
|
+
def add(value); end
|
41
|
+
end
|
42
|
+
|
43
|
+
# A float measure handle.
|
44
|
+
class FloatMeasure
|
45
|
+
def record(value); end
|
46
|
+
end
|
47
|
+
|
48
|
+
# An integer measure handle.
|
49
|
+
class IntegerMeasure
|
50
|
+
def record(value); end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
module Metrics
|
9
|
+
# The user-facing metrics API supports producing diagnostic measurements
|
10
|
+
# using three basic kinds of instrument. "Metrics" are the thing being
|
11
|
+
# produced -- mathematical, statistical summaries of certain observable
|
12
|
+
# behavior in the program. "Instruments" are the devices used by the
|
13
|
+
# program to record observations about their behavior. Therefore, we use
|
14
|
+
# "metric instrument" to refer to a program object, allocated through the
|
15
|
+
# API, used for recording metrics. There are three distinct instruments in
|
16
|
+
# the Metrics API, commonly known as Counters, Gauges, and Measures.
|
17
|
+
module Instruments
|
18
|
+
# A float gauge instrument.
|
19
|
+
class FloatGauge
|
20
|
+
# Set the value of the gauge.
|
21
|
+
#
|
22
|
+
# @param [Float] value The value to set.
|
23
|
+
# @param [optional LabelSet, Hash<String, String>] labels_or_label_set
|
24
|
+
# A {LabelSet} returned from {Meter#labels} or a Hash of Strings.
|
25
|
+
def set(value, labels_or_label_set = {}); end
|
26
|
+
|
27
|
+
# Obtain a handle from the instrument and label set.
|
28
|
+
#
|
29
|
+
# @param [optional LabelSet, Hash<String, String>] labels_or_label_set
|
30
|
+
# A {LabelSet} returned from {Meter#labels} or a Hash of Strings.
|
31
|
+
# @return [Handles::FloatGauge]
|
32
|
+
def handle(labels_or_label_set = {})
|
33
|
+
Handles::FloatGauge.new
|
34
|
+
end
|
35
|
+
|
36
|
+
# Return a measurement to be recorded via {Meter#record_batch}.
|
37
|
+
#
|
38
|
+
# @param [Float] value
|
39
|
+
# @return [Object, Measurement]
|
40
|
+
def measurement(value)
|
41
|
+
NOOP_MEASUREMENT
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# An integer gauge instrument.
|
46
|
+
class IntegerGauge
|
47
|
+
def set(value, labels_or_label_set = {}); end
|
48
|
+
|
49
|
+
# Obtain a handle from the instrument and label set.
|
50
|
+
#
|
51
|
+
# @param [optional LabelSet, Hash<String, String>] labels_or_label_set
|
52
|
+
# A {LabelSet} returned from {Meter#labels} or a Hash of Strings.
|
53
|
+
# @return [Handles::IntegerGauge]
|
54
|
+
def handle(labels_or_label_set = {})
|
55
|
+
Handles::IntegerGauge.new
|
56
|
+
end
|
57
|
+
|
58
|
+
# Return a measurement to be recorded via {Meter#record_batch}.
|
59
|
+
#
|
60
|
+
# @param [Integer] value
|
61
|
+
# @return [Object, Measurement]
|
62
|
+
def measurement(value)
|
63
|
+
NOOP_MEASUREMENT
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# A float counter instrument.
|
68
|
+
class FloatCounter
|
69
|
+
def add(value, labels_or_label_set = {}); end
|
70
|
+
|
71
|
+
# Obtain a handle from the instrument and label set.
|
72
|
+
#
|
73
|
+
# @param [optional LabelSet, Hash<String, String>] labels_or_label_set
|
74
|
+
# A {LabelSet} returned from {Meter#labels} or a Hash of Strings.
|
75
|
+
# @return [Handles::FloatCounter]
|
76
|
+
def handle(labels_or_label_set = {})
|
77
|
+
Handles::FloatCounter.new
|
78
|
+
end
|
79
|
+
|
80
|
+
# Return a measurement to be recorded via {Meter#record_batch}.
|
81
|
+
#
|
82
|
+
# @param [Float] value
|
83
|
+
# @return [Object, Measurement]
|
84
|
+
def measurement(value)
|
85
|
+
NOOP_MEASUREMENT
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# An integer counter instrument.
|
90
|
+
class IntegerCounter
|
91
|
+
def add(value, labels_or_label_set = {}); end
|
92
|
+
|
93
|
+
# Obtain a handle from the instrument and label set.
|
94
|
+
#
|
95
|
+
# @param [optional LabelSet, Hash<String, String>] labels_or_label_set
|
96
|
+
# A {LabelSet} returned from {Meter#labels} or a Hash of Strings.
|
97
|
+
# @return [Handles::IntegerCounter]
|
98
|
+
def handle(labels_or_label_set = {})
|
99
|
+
Handles::IntegerCounter.new
|
100
|
+
end
|
101
|
+
|
102
|
+
# Return a measurement to be recorded via {Meter#record_batch}.
|
103
|
+
#
|
104
|
+
# @param [Integer] value
|
105
|
+
# @return [Object, Measurement]
|
106
|
+
def measurement(value)
|
107
|
+
NOOP_MEASUREMENT
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# A float measure instrument.
|
112
|
+
class FloatMeasure
|
113
|
+
def record(value, labels_or_label_set = {}); end
|
114
|
+
|
115
|
+
# Obtain a handle from the instrument and label set.
|
116
|
+
#
|
117
|
+
# @param [optional LabelSet, Hash<String, String>] labels_or_label_set
|
118
|
+
# A {LabelSet} returned from {Meter#labels} or a Hash of Strings.
|
119
|
+
# @return [Handles::FloatMeasure]
|
120
|
+
def handle(labels_or_label_set = {})
|
121
|
+
Handles::FloatMeasure.new
|
122
|
+
end
|
123
|
+
|
124
|
+
# Return a measurement to be recorded via {Meter#record_batch}.
|
125
|
+
#
|
126
|
+
# @param [Float] value
|
127
|
+
# @return [Object, Measurement]
|
128
|
+
def measurement(value)
|
129
|
+
NOOP_MEASUREMENT
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# An integer measure instrument.
|
134
|
+
class IntegerMeasure
|
135
|
+
def record(value, labels_or_label_set = {}); end
|
136
|
+
|
137
|
+
# Obtain a handle from the instrument and label set.
|
138
|
+
#
|
139
|
+
# @param [optional LabelSet, Hash<String, String>] labels_or_label_set
|
140
|
+
# A {LabelSet} returned from {Meter#labels} or a Hash of Strings.
|
141
|
+
# @return [Handles::IntegerMeasure]
|
142
|
+
def handle(labels_or_label_set = {})
|
143
|
+
Handles::IntegerMeasure.new
|
144
|
+
end
|
145
|
+
|
146
|
+
# Return a measurement to be recorded via {Meter#record_batch}.
|
147
|
+
#
|
148
|
+
# @param [Integer] value
|
149
|
+
# @return [Object, Measurement]
|
150
|
+
def measurement(value)
|
151
|
+
NOOP_MEASUREMENT
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|