opencensus 0.3.1 → 0.4.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 (41) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +23 -0
  3. data/README.md +14 -3
  4. data/lib/opencensus.rb +12 -0
  5. data/lib/opencensus/common.rb +1 -0
  6. data/lib/opencensus/common/config.rb +1 -0
  7. data/lib/opencensus/config.rb +5 -3
  8. data/lib/opencensus/context.rb +1 -0
  9. data/lib/opencensus/stats.rb +1 -0
  10. data/lib/opencensus/tags.rb +1 -0
  11. data/lib/opencensus/trace.rb +31 -11
  12. data/lib/opencensus/trace/annotation.rb +1 -0
  13. data/lib/opencensus/trace/config.rb +13 -11
  14. data/lib/opencensus/trace/exporters.rb +1 -0
  15. data/lib/opencensus/trace/exporters/logger.rb +4 -3
  16. data/lib/opencensus/trace/exporters/multi.rb +1 -0
  17. data/lib/opencensus/trace/formatters.rb +3 -2
  18. data/lib/opencensus/trace/formatters/binary.rb +1 -0
  19. data/lib/opencensus/trace/formatters/cloud_trace.rb +1 -0
  20. data/lib/opencensus/trace/formatters/trace_context.rb +3 -2
  21. data/lib/opencensus/trace/integrations.rb +1 -0
  22. data/lib/opencensus/trace/integrations/faraday_middleware.rb +57 -21
  23. data/lib/opencensus/trace/integrations/rack_middleware.rb +11 -19
  24. data/lib/opencensus/trace/integrations/rails.rb +1 -0
  25. data/lib/opencensus/trace/link.rb +17 -7
  26. data/lib/opencensus/trace/message_event.rb +13 -3
  27. data/lib/opencensus/trace/samplers.rb +11 -7
  28. data/lib/opencensus/trace/samplers/always_sample.rb +1 -0
  29. data/lib/opencensus/trace/samplers/never_sample.rb +1 -0
  30. data/lib/opencensus/trace/samplers/probability.rb +13 -5
  31. data/lib/opencensus/trace/samplers/rate_limiting.rb +74 -0
  32. data/lib/opencensus/trace/span.rb +11 -5
  33. data/lib/opencensus/trace/span_builder.rb +84 -27
  34. data/lib/opencensus/trace/span_context.rb +76 -40
  35. data/lib/opencensus/trace/status.rb +227 -5
  36. data/lib/opencensus/trace/time_event.rb +1 -0
  37. data/lib/opencensus/trace/trace_context_data.rb +1 -0
  38. data/lib/opencensus/trace/truncatable_string.rb +1 -0
  39. data/lib/opencensus/version.rb +2 -1
  40. metadata +6 -6
  41. data/lib/opencensus/trace/samplers/max_qps.rb +0 -55
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+
15
16
  module OpenCensus
16
17
  module Trace
17
18
  ##
@@ -22,30 +23,27 @@ module OpenCensus
22
23
  class SpanContext
23
24
  ##
24
25
  # Internal struct that holds trace-wide data.
25
- #
26
26
  # @private
27
27
  #
28
- TraceData = Struct.new :trace_id, :trace_options, :span_map
28
+ TraceData = Struct.new :trace_id, :span_map
29
29
 
30
30
  ##
31
31
  # Maximum integer value for a `trace_id`
32
- #
33
32
  # @private
34
33
  #
35
34
  MAX_TRACE_ID = 0xffffffffffffffffffffffffffffffff
36
35
 
37
36
  ##
38
37
  # Maximum integer value for a `span_id`
39
- #
40
38
  # @private
41
39
  #
42
40
  MAX_SPAN_ID = 0xffffffffffffffff
43
41
 
44
42
  class << self
45
43
  ##
46
- # Create a new root SpanContext object, given either a Trace-Context
44
+ # Create a new root SpanContext object, given either a traceparent
47
45
  # 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
46
+ # traceparent header can be obtained from either source, it is used
49
47
  # to generate the SpanContext. Otherwise, a new root context with a
50
48
  # unique `trace_id` and a root `span_id` of "" is used.
51
49
  #
@@ -59,15 +57,14 @@ module OpenCensus
59
57
  #
60
58
  def create_root trace_context: nil, same_process_as_parent: nil
61
59
  if trace_context
62
- trace_data = TraceData.new \
63
- trace_context.trace_id, trace_context.trace_options, {}
60
+ trace_data = TraceData.new trace_context.trace_id, {}
64
61
  new trace_data, nil, trace_context.span_id,
65
- same_process_as_parent
62
+ trace_context.trace_options, same_process_as_parent
66
63
  else
67
64
  trace_id = rand 1..MAX_TRACE_ID
68
65
  trace_id = trace_id.to_s(16).rjust(32, "0")
69
- trace_data = TraceData.new trace_id, 0, {}
70
- new trace_data, nil, "", nil
66
+ trace_data = TraceData.new trace_id, {}
67
+ new trace_data, nil, "", 0, nil
71
68
  end
72
69
  end
73
70
  end
@@ -124,9 +121,7 @@ module OpenCensus
124
121
  #
125
122
  # @return [Integer]
126
123
  #
127
- def trace_options
128
- @trace_data.trace_options
129
- end
124
+ attr_reader :trace_options
130
125
 
131
126
  ##
132
127
  # The span ID as a 16-character hex string, or the empty string if the
@@ -145,41 +140,41 @@ module OpenCensus
145
140
  attr_reader :same_process_as_parent
146
141
 
147
142
  ##
148
- # Whether the context (e.g. the parent span) has been sampled. This
143
+ # Whether this context (e.g. the parent span) has been sampled. This
149
144
  # information may be used in sampling decisions for new spans.
150
145
  #
151
146
  # @return [boolean]
152
147
  #
153
148
  def sampled?
154
- span = this_span
155
- if span
156
- span.sampled
157
- else
158
- trace_options & 0x01 != 0
159
- end
149
+ trace_options & 0x01 != 0
160
150
  end
161
151
 
162
152
  ##
163
153
  # Create a new span in this context.
164
154
  # You must pass a name for the span. All other span attributes should
165
- # be set using the SpanBuilder methods.
155
+ # be set using {OpenCensus::Trace::SpanBuilder} methods.
166
156
  # The span will be started automatically with the current timestamp.
167
157
  # However, you are responsible for finishing the span yourself.
168
158
  #
169
- # @param [String] name Name of the span
170
- # @param [Symbol] kind Kind of span. Defaults to unspecified.
171
- # @param [Sampler] sampler Span-scoped sampler. If not provided,
172
- # defaults to the trace configuration's default sampler.
159
+ # @param [String] name Name of the span. Required.
160
+ # @param [Symbol] kind Kind of span. Optional. Defaults to unspecified.
161
+ # Other allowed values are {OpenCensus::Trace::SpanBuilder::SERVER}
162
+ # and {OpenCensus::Trace::SpanBuilder::CLIENT}.
163
+ # @param [Sampler,Boolean,nil] sampler Span-scoped sampler. Optional.
164
+ # If provided, the sampler may be a sampler object as defined in the
165
+ # {OpenCensus::Trace::Samplers} module docs, or the values `true` or
166
+ # `false` as shortcuts for {OpenCensus::Trace::Samplers::AlwaysSample}
167
+ # or {OpenCensus::Trace::Samplers::NeverSample}, respectively. If no
168
+ # span-scoped sampler is provided, the local parent span's sampling
169
+ # decision is used. If there is no local parent span, the configured
170
+ # default sampler is used to make a sampling decision.
173
171
  #
174
172
  # @return [SpanBuilder] A SpanBuilder object that you can use to
175
173
  # set span attributes and create children.
176
174
  #
177
175
  def start_span name, kind: nil, skip_frames: 0, sampler: nil
178
- child_context = create_child
179
- sampler ||= OpenCensus::Trace.config.default_sampler
180
- sampled = sampler.call span_context: self
181
- span = SpanBuilder.new child_context, sampled,
182
- skip_frames: skip_frames + 1
176
+ child_context = create_child sampler
177
+ span = SpanBuilder.new child_context, skip_frames: skip_frames + 1
183
178
  span.name = name
184
179
  span.kind = kind if kind
185
180
  span.start!
@@ -189,16 +184,24 @@ module OpenCensus
189
184
  ##
190
185
  # Create a new span in this context.
191
186
  # You must pass a name for the span. All other span attributes should
192
- # be set using the SpanBuilder methods.
187
+ # be set using {OpenCensus::Trace::SpanBuilder} methods.
193
188
  #
194
189
  # The span will be started automatically with the current timestamp. The
195
190
  # SpanBuilder will then be passed to the block you provide. The span will
196
191
  # be finished automatically at the end of the block.
197
192
  #
198
- # @param [String] name Name of the span
199
- # @param [Symbol] kind Kind of span. Defaults to unspecified.
200
- # @param [Sampler] sampler Span-scoped sampler. If not provided,
201
- # defaults to the trace configuration's default sampler.
193
+ # @param [String] name Name of the span. Required.
194
+ # @param [Symbol] kind Kind of span. Optional. Defaults to unspecified.
195
+ # Other allowed values are {OpenCensus::Trace::SpanBuilder::SERVER}
196
+ # and {OpenCensus::Trace::SpanBuilder::CLIENT}.
197
+ # @param [Sampler,Boolean,nil] sampler Span-scoped sampler. Optional.
198
+ # If provided, the sampler may be a sampler object as defined in the
199
+ # {OpenCensus::Trace::Samplers} module docs, or the values `true` or
200
+ # `false` as shortcuts for {OpenCensus::Trace::Samplers::AlwaysSample}
201
+ # or {OpenCensus::Trace::Samplers::NeverSample}, respectively. If no
202
+ # span-scoped sampler is provided, the local parent span's sampling
203
+ # decision is used. If there is no local parent span, the configured
204
+ # default sampler is used to make a sampling decision.
202
205
  #
203
206
  def in_span name, kind: nil, skip_frames: 0, sampler: nil
204
207
  span = start_span name, kind: kind, skip_frames: skip_frames + 1,
@@ -265,7 +268,7 @@ module OpenCensus
265
268
  max_links: nil,
266
269
  max_string_length: nil
267
270
  sampled_span_builders = contained_span_builders.find_all do |sb|
268
- sb.finished? && sb.sampled
271
+ sb.finished? && sb.sampled?
269
272
  end
270
273
  sampled_span_builders.map do |sb|
271
274
  sb.to_span max_attributes: max_attributes,
@@ -284,10 +287,12 @@ module OpenCensus
284
287
  #
285
288
  # @private
286
289
  #
287
- def initialize trace_data, parent, span_id, same_process_as_parent
290
+ def initialize trace_data, parent, span_id, trace_options,
291
+ same_process_as_parent
288
292
  @trace_data = trace_data
289
293
  @parent = parent
290
294
  @span_id = span_id
295
+ @trace_options = trace_options
291
296
  @same_process_as_parent = same_process_as_parent
292
297
  end
293
298
 
@@ -327,18 +332,49 @@ module OpenCensus
327
332
  ##
328
333
  # Create a child of this SpanContext, with a random unique span ID.
329
334
  #
335
+ # @param [Sampler,Boolean,nil] sampler Span-scoped sampler.
330
336
  # @return [SpanContext] The created child context.
331
337
  #
332
- def create_child
338
+ def create_child sampler
339
+ sampling_decision = make_sampling_decision sampler
340
+ child_trace_options = sampling_decision ? 1 : 0
333
341
  loop do
334
342
  child_span_id = rand 1..MAX_SPAN_ID
335
343
  child_span_id = child_span_id.to_s(16).rjust(16, "0")
336
344
  unless @trace_data.span_map.key? child_span_id
337
- return SpanContext.new @trace_data, self, child_span_id, true
345
+ return SpanContext.new @trace_data, self, child_span_id,
346
+ child_trace_options, true
338
347
  end
339
348
  end
340
349
  end
341
350
 
351
+ ##
352
+ # Make a sampling decision in the current context given a span sampler.
353
+ # Implements the logic specified at:
354
+ # https://github.com/census-instrumentation/opencensus-specs/blob/master/trace/Sampling.md
355
+ #
356
+ # @param [Sampler,Boolean,nil] sampler Span-scoped sampler.
357
+ # @return [Boolean]
358
+ #
359
+ def make_sampling_decision sampler
360
+ resolved_sampler =
361
+ case sampler
362
+ when true
363
+ OpenCensus::Trace::Samplers::AlwaysSample.new
364
+ when false
365
+ OpenCensus::Trace::Samplers::NeverSample.new
366
+ when nil
367
+ root? ? OpenCensus::Trace.config.default_sampler : nil
368
+ else
369
+ sampler
370
+ end
371
+ if resolved_sampler
372
+ resolved_sampler.call(span_context: self)
373
+ else
374
+ sampled?
375
+ end
376
+ end
377
+
342
378
  ##
343
379
  # Get the SpanBuilder given a Span ID.
344
380
  #
@@ -12,17 +12,239 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+
15
16
  module OpenCensus
16
17
  module Trace
17
18
  ##
18
19
  # The `Status` type defines a logical error model that is suitable for
19
20
  # 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).
21
+ #
23
22
  class Status
24
23
  ##
25
- # The status code.
24
+ # Not an error; returned on success
25
+ #
26
+ # HTTP Mapping: 200 OK
27
+ #
28
+ # @return [Integer]
29
+ #
30
+ OK = 0
31
+
32
+ ##
33
+ # The operation was cancelled, typically by the caller.
34
+ #
35
+ # HTTP Mapping: 499 Client Closed Request
36
+ #
37
+ # @return [Integer]
38
+ #
39
+ CANCELLED = 1
40
+
41
+ ##
42
+ # Unknown error. For example, this error may be returned when
43
+ # a `Status` value received from another address space belongs to
44
+ # an error space that is not known in this address space. Also
45
+ # errors raised by APIs that do not return enough error information
46
+ # may be converted to this error.
47
+ #
48
+ # HTTP Mapping: 500 Internal Server Error
49
+ #
50
+ # @return [Integer]
51
+ #
52
+ UNKNOWN = 2
53
+
54
+ ##
55
+ # The client specified an invalid argument. Note that this differs
56
+ # from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments
57
+ # that are problematic regardless of the state of the system
58
+ # (e.g., a malformed file name).
59
+ #
60
+ # HTTP Mapping: 400 Bad Request
61
+ #
62
+ # @return [Integer]
63
+ #
64
+ INVALID_ARGUMENT = 3
65
+
66
+ ##
67
+ # The deadline expired before the operation could complete. For operations
68
+ # that change the state of the system, this error may be returned
69
+ # even if the operation has completed successfully. For example, a
70
+ # successful response from a server could have been delayed long
71
+ # enough for the deadline to expire.
72
+ #
73
+ # HTTP Mapping: 504 Gateway Timeout
74
+ #
75
+ # @return [Integer]
76
+ #
77
+ DEADLINE_EXCEEDED = 4
78
+
79
+ ##
80
+ # Some requested entity (e.g., file or directory) was not found.
81
+ #
82
+ # Note to server developers: if a request is denied for an entire class
83
+ # of users, such as gradual feature rollout or undocumented whitelist,
84
+ # `NOT_FOUND` may be used. If a request is denied for some users within
85
+ # a class of users, such as user-based access control, `PERMISSION_DENIED`
86
+ # must be used.
87
+ #
88
+ # HTTP Mapping: 404 Not Found
89
+ #
90
+ # @return [Integer]
91
+ #
92
+ NOT_FOUND = 5
93
+
94
+ ##
95
+ # The entity that a client attempted to create (e.g., file or directory)
96
+ # already exists.
97
+ #
98
+ # HTTP Mapping: 409 Conflict
99
+ #
100
+ # @return [Integer]
101
+ #
102
+ ALREADY_EXISTS = 6
103
+
104
+ ##
105
+ # The caller does not have permission to execute the specified
106
+ # operation. `PERMISSION_DENIED` must not be used for rejections
107
+ # caused by exhausting some resource (use `RESOURCE_EXHAUSTED`
108
+ # instead for those errors). `PERMISSION_DENIED` must not be
109
+ # used if the caller can not be identified (use `UNAUTHENTICATED`
110
+ # instead for those errors). This error code does not imply the
111
+ # request is valid or the requested entity exists or satisfies
112
+ # other pre-conditions.
113
+ #
114
+ # HTTP Mapping: 403 Forbidden
115
+ #
116
+ # @return [Integer]
117
+ #
118
+ PERMISSION_DENIED = 7
119
+
120
+ ##
121
+ # Some resource has been exhausted, perhaps a per-user quota, or
122
+ # perhaps the entire file system is out of space.
123
+ #
124
+ # HTTP Mapping: 429 Too Many Requests
125
+ #
126
+ # @return [Integer]
127
+ #
128
+ RESOURCE_EXHAUSTED = 8
129
+
130
+ ##
131
+ # The operation was rejected because the system is not in a state
132
+ # required for the operation's execution. For example, the directory
133
+ # to be deleted is non-empty, an rmdir operation is applied to
134
+ # a non-directory, etc.
135
+ #
136
+ # Service implementors can use the following guidelines to decide
137
+ # between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`:
138
+ # a. Use `UNAVAILABLE` if the client can retry just the failing call.
139
+ # b. Use `ABORTED` if the client should retry at a higher level
140
+ # (e.g., when a client-specified test-and-set fails, indicating the
141
+ # client should restart a read-modify-write sequence).
142
+ # c. Use `FAILED_PRECONDITION` if the client should not retry until
143
+ # the system state has been explicitly fixed. E.g., if an "rmdir"
144
+ # fails because the directory is non-empty, `FAILED_PRECONDITION`
145
+ # should be returned since the client should not retry unless
146
+ # the files are deleted from the directory.
147
+ #
148
+ # HTTP Mapping: 400 Bad Request
149
+ #
150
+ # @return [Integer]
151
+ #
152
+ FAILED_PRECONDITION = 9
153
+
154
+ ##
155
+ # The operation was aborted, typically due to a concurrency issue such as
156
+ # a sequencer check failure or transaction abort.
157
+ #
158
+ # See the guidelines above for deciding between `FAILED_PRECONDITION`,
159
+ # `ABORTED`, and `UNAVAILABLE`.
160
+ #
161
+ # HTTP Mapping: 409 Conflict
162
+ #
163
+ # @return [Integer]
164
+ #
165
+ ABORTED = 10
166
+
167
+ ##
168
+ # The operation was attempted past the valid range. E.g., seeking or
169
+ # reading past end-of-file.
170
+ #
171
+ # Unlike `INVALID_ARGUMENT`, this error indicates a problem that may
172
+ # be fixed if the system state changes. For example, a 32-bit file
173
+ # system will generate `INVALID_ARGUMENT` if asked to read at an
174
+ # offset that is not in the range [0,2^32-1], but it will generate
175
+ # `OUT_OF_RANGE` if asked to read from an offset past the current
176
+ # file size.
177
+ #
178
+ # There is a fair bit of overlap between `FAILED_PRECONDITION` and
179
+ # `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific
180
+ # error) when it applies so that callers who are iterating through
181
+ # a space can easily look for an `OUT_OF_RANGE` error to detect when
182
+ # they are done.
183
+ #
184
+ # HTTP Mapping: 400 Bad Request
185
+ #
186
+ # @return [Integer]
187
+ #
188
+ OUT_OF_RANGE = 11
189
+
190
+ ##
191
+ # The operation is not implemented or is not supported/enabled in this
192
+ # service.
193
+ #
194
+ # HTTP Mapping: 501 Not Implemented
195
+ #
196
+ # @return [Integer]
197
+ #
198
+ UNIMPLEMENTED = 12
199
+
200
+ ##
201
+ # Internal errors. This means that some invariants expected by the
202
+ # underlying system have been broken. This error code is reserved
203
+ # for serious errors.
204
+ #
205
+ # HTTP Mapping: 500 Internal Server Error
206
+ #
207
+ # @return [Integer]
208
+ #
209
+ INTERNAL = 13
210
+
211
+ ##
212
+ # The service is currently unavailable. This is most likely a
213
+ # transient condition, which can be corrected by retrying with
214
+ # a backoff.
215
+ #
216
+ # See the guidelines above for deciding between `FAILED_PRECONDITION`,
217
+ # `ABORTED`, and `UNAVAILABLE`.
218
+ #
219
+ # HTTP Mapping: 503 Service Unavailable
220
+ #
221
+ # @return [Integer]
222
+ #
223
+ UNAVAILABLE = 14
224
+
225
+ ##
226
+ # Unrecoverable data loss or corruption.
227
+ #
228
+ # HTTP Mapping: 500 Internal Server Error
229
+ #
230
+ # @return [Integer]
231
+ #
232
+ DATA_LOSS = 15
233
+
234
+ ##
235
+ # The request does not have valid authentication credentials for the
236
+ # operation.
237
+ #
238
+ # HTTP Mapping: 401 Unauthorized
239
+ #
240
+ # @return [Integer]
241
+ #
242
+ UNAUTHENTICATED = 16
243
+
244
+ ##
245
+ # The status code. Allowed values are the Google RPC status codes
246
+ # defined at https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
247
+ # and also provided as constants in this class.
26
248
  #
27
249
  # @return [Integer]
28
250
  #
@@ -36,7 +258,7 @@ module OpenCensus
36
258
  attr_reader :message
37
259
 
38
260
  ##
39
- # Create an empty Status object.
261
+ # Create a Status object.
40
262
  #
41
263
  # @private
42
264
  #