opencensus 0.1.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.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rubocop.yml +48 -0
  4. data/.travis.yml +16 -0
  5. data/AUTHORS +1 -0
  6. data/CODE_OF_CONDUCT.md +43 -0
  7. data/CONTRIBUTING.md +34 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE +201 -0
  10. data/README.md +180 -0
  11. data/Rakefile +20 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/docs/.gitignore +3 -0
  15. data/docs/404.html +24 -0
  16. data/docs/Gemfile +31 -0
  17. data/docs/_config.yml +39 -0
  18. data/docs/_layouts/default.html +65 -0
  19. data/docs/index.md +151 -0
  20. data/lib/opencensus.rb +21 -0
  21. data/lib/opencensus/common.rb +24 -0
  22. data/lib/opencensus/common/config.rb +521 -0
  23. data/lib/opencensus/config.rb +54 -0
  24. data/lib/opencensus/context.rb +72 -0
  25. data/lib/opencensus/stats.rb +26 -0
  26. data/lib/opencensus/tags.rb +25 -0
  27. data/lib/opencensus/trace.rb +181 -0
  28. data/lib/opencensus/trace/annotation.rb +60 -0
  29. data/lib/opencensus/trace/config.rb +119 -0
  30. data/lib/opencensus/trace/exporters.rb +26 -0
  31. data/lib/opencensus/trace/exporters/logger.rb +149 -0
  32. data/lib/opencensus/trace/formatters.rb +29 -0
  33. data/lib/opencensus/trace/formatters/binary.rb +66 -0
  34. data/lib/opencensus/trace/formatters/cloud_trace.rb +102 -0
  35. data/lib/opencensus/trace/formatters/trace_context.rb +124 -0
  36. data/lib/opencensus/trace/integrations.rb +24 -0
  37. data/lib/opencensus/trace/integrations/faraday_middleware.rb +176 -0
  38. data/lib/opencensus/trace/integrations/rack_middleware.rb +127 -0
  39. data/lib/opencensus/trace/integrations/rails.rb +121 -0
  40. data/lib/opencensus/trace/link.rb +90 -0
  41. data/lib/opencensus/trace/message_event.rb +80 -0
  42. data/lib/opencensus/trace/samplers.rb +50 -0
  43. data/lib/opencensus/trace/samplers/always_sample.rb +34 -0
  44. data/lib/opencensus/trace/samplers/max_qps.rb +55 -0
  45. data/lib/opencensus/trace/samplers/never_sample.rb +34 -0
  46. data/lib/opencensus/trace/samplers/probability.rb +69 -0
  47. data/lib/opencensus/trace/span.rb +196 -0
  48. data/lib/opencensus/trace/span_builder.rb +560 -0
  49. data/lib/opencensus/trace/span_context.rb +308 -0
  50. data/lib/opencensus/trace/status.rb +49 -0
  51. data/lib/opencensus/trace/time_event.rb +38 -0
  52. data/lib/opencensus/trace/trace_context_data.rb +22 -0
  53. data/lib/opencensus/trace/truncatable_string.rb +61 -0
  54. data/lib/opencensus/version.rb +18 -0
  55. data/opencensus.gemspec +32 -0
  56. metadata +210 -0
@@ -0,0 +1,308 @@
1
+ # Copyright 2017 OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module OpenCensus
16
+ module Trace
17
+ ##
18
+ # Span represents a span in a trace record. Spans are contained in
19
+ # a trace and arranged in a forest. That is, each span may be a root span
20
+ # or have a parent span, and may have zero or more children.
21
+ #
22
+ class SpanContext
23
+ ##
24
+ # Internal struct that holds trace-wide data.
25
+ #
26
+ # @private
27
+ #
28
+ TraceData = Struct.new :trace_id, :trace_options, :span_map
29
+
30
+ ##
31
+ # Maximum integer value for a `trace_id`
32
+ #
33
+ # @private
34
+ #
35
+ MAX_TRACE_ID = 0xffffffffffffffffffffffffffffffff
36
+
37
+ ##
38
+ # Maximum integer value for a `span_id`
39
+ #
40
+ # @private
41
+ #
42
+ MAX_SPAN_ID = 0xffffffffffffffff
43
+
44
+ class << self
45
+ ##
46
+ # Create a new root SpanContext object, given either a Trace-Context
47
+ # header value by itself, or an entire Rack environment. If a valid
48
+ # Trace-Context header can be obtained from either source, it is used
49
+ # to generate the SpanContext. Otherwise, a new root context with a
50
+ # unique `trace_id` and a root `span_id` of "" is used.
51
+ #
52
+ # @param [TraceContextData] trace_context The request's incoming trace
53
+ # context (optional)
54
+ #
55
+ # @return [SpanContext]
56
+ #
57
+ def create_root trace_context: nil
58
+ if trace_context
59
+ trace_data = TraceData.new \
60
+ trace_context.trace_id, trace_context.trace_options, {}
61
+ new trace_data, nil, trace_context.span_id
62
+ else
63
+ trace_id = rand 1..MAX_TRACE_ID
64
+ trace_id = trace_id.to_s(16).rjust(32, "0")
65
+ trace_data = TraceData.new trace_id, 0, {}
66
+ new trace_data, nil, ""
67
+ end
68
+ end
69
+ end
70
+
71
+ ##
72
+ # The parent of this context, or `nil` if this is a root context.
73
+ #
74
+ # @return [SpanContext, nil]
75
+ #
76
+ attr_reader :parent
77
+
78
+ ##
79
+ # Returns true if this is a root span context
80
+ #
81
+ # @return [boolean]
82
+ #
83
+ def root?
84
+ parent.nil?
85
+ end
86
+
87
+ ##
88
+ # The root context, which may be this context or one of its ancestors.
89
+ #
90
+ # @return [SpanContext]
91
+ #
92
+ def root
93
+ root = self
94
+ until (parent = root.parent).nil?
95
+ root = parent
96
+ end
97
+ root
98
+ end
99
+
100
+ ##
101
+ # Returns the trace context for this span.
102
+ #
103
+ # @return [TraceContextData]
104
+ #
105
+ def trace_context
106
+ TraceContextData.new trace_id, @span_id, trace_options
107
+ end
108
+
109
+ ##
110
+ # The trace ID, as a 32-character hex string.
111
+ #
112
+ # @return [String]
113
+ #
114
+ def trace_id
115
+ @trace_data.trace_id
116
+ end
117
+
118
+ ##
119
+ # The original trace options byte used to create this span context.
120
+ #
121
+ # @return [Integer]
122
+ #
123
+ def trace_options
124
+ @trace_data.trace_options
125
+ end
126
+
127
+ ##
128
+ # The span ID as a 16-character hex string, or the empty string if the
129
+ # context refers to the root of the trace.
130
+ #
131
+ # @return [String]
132
+ #
133
+ attr_reader :span_id
134
+
135
+ ##
136
+ # Whether the context (e.g. the parent span) has been sampled. This
137
+ # information may be used in sampling decisions for new spans.
138
+ #
139
+ # @return [boolean]
140
+ #
141
+ def sampled?
142
+ span = this_span
143
+ if span
144
+ span.sampled
145
+ else
146
+ trace_options & 0x01 != 0
147
+ end
148
+ end
149
+
150
+ ##
151
+ # Create a new span in this context.
152
+ # You must pass a name for the span. All other span attributes should
153
+ # be set using the SpanBuilder methods.
154
+ # The span will be started automatically with the current timestamp.
155
+ # However, you are responsible for finishing the span yourself.
156
+ #
157
+ # @param [String] name Name of the span
158
+ # @param [Sampler] sampler Span-scoped sampler. If not provided,
159
+ # defaults to the trace configuration's default sampler.
160
+ #
161
+ # @return [SpanBuilder] A SpanBuilder object that you can use to
162
+ # set span attributes and create children.
163
+ #
164
+ def start_span name, skip_frames: 0, sampler: nil
165
+ child_context = create_child
166
+ sampler ||= OpenCensus::Trace.config.default_sampler
167
+ sampled = sampler.call span_context: self
168
+ span = SpanBuilder.new child_context, sampled,
169
+ skip_frames: skip_frames + 1
170
+ span.name = name
171
+ span.start!
172
+ @trace_data.span_map[child_context.span_id] = span
173
+ end
174
+
175
+ ##
176
+ # Create a new span in this context.
177
+ # You must pass a name for the span. All other span attributes should
178
+ # be set using the SpanBuilder methods.
179
+ #
180
+ # The span will be started automatically with the current timestamp. The
181
+ # SpanBuilder will then be passed to the block you provide. The span will
182
+ # be finished automatically at the end of the block.
183
+ #
184
+ # @param [String] name Name of the span
185
+ # @param [Sampler] sampler Span-scoped sampler. If not provided,
186
+ # defaults to the trace configuration's default sampler.
187
+ #
188
+ def in_span name, skip_frames: 0, sampler: nil
189
+ span = start_span name, skip_frames: skip_frames + 1, sampler: sampler
190
+ begin
191
+ yield span
192
+ ensure
193
+ end_span span
194
+ end
195
+ end
196
+
197
+ ##
198
+ # Finish the given span, which must have been created by this span
199
+ # context.
200
+ #
201
+ # @param [SpanBuilder] span The span to finish.
202
+ #
203
+ def end_span span
204
+ unless span.context.parent == self
205
+ raise "The given span was not created by this context"
206
+ end
207
+ span.finish!
208
+ end
209
+
210
+ ##
211
+ # Returns the span that defines this context; that is, the span that is
212
+ # the parent of spans created by this context. Returns `nil` if this
213
+ # context is the root and doesn't correspond to an actual span, or if
214
+ # the corresponding span is remote.
215
+ #
216
+ # @return [SpanBuilder, nil] The span defining this context.
217
+ #
218
+ def this_span
219
+ get_span @span_id
220
+ end
221
+
222
+ ##
223
+ # Builds all finished spans under this context, and returns an array of
224
+ # built `Span` objects. Ignores any unfinished spans. The order of the
225
+ # generated spans is undefined.
226
+ #
227
+ # Does not build any ancestor spans. If you want the entire span tree
228
+ # built, call this method on the `#root` context.
229
+ #
230
+ # @return [Array<Span>] Built Span objects
231
+ #
232
+ def build_contained_spans
233
+ contained_span_builders.find_all(&:finished?).map(&:to_span)
234
+ end
235
+
236
+ ##
237
+ # Initialize a SpanContext object. This low-level constructor is used
238
+ # internally only. Generally, you should create a SpanContext using the
239
+ # `SpanContext.create_root` method.
240
+ #
241
+ # @private
242
+ #
243
+ def initialize trace_data, parent, span_id
244
+ @trace_data = trace_data
245
+ @parent = parent
246
+ @span_id = span_id
247
+ end
248
+
249
+ ##
250
+ # Returns true if this context equals or is an ancestor of the given
251
+ # context.
252
+ #
253
+ # @private
254
+ # @return [boolean]
255
+ #
256
+ def contains? context
257
+ until context.nil?
258
+ return true if context == self
259
+ context = context.parent
260
+ end
261
+ false
262
+ end
263
+
264
+ ##
265
+ # Returns all SpanBuilder objects created by this context or any
266
+ # descendant context. The order of the returned spans is undefined.
267
+ #
268
+ # @private
269
+ # @return [Array<SpanBuilder>]
270
+ #
271
+ def contained_span_builders
272
+ builders = @trace_data.span_map.values
273
+ if root?
274
+ builders
275
+ else
276
+ builders.find_all { |sb| contains? sb.context.parent }
277
+ end
278
+ end
279
+
280
+ private
281
+
282
+ ##
283
+ # Create a child of this SpanContext, with a random unique span ID.
284
+ #
285
+ # @return [SpanContext] The created child context.
286
+ #
287
+ def create_child
288
+ loop do
289
+ child_span_id = rand 1..MAX_SPAN_ID
290
+ child_span_id = child_span_id.to_s(16).rjust(16, "0")
291
+ unless @trace_data.span_map.key? child_span_id
292
+ return SpanContext.new @trace_data, self, child_span_id
293
+ end
294
+ end
295
+ end
296
+
297
+ ##
298
+ # Get the SpanBuilder given a Span ID.
299
+ #
300
+ # @param [Integer] span_id the ID of the span to get
301
+ # @return [SpanBuilder, nil] The SpanBuilder, or `nil` if ID not found
302
+ #
303
+ def get_span span_id
304
+ @trace_data.span_map[span_id]
305
+ end
306
+ end
307
+ end
308
+ end
@@ -0,0 +1,49 @@
1
+ # Copyright 2017 OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module OpenCensus
16
+ module Trace
17
+ ##
18
+ # The `Status` type defines a logical error model that is suitable for
19
+ # different programming environments, including REST APIs and RPC APIs.
20
+ # This Trace's fields are a subset of those of
21
+ # [google.rpc.Status](https://github.com/googleapis/googleapis/blob/master/google/rpc/status.Trace),
22
+ # which is used by [gRPC](https://github.com/grpc).
23
+ class Status
24
+ ##
25
+ # The status code.
26
+ #
27
+ # @return [Integer]
28
+ #
29
+ attr_reader :code
30
+
31
+ ##
32
+ # A developer-facing error message, which should be in English.
33
+ #
34
+ # @return [String]
35
+ #
36
+ attr_reader :message
37
+
38
+ ##
39
+ # Create an empty Status object.
40
+ #
41
+ # @private
42
+ #
43
+ def initialize code, message
44
+ @code = code
45
+ @message = message
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,38 @@
1
+ # Copyright 2017 OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module OpenCensus
16
+ module Trace
17
+ ##
18
+ # A time-stamped annotation or message event in the Span.
19
+ #
20
+ class TimeEvent
21
+ ##
22
+ # The time the event occurred.
23
+ #
24
+ # @return [Time]
25
+ #
26
+ attr_reader :time
27
+
28
+ ##
29
+ # Create a TimeEvent object
30
+ #
31
+ # @private
32
+ #
33
+ def initialize time: nil
34
+ @time = time || ::Time.now.utc
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ # Copyright 2018 OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module OpenCensus
16
+ module Trace
17
+ ##
18
+ # Struct that holds parsed trace context data.
19
+ #
20
+ TraceContextData = Struct.new :trace_id, :span_id, :trace_options
21
+ end
22
+ end
@@ -0,0 +1,61 @@
1
+ # Copyright 2017 OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module OpenCensus
16
+ module Trace
17
+ ##
18
+ # A string that might be shortened to a specified length.
19
+ #
20
+ class TruncatableString
21
+ ##
22
+ # The shortened string. For example, if the original string was 500 bytes
23
+ # long and the limit of the string was 128 bytes, then this value contains
24
+ # the first 128 bytes of the 500-byte string. Note that truncation always
25
+ # happens on a character boundary, to ensure that a truncated string is
26
+ # still valid UTF-8. Because it may contain multi-byte characters, the
27
+ # size of the truncated string may be less than the truncation limit.
28
+ #
29
+ # @return [String]
30
+ #
31
+ attr_reader :value
32
+
33
+ ##
34
+ # The number of bytes removed from the original string. If this value is
35
+ # 0, then the string was not shortened.
36
+ #
37
+ # @return [Integer]
38
+ #
39
+ attr_reader :truncated_byte_count
40
+
41
+ ##
42
+ # Create an empty TruncatableString object.
43
+ #
44
+ # @private
45
+ #
46
+ def initialize value, truncated_byte_count: 0
47
+ @value = value
48
+ @truncated_byte_count = truncated_byte_count
49
+ end
50
+
51
+ ##
52
+ # Override the default to_s implementation.
53
+ #
54
+ # @private
55
+ #
56
+ def to_s
57
+ @value
58
+ end
59
+ end
60
+ end
61
+ end