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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rubocop.yml +48 -0
- data/.travis.yml +16 -0
- data/AUTHORS +1 -0
- data/CODE_OF_CONDUCT.md +43 -0
- data/CONTRIBUTING.md +34 -0
- data/Gemfile +4 -0
- data/LICENSE +201 -0
- data/README.md +180 -0
- data/Rakefile +20 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/docs/.gitignore +3 -0
- data/docs/404.html +24 -0
- data/docs/Gemfile +31 -0
- data/docs/_config.yml +39 -0
- data/docs/_layouts/default.html +65 -0
- data/docs/index.md +151 -0
- data/lib/opencensus.rb +21 -0
- data/lib/opencensus/common.rb +24 -0
- data/lib/opencensus/common/config.rb +521 -0
- data/lib/opencensus/config.rb +54 -0
- data/lib/opencensus/context.rb +72 -0
- data/lib/opencensus/stats.rb +26 -0
- data/lib/opencensus/tags.rb +25 -0
- data/lib/opencensus/trace.rb +181 -0
- data/lib/opencensus/trace/annotation.rb +60 -0
- data/lib/opencensus/trace/config.rb +119 -0
- data/lib/opencensus/trace/exporters.rb +26 -0
- data/lib/opencensus/trace/exporters/logger.rb +149 -0
- data/lib/opencensus/trace/formatters.rb +29 -0
- data/lib/opencensus/trace/formatters/binary.rb +66 -0
- data/lib/opencensus/trace/formatters/cloud_trace.rb +102 -0
- data/lib/opencensus/trace/formatters/trace_context.rb +124 -0
- data/lib/opencensus/trace/integrations.rb +24 -0
- data/lib/opencensus/trace/integrations/faraday_middleware.rb +176 -0
- data/lib/opencensus/trace/integrations/rack_middleware.rb +127 -0
- data/lib/opencensus/trace/integrations/rails.rb +121 -0
- data/lib/opencensus/trace/link.rb +90 -0
- data/lib/opencensus/trace/message_event.rb +80 -0
- data/lib/opencensus/trace/samplers.rb +50 -0
- data/lib/opencensus/trace/samplers/always_sample.rb +34 -0
- data/lib/opencensus/trace/samplers/max_qps.rb +55 -0
- data/lib/opencensus/trace/samplers/never_sample.rb +34 -0
- data/lib/opencensus/trace/samplers/probability.rb +69 -0
- data/lib/opencensus/trace/span.rb +196 -0
- data/lib/opencensus/trace/span_builder.rb +560 -0
- data/lib/opencensus/trace/span_context.rb +308 -0
- data/lib/opencensus/trace/status.rb +49 -0
- data/lib/opencensus/trace/time_event.rb +38 -0
- data/lib/opencensus/trace/trace_context_data.rb +22 -0
- data/lib/opencensus/trace/truncatable_string.rb +61 -0
- data/lib/opencensus/version.rb +18 -0
- data/opencensus.gemspec +32 -0
- metadata +210 -0
@@ -0,0 +1,560 @@
|
|
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 single span within a request trace.
|
19
|
+
#
|
20
|
+
class SpanBuilder
|
21
|
+
## The type of a message event or link is unknown.
|
22
|
+
TYPE_UNSPECIFIED = :TYPE_UNSPECIFIED
|
23
|
+
|
24
|
+
## Indicates a sent message.
|
25
|
+
SENT = :SENT
|
26
|
+
|
27
|
+
## Indicates a received message.
|
28
|
+
RECEIVED = :RECEIVED
|
29
|
+
|
30
|
+
## The linked span is a child of the current span.
|
31
|
+
CHILD_LINKED_SPAN = :CHILD_LINKED_SPAN
|
32
|
+
|
33
|
+
## The linked span is a parent of the current span.
|
34
|
+
PARENT_LINKED_SPAN = :PARENT_LINKED_SPAN
|
35
|
+
|
36
|
+
##
|
37
|
+
# The context that can build children of this span.
|
38
|
+
#
|
39
|
+
# @return [SpanContext]
|
40
|
+
#
|
41
|
+
attr_reader :context
|
42
|
+
|
43
|
+
##
|
44
|
+
# The trace ID, as a 32-character hex string.
|
45
|
+
#
|
46
|
+
# @return [String]
|
47
|
+
#
|
48
|
+
def trace_id
|
49
|
+
context.trace_id
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# The span ID, as a 16-character hex string.
|
54
|
+
#
|
55
|
+
# @return [String]
|
56
|
+
#
|
57
|
+
def span_id
|
58
|
+
context.span_id
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# The span ID of the parent, as a 16-character hex string, or the empty
|
63
|
+
# string if this is a root span.
|
64
|
+
#
|
65
|
+
# @return [String]
|
66
|
+
#
|
67
|
+
def parent_span_id
|
68
|
+
context.parent.span_id
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Sampling decision for this span. Generally this field is set when the
|
73
|
+
# span is first created. However, you can also change it after the fact.
|
74
|
+
#
|
75
|
+
# @return [boolean]
|
76
|
+
#
|
77
|
+
attr_accessor :sampled
|
78
|
+
|
79
|
+
##
|
80
|
+
# A description of the span's operation.
|
81
|
+
#
|
82
|
+
# For example, the name can be a qualified method name or a file name and
|
83
|
+
# a line number where the operation is called. A best practice is to use
|
84
|
+
# the same display name at the same call point in an application.
|
85
|
+
# This makes it easier to correlate spans in different traces.
|
86
|
+
#
|
87
|
+
# This field is required.
|
88
|
+
#
|
89
|
+
# @return [String, TruncatableString]
|
90
|
+
#
|
91
|
+
attr_accessor :name
|
92
|
+
|
93
|
+
##
|
94
|
+
# The start time of the span. On the client side, this is the time kept
|
95
|
+
# by the local machine where the span execution starts. On the server
|
96
|
+
# side, this is the time when the server's application handler starts
|
97
|
+
# running.
|
98
|
+
#
|
99
|
+
# In Ruby, this is represented by a Time object in UTC, or `nil` if the
|
100
|
+
# starting timestamp has not yet been populated.
|
101
|
+
#
|
102
|
+
# @return [Time, nil]
|
103
|
+
#
|
104
|
+
attr_accessor :start_time
|
105
|
+
|
106
|
+
##
|
107
|
+
# The end time of the span. On the client side, this is the time kept by
|
108
|
+
# the local machine where the span execution ends. On the server side,
|
109
|
+
# this is the time when the server application handler stops running.
|
110
|
+
#
|
111
|
+
# In Ruby, this is represented by a Time object in UTC, or `nil` if the
|
112
|
+
# starting timestamp has not yet been populated.
|
113
|
+
#
|
114
|
+
# @return [Time, nil]
|
115
|
+
#
|
116
|
+
attr_accessor :end_time
|
117
|
+
|
118
|
+
##
|
119
|
+
# Whether this span is finished (i.e. has both a start and end time)
|
120
|
+
#
|
121
|
+
# @return [boolean]
|
122
|
+
#
|
123
|
+
def finished?
|
124
|
+
!start_time.nil? && !end_time.nil?
|
125
|
+
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# Start this span by setting the start time to the current time.
|
129
|
+
# Raises an exception if the start time is already set.
|
130
|
+
#
|
131
|
+
def start!
|
132
|
+
raise "Span already started" unless start_time.nil?
|
133
|
+
@start_time = Time.now.utc
|
134
|
+
self
|
135
|
+
end
|
136
|
+
|
137
|
+
##
|
138
|
+
# Finish this span by setting the end time to the current time.
|
139
|
+
# Raises an exception if the start time is not yet set, or the end time
|
140
|
+
# is already set.
|
141
|
+
#
|
142
|
+
def finish!
|
143
|
+
raise "Span not yet started" if start_time.nil?
|
144
|
+
raise "Span already finished" unless end_time.nil?
|
145
|
+
@end_time = Time.now.utc
|
146
|
+
self
|
147
|
+
end
|
148
|
+
|
149
|
+
##
|
150
|
+
# Add an attribute to this span.
|
151
|
+
#
|
152
|
+
# Attributes are key-value pairs representing properties of this span.
|
153
|
+
# You could, for example, add an attribute indicating the URL for the
|
154
|
+
# request being handled, the user-agent, the database query being run,
|
155
|
+
# the ID of the logged-in user, or any other relevant information.
|
156
|
+
#
|
157
|
+
# Keys must be strings.
|
158
|
+
# Values may be String, TruncatableString, Integer, or Boolean.
|
159
|
+
# The valid integer range is 64-bit signed `(-2^63..2^63-1)`.
|
160
|
+
#
|
161
|
+
# @param [String, Symbol] key
|
162
|
+
# @param [String, TruncatableString, Integer, boolean] value
|
163
|
+
#
|
164
|
+
def put_attribute key, value
|
165
|
+
@attributes[key.to_s] = value
|
166
|
+
self
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Add an event annotation with a timestamp.
|
171
|
+
#
|
172
|
+
# @param [String] description Description of the event
|
173
|
+
# @param [Hash] attributes Key-value pairs providing additional
|
174
|
+
# properties of the event. Keys must be strings, and values are
|
175
|
+
# restricted to the same types as attributes (see #put_attribute).
|
176
|
+
# @param [Time, nil] time Timestamp of the event. Optional, defaults to
|
177
|
+
# the current time.
|
178
|
+
#
|
179
|
+
def put_annotation description, attributes = {}, time: nil
|
180
|
+
time ||= Time.now.utc
|
181
|
+
annotation = AnnotationBuilder.new time, description, attributes
|
182
|
+
@annotations << annotation
|
183
|
+
self
|
184
|
+
end
|
185
|
+
|
186
|
+
##
|
187
|
+
# Add an event describing a message sent/received between spans.
|
188
|
+
#
|
189
|
+
# @param [Symbol] type The type of MessageEvent. Indicates whether the
|
190
|
+
# message was sent or received. Valid values are `SpanBuilder::SENT`
|
191
|
+
# `SpanBuilder::RECEIVED`, and `SpanBuilder::TYPE_UNSPECIFIED`.
|
192
|
+
# @param [Integer] id An identifier for the MessageEvent's message that
|
193
|
+
# can be used to match SENT and RECEIVED events. For example, this
|
194
|
+
# field could represent a sequence ID for a streaming RPC. It is
|
195
|
+
# recommended to be unique within a Span. The valid range is 64-bit
|
196
|
+
# unsigned `(0..2^64-1)`
|
197
|
+
# @param [Integer] uncompressed_size The number of uncompressed bytes
|
198
|
+
# sent or received.
|
199
|
+
# @param [Integer, nil] compressed_size The number of compressed bytes
|
200
|
+
# sent or received. Optional.
|
201
|
+
# @param [Time, nil] time Timestamp of the event. Optional, defaults to
|
202
|
+
# the current time.
|
203
|
+
#
|
204
|
+
def put_message_event type, id, uncompressed_size,
|
205
|
+
compressed_size: nil, time: nil
|
206
|
+
time ||= Time.now.utc
|
207
|
+
message_event =
|
208
|
+
MessageEventBuilder.new time, type, id, uncompressed_size,
|
209
|
+
compressed_size
|
210
|
+
@message_events << message_event
|
211
|
+
self
|
212
|
+
end
|
213
|
+
|
214
|
+
##
|
215
|
+
# Add a pointer from the current span to another span, which may be in
|
216
|
+
# the same trace or in a different trace. For example, this can be used
|
217
|
+
# in batching operations, where a single batch handler processes multiple
|
218
|
+
# requests from different traces or when the handler receives a request
|
219
|
+
# from a different project.
|
220
|
+
#
|
221
|
+
# @param [String] trace_id The unique identifier for a trace. A 16-byte
|
222
|
+
# array expressed as 32 hex digits.
|
223
|
+
# @param [String] span_id The unique identifier for a span within a trace.
|
224
|
+
# An 8-byte array expressed as 16 hex digits.
|
225
|
+
# @param [Symbol] type The relationship of the current span relative to
|
226
|
+
# the linked span. Valid values are `SpanBuilder::CHILD_LINKED_SPAN`,
|
227
|
+
# `SpanBuilder::PARENT_LINKED_SPAN`, and
|
228
|
+
# `SpanBuilder::TYPE_UNSPECIFIED`.
|
229
|
+
# @param [String] attributes Key-value pairs providing additional
|
230
|
+
# properties of the link. Keys must be strings, and values are
|
231
|
+
# restricted to the same types as attributes (see #put_attribute).
|
232
|
+
#
|
233
|
+
def put_link trace_id, span_id, type, attributes = {}
|
234
|
+
link = LinkBuilder.new trace_id, span_id, type, attributes
|
235
|
+
@links << link
|
236
|
+
self
|
237
|
+
end
|
238
|
+
|
239
|
+
##
|
240
|
+
# Set the optional final status for the span.
|
241
|
+
#
|
242
|
+
# @param [Integer] code Status code as a 32-bit signed integer
|
243
|
+
# @param [String] message A developer-facing error message, which should
|
244
|
+
# be in English.
|
245
|
+
def set_status code, message = ""
|
246
|
+
@status_code = code
|
247
|
+
@status_message = message
|
248
|
+
self
|
249
|
+
end
|
250
|
+
|
251
|
+
##
|
252
|
+
# Set the stack trace for this span.
|
253
|
+
# You may call this in one of three ways:
|
254
|
+
#
|
255
|
+
# * Pass in no argument to use the caller's stack trace.
|
256
|
+
# * Pass in an integer to use the caller's stack trace, but skip
|
257
|
+
# additional stack frames.
|
258
|
+
# * Pass in an explicit array of Thread::Backtrace::Location as
|
259
|
+
# returned from Kernel#caller_locations
|
260
|
+
#
|
261
|
+
# @param [Array<Thread::Backtrace::Location>, Integer] stack_trace
|
262
|
+
#
|
263
|
+
def update_stack_trace stack_trace = 0
|
264
|
+
@stack_trace =
|
265
|
+
case stack_trace
|
266
|
+
when Integer
|
267
|
+
caller_locations(stack_trace + 2)
|
268
|
+
when Array
|
269
|
+
stack_trace
|
270
|
+
else
|
271
|
+
raise ArgumentError, "Unknown stack trace type: #{stack_trace}"
|
272
|
+
end
|
273
|
+
self
|
274
|
+
end
|
275
|
+
|
276
|
+
# rubocop:disable Metrics/MethodLength
|
277
|
+
# rubocop:disable Metrics/AbcSize
|
278
|
+
|
279
|
+
##
|
280
|
+
# Return a read-only version of this span
|
281
|
+
#
|
282
|
+
# @return [Span]
|
283
|
+
#
|
284
|
+
def to_span max_attributes: nil,
|
285
|
+
max_stack_frames: nil,
|
286
|
+
max_annotations: nil,
|
287
|
+
max_message_events: nil,
|
288
|
+
max_links: nil,
|
289
|
+
max_string_length: nil,
|
290
|
+
same_process_as_parent_span: nil
|
291
|
+
|
292
|
+
raise "Span must have start_time" unless @start_time
|
293
|
+
raise "Span must have end_time" unless @end_time
|
294
|
+
|
295
|
+
builder = PieceBuilder.new max_attributes: max_attributes,
|
296
|
+
max_stack_frames: max_stack_frames,
|
297
|
+
max_annotations: max_annotations,
|
298
|
+
max_message_events: max_message_events,
|
299
|
+
max_links: max_links,
|
300
|
+
max_string_length: max_string_length
|
301
|
+
|
302
|
+
built_name = builder.truncatable_string name
|
303
|
+
built_attributes = builder.convert_attributes @attributes
|
304
|
+
dropped_attributes_count = @attributes.size - built_attributes.size
|
305
|
+
built_stack_trace = builder.truncate_stack_trace @stack_trace
|
306
|
+
dropped_frames_count = @stack_trace.size - built_stack_trace.size
|
307
|
+
built_annotations = builder.convert_annotations @annotations
|
308
|
+
dropped_annotations_count = @annotations.size - built_annotations.size
|
309
|
+
built_message_events = builder.convert_message_events @message_events
|
310
|
+
dropped_message_events_count =
|
311
|
+
@message_events.size - built_message_events.size
|
312
|
+
built_links = builder.convert_links @links
|
313
|
+
dropped_links_count = @links.size - built_links.size
|
314
|
+
built_status = builder.convert_status @status_code, @status_message
|
315
|
+
|
316
|
+
Span.new trace_id, span_id, built_name, @start_time, @end_time,
|
317
|
+
parent_span_id: parent_span_id,
|
318
|
+
attributes: built_attributes,
|
319
|
+
dropped_attributes_count: dropped_attributes_count,
|
320
|
+
stack_trace: built_stack_trace,
|
321
|
+
dropped_frames_count: dropped_frames_count,
|
322
|
+
time_events: built_annotations + built_message_events,
|
323
|
+
dropped_annotations_count: dropped_annotations_count,
|
324
|
+
dropped_message_events_count: dropped_message_events_count,
|
325
|
+
links: built_links,
|
326
|
+
dropped_links_count: dropped_links_count,
|
327
|
+
status: built_status,
|
328
|
+
same_process_as_parent_span: same_process_as_parent_span
|
329
|
+
end
|
330
|
+
|
331
|
+
# rubocop:enable Metrics/MethodLength
|
332
|
+
# rubocop:enable Metrics/AbcSize
|
333
|
+
|
334
|
+
##
|
335
|
+
# Initializer.
|
336
|
+
#
|
337
|
+
# @private
|
338
|
+
#
|
339
|
+
def initialize span_context, sampled, skip_frames: 0
|
340
|
+
@context = span_context
|
341
|
+
@sampled = sampled
|
342
|
+
@name = ""
|
343
|
+
@start_time = nil
|
344
|
+
@end_time = nil
|
345
|
+
@attributes = {}
|
346
|
+
@annotations = []
|
347
|
+
@message_events = []
|
348
|
+
@links = []
|
349
|
+
@status_code = nil
|
350
|
+
@status_message = nil
|
351
|
+
@stack_trace = caller_locations(skip_frames + 2)
|
352
|
+
end
|
353
|
+
|
354
|
+
##
|
355
|
+
# Internal structure for holding annotations.
|
356
|
+
#
|
357
|
+
# @private
|
358
|
+
#
|
359
|
+
AnnotationBuilder = Struct.new :time, :description, :attributes
|
360
|
+
|
361
|
+
##
|
362
|
+
# Internal structure for holding message events.
|
363
|
+
#
|
364
|
+
# @private
|
365
|
+
#
|
366
|
+
MessageEventBuilder = Struct.new :time, :type, :id, :uncompressed_size,
|
367
|
+
:compressed_size
|
368
|
+
##
|
369
|
+
# Internal structure for holding links.
|
370
|
+
#
|
371
|
+
# @private
|
372
|
+
#
|
373
|
+
LinkBuilder = Struct.new :trace_id, :span_id, :type, :attributes
|
374
|
+
|
375
|
+
##
|
376
|
+
# Internal class that builds pieces of a span, honoring limits.
|
377
|
+
#
|
378
|
+
# @private
|
379
|
+
#
|
380
|
+
class PieceBuilder
|
381
|
+
##
|
382
|
+
# Minimum value of int64
|
383
|
+
# @private
|
384
|
+
#
|
385
|
+
MIN_INT = -0x10000000000000000
|
386
|
+
|
387
|
+
##
|
388
|
+
# Maximum value of int64
|
389
|
+
# @private
|
390
|
+
#
|
391
|
+
MAX_INT = 0xffffffffffffffff
|
392
|
+
|
393
|
+
##
|
394
|
+
# Initializer for PieceBuilder
|
395
|
+
# @private
|
396
|
+
#
|
397
|
+
def initialize max_attributes: nil,
|
398
|
+
max_stack_frames: nil,
|
399
|
+
max_annotations: nil,
|
400
|
+
max_message_events: nil,
|
401
|
+
max_links: nil,
|
402
|
+
max_string_length: nil
|
403
|
+
config = OpenCensus::Trace.config
|
404
|
+
@max_attributes = max_attributes || config.default_max_attributes
|
405
|
+
@max_stack_frames =
|
406
|
+
max_stack_frames || config.default_max_stack_frames
|
407
|
+
@max_annotations = max_annotations || config.default_max_annotations
|
408
|
+
@max_message_events =
|
409
|
+
max_message_events || config.default_max_message_events
|
410
|
+
@max_links = max_links || config.default_max_links
|
411
|
+
@max_string_length =
|
412
|
+
max_string_length || config.default_max_string_length
|
413
|
+
end
|
414
|
+
|
415
|
+
##
|
416
|
+
# Build a canonical attributes hash, truncating if necessary
|
417
|
+
# @private
|
418
|
+
#
|
419
|
+
def convert_attributes attrs
|
420
|
+
result = {}
|
421
|
+
attrs.each do |k, v|
|
422
|
+
break if @max_attributes != 0 && result.size >= @max_attributes
|
423
|
+
result[k.to_s] =
|
424
|
+
case v
|
425
|
+
when Integer
|
426
|
+
if v >= MIN_INT && v <= MAX_INT
|
427
|
+
v
|
428
|
+
else
|
429
|
+
truncatable_string v.to_s
|
430
|
+
end
|
431
|
+
when true, false, TruncatableString
|
432
|
+
v
|
433
|
+
else
|
434
|
+
truncatable_string v.to_s
|
435
|
+
end
|
436
|
+
end
|
437
|
+
result
|
438
|
+
end
|
439
|
+
|
440
|
+
##
|
441
|
+
# Build a canonical stack trace, truncating if necessary
|
442
|
+
# @private
|
443
|
+
#
|
444
|
+
def truncate_stack_trace raw_trace
|
445
|
+
if @max_stack_frames.zero? || raw_trace.size <= @max_stack_frames
|
446
|
+
raw_trace
|
447
|
+
else
|
448
|
+
raw_trace[0, @max_stack_frames]
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
##
|
453
|
+
# Build a canonical annotations list, truncating if necessary
|
454
|
+
# @private
|
455
|
+
#
|
456
|
+
def convert_annotations raw_annotations
|
457
|
+
result = []
|
458
|
+
raw_annotations.each do |ann|
|
459
|
+
break if @max_annotations != 0 && result.size >= @max_annotations
|
460
|
+
attrs = convert_attributes ann.attributes
|
461
|
+
dropped_attributes_count = ann.attributes.size - attrs.size
|
462
|
+
result <<
|
463
|
+
OpenCensus::Trace::Annotation.new(
|
464
|
+
truncatable_string(ann.description),
|
465
|
+
attributes: attrs,
|
466
|
+
dropped_attributes_count: dropped_attributes_count,
|
467
|
+
time: ann.time
|
468
|
+
)
|
469
|
+
end
|
470
|
+
result
|
471
|
+
end
|
472
|
+
|
473
|
+
##
|
474
|
+
# Build a canonical message list, truncating if necessary
|
475
|
+
# @private
|
476
|
+
#
|
477
|
+
def convert_message_events raw_message_events
|
478
|
+
result = []
|
479
|
+
raw_message_events.each do |evt|
|
480
|
+
break if @max_message_events != 0 &&
|
481
|
+
result.size >= @max_message_events
|
482
|
+
result <<
|
483
|
+
OpenCensus::Trace::MessageEvent.new(
|
484
|
+
evt.type,
|
485
|
+
evt.id,
|
486
|
+
evt.uncompressed_size,
|
487
|
+
compressed_size: evt.compressed_size,
|
488
|
+
time: evt.time
|
489
|
+
)
|
490
|
+
end
|
491
|
+
result
|
492
|
+
end
|
493
|
+
|
494
|
+
##
|
495
|
+
# Build a canonical links list, truncating if necessary
|
496
|
+
# @private
|
497
|
+
#
|
498
|
+
def convert_links raw_links
|
499
|
+
result = []
|
500
|
+
raw_links.each do |lnk|
|
501
|
+
break if @max_links != 0 && result.size >= @max_links
|
502
|
+
attrs = convert_attributes lnk.attributes
|
503
|
+
dropped_attributes_count = lnk.attributes.size - attrs.size
|
504
|
+
result <<
|
505
|
+
OpenCensus::Trace::Link.new(
|
506
|
+
lnk.trace_id,
|
507
|
+
lnk.span_id,
|
508
|
+
type: lnk.type,
|
509
|
+
attributes: attrs,
|
510
|
+
dropped_attributes_count: dropped_attributes_count
|
511
|
+
)
|
512
|
+
end
|
513
|
+
result
|
514
|
+
end
|
515
|
+
|
516
|
+
##
|
517
|
+
# Build a canonical status object
|
518
|
+
# @private
|
519
|
+
#
|
520
|
+
def convert_status status_code, status_message
|
521
|
+
return nil unless status_code || status_message
|
522
|
+
Status.new status_code.to_i, status_message.to_s
|
523
|
+
end
|
524
|
+
|
525
|
+
##
|
526
|
+
# Build a truncatable string
|
527
|
+
# @private
|
528
|
+
#
|
529
|
+
def truncatable_string str
|
530
|
+
return str if str.is_a? TruncatableString
|
531
|
+
orig_str = str.encode Encoding::UTF_8,
|
532
|
+
invalid: :replace,
|
533
|
+
undef: :replace
|
534
|
+
if @max_string_length != 0 && @max_string_length < str.bytesize
|
535
|
+
str = truncate_str orig_str, @max_string_length
|
536
|
+
truncated_bytes = orig_str.bytesize - str.bytesize
|
537
|
+
TruncatableString.new str, truncated_byte_count: truncated_bytes
|
538
|
+
else
|
539
|
+
TruncatableString.new orig_str
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
private
|
544
|
+
|
545
|
+
def truncate_str str, target_bytes
|
546
|
+
tstr = str.dup
|
547
|
+
tstr.force_encoding Encoding::ASCII_8BIT
|
548
|
+
tstr.slice! target_bytes..-1
|
549
|
+
tstr.force_encoding Encoding::UTF_8
|
550
|
+
until tstr.valid_encoding?
|
551
|
+
tstr.force_encoding Encoding::ASCII_8BIT
|
552
|
+
tstr.slice!(-1..-1)
|
553
|
+
tstr.force_encoding Encoding::UTF_8
|
554
|
+
end
|
555
|
+
tstr
|
556
|
+
end
|
557
|
+
end
|
558
|
+
end
|
559
|
+
end
|
560
|
+
end
|