opencensus 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
  #