opencensus-stackdriver 0.1.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rubocop.yml +51 -0
- data/.travis.yml +10 -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 +119 -0
- data/Rakefile +21 -0
- data/lib/opencensus-stackdriver.rb +15 -0
- data/lib/opencensus/stackdriver.rb +25 -0
- data/lib/opencensus/stackdriver/version.rb +20 -0
- data/lib/opencensus/trace/exporters/stackdriver.rb +259 -0
- data/lib/opencensus/trace/exporters/stackdriver/converter.rb +356 -0
- data/opencensus-stackdriver.gemspec +38 -0
- metadata +228 -0
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
require "yard"
|
4
|
+
|
5
|
+
require "rubocop/rake_task"
|
6
|
+
RuboCop::RakeTask.new
|
7
|
+
|
8
|
+
Rake::TestTask.new :test do |t|
|
9
|
+
t.libs << "test"
|
10
|
+
t.libs << "lib"
|
11
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
12
|
+
t.warning = false
|
13
|
+
end
|
14
|
+
|
15
|
+
YARD::Rake::YardocTask.new do |t|
|
16
|
+
t.files = ['lib/**/*.rb'] # optional
|
17
|
+
t.options = ['--output-dir', 'docs/api'] # optional
|
18
|
+
t.stats_options = ['--list-undoc'] # optional
|
19
|
+
end
|
20
|
+
|
21
|
+
task :default => [:test, :rubocop, :yard]
|
@@ -0,0 +1,15 @@
|
|
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
|
+
require "opencensus/stackdriver"
|
@@ -0,0 +1,25 @@
|
|
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
|
+
require "opencensus"
|
16
|
+
|
17
|
+
module OpenCensus
|
18
|
+
## Information about the Stackdriver exporter plugin
|
19
|
+
module Stackdriver
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
require "opencensus/stackdriver/version"
|
24
|
+
require "opencensus/trace/exporters/stackdriver"
|
25
|
+
require "opencensus/trace/exporters/stackdriver/converter"
|
@@ -0,0 +1,20 @@
|
|
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 Stackdriver
|
17
|
+
## Current OpenCensus Stackdriver plugin version
|
18
|
+
VERSION = "0.1.0.pre1".freeze
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,259 @@
|
|
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
|
+
gem "google-cloud-trace"
|
16
|
+
gem "concurrent-ruby"
|
17
|
+
|
18
|
+
require "concurrent"
|
19
|
+
require "google/cloud/trace"
|
20
|
+
require "google/cloud/trace/v2"
|
21
|
+
|
22
|
+
module OpenCensus
|
23
|
+
module Trace
|
24
|
+
module Exporters
|
25
|
+
##
|
26
|
+
# The Stackdriver exporter for OpenCensus Trace exports captured spans
|
27
|
+
# to a Google Stackdriver project. It calls the Stackdriver Trace API in
|
28
|
+
# a background thread pool.
|
29
|
+
#
|
30
|
+
class Stackdriver
|
31
|
+
##
|
32
|
+
# Create a Stackdriver exporter.
|
33
|
+
#
|
34
|
+
# @param [String] project_id The project identifier for the Stackdriver
|
35
|
+
# Trace service you are connecting to. If you are running on Google
|
36
|
+
# Cloud hosting (e.g. Compute Engine, Kubernetes Engine, or App
|
37
|
+
# Engine), this parameter is optional and will default to the
|
38
|
+
# hosting project. Otherwise, it is required.
|
39
|
+
# @param [String, Hash, Google::Auth::Credentials] credentials The
|
40
|
+
# Stackdriver API credentials, which can be a path to a keyfile as
|
41
|
+
# a String, the contents of a keyfile as a Hash, or a
|
42
|
+
# Google::Auth::Credentials object. If you are running on Google
|
43
|
+
# Cloud hosting (e.g. Compute Engine, Kubernetes Engine, or App
|
44
|
+
# Engine), this parameter is optional and will default to the
|
45
|
+
# credentials provided by the hosting project. Otherwise, it is
|
46
|
+
# required.
|
47
|
+
# @param [String, Array<String>] scope The OAuth 2.0 scopes controlling
|
48
|
+
# the set of resources and operations the API client can access.
|
49
|
+
# Optional. Most applications can leave this set to the default.
|
50
|
+
# @param [Integer] timeout The default timeout for API requests, in
|
51
|
+
# seconds. Optional.
|
52
|
+
# @param [Hash] client_config An optional set of additional
|
53
|
+
# configuration values for the API connection.
|
54
|
+
# @param [Integer] max_queue The maximum number of API requests that
|
55
|
+
# can be queued for background operation. If the queue exceeds this
|
56
|
+
# value, additional requests will be run in the calling thread
|
57
|
+
# rather than in the background. Set to 0 to allow the queue to
|
58
|
+
# grow indefinitely. Default is 1000.
|
59
|
+
# @param [Integer] max_threads The maximum number of threads that can
|
60
|
+
# be spun up to handle API requests. Default is 1. If set to 0,
|
61
|
+
# backgrounding will be disabled and all requests will run in the
|
62
|
+
# calling thread.
|
63
|
+
# @param [Integer] auto_terminate_time The time in seconds allotted to
|
64
|
+
# complete any pending background requests when Ruby is exiting.
|
65
|
+
#
|
66
|
+
def initialize \
|
67
|
+
project_id: nil,
|
68
|
+
credentials: nil,
|
69
|
+
scope: nil,
|
70
|
+
timeout: nil,
|
71
|
+
client_config: nil,
|
72
|
+
max_queue: 1000,
|
73
|
+
max_threads: 1,
|
74
|
+
auto_terminate_time: 10,
|
75
|
+
mock_client: nil
|
76
|
+
@project_id = final_project_id project_id
|
77
|
+
|
78
|
+
@executor = create_executor max_threads, max_queue
|
79
|
+
if auto_terminate_time
|
80
|
+
terminate_at_exit! @executor, auto_terminate_time
|
81
|
+
end
|
82
|
+
|
83
|
+
if mock_client
|
84
|
+
@client_promise =
|
85
|
+
Concurrent::Promise.fulfill mock_client, executor: @executor
|
86
|
+
else
|
87
|
+
credentials = final_credentials credentials, scope
|
88
|
+
scope ||= Google::Cloud.configure.trace.scope
|
89
|
+
timeout ||= Google::Cloud.configure.trace.timeout
|
90
|
+
client_config ||= Google::Cloud.configure.trace.client_config
|
91
|
+
@client_promise = create_client_promise \
|
92
|
+
@executor, credentials, scope, client_config, timeout
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# The project ID
|
98
|
+
# @return [String]
|
99
|
+
#
|
100
|
+
attr_reader :project_id
|
101
|
+
|
102
|
+
##
|
103
|
+
# Export spans to Stackdriver asynchronously.
|
104
|
+
#
|
105
|
+
# @param [Array<OpenCensus::Trace::Span>] spans The captured spans to
|
106
|
+
# export to Stackdriver
|
107
|
+
#
|
108
|
+
def export spans
|
109
|
+
raise "Exporter is no longer running" unless @executor.running?
|
110
|
+
|
111
|
+
@client_promise.execute
|
112
|
+
export_promise = @client_promise.then do |client|
|
113
|
+
export_as_batch(client, spans)
|
114
|
+
end
|
115
|
+
export_promise.on_error do |reason|
|
116
|
+
warn "Unable to export to Stackdriver because: #{reason}"
|
117
|
+
end
|
118
|
+
|
119
|
+
true
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Returns true if this exporter is running and will accept further
|
124
|
+
# export requests. Returns false once the exporter begins shutting down.
|
125
|
+
#
|
126
|
+
# @return [boolean]
|
127
|
+
#
|
128
|
+
def running?
|
129
|
+
@executor.running?
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# Returns true if this exporter has finished shutting down and all
|
134
|
+
# pending spans have been sent.
|
135
|
+
#
|
136
|
+
# @return [boolean]
|
137
|
+
#
|
138
|
+
def shutdown?
|
139
|
+
@executor.shutdown?
|
140
|
+
end
|
141
|
+
|
142
|
+
##
|
143
|
+
# Returns true if this exporter has begun shutting down and is no
|
144
|
+
# longer accepting export requests, but is still running queued
|
145
|
+
# requests in the background.
|
146
|
+
#
|
147
|
+
# @return [boolean]
|
148
|
+
#
|
149
|
+
def shuttingdown?
|
150
|
+
@executor.shuttingdown?
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# Begin shutting down the exporter gracefully. After this operation is
|
155
|
+
# performed, the exporter will no longer accept export requests, but
|
156
|
+
# will finish any pending requests in the background.
|
157
|
+
#
|
158
|
+
def shutdown
|
159
|
+
@executor.shutdown
|
160
|
+
self
|
161
|
+
end
|
162
|
+
|
163
|
+
##
|
164
|
+
# Begin shutting down the exporter forcefully. After this operation is
|
165
|
+
# performed, the exporter will no longer accept export requests, and
|
166
|
+
# will finish any currently running export requests, but will cancel
|
167
|
+
# all requests that are still pending in the queue.
|
168
|
+
#
|
169
|
+
def kill
|
170
|
+
@executor.kill
|
171
|
+
self
|
172
|
+
end
|
173
|
+
|
174
|
+
##
|
175
|
+
# Wait for the exporter to finish shutting down.
|
176
|
+
#
|
177
|
+
# @param [Integer, nil] timeout A timeout in seconds, or nil for no
|
178
|
+
# timeout.
|
179
|
+
# @return [boolean] true if the exporter is shut down, or false if the
|
180
|
+
# wait timed out.
|
181
|
+
#
|
182
|
+
def wait_for_termination timeout = nil
|
183
|
+
@executor.wait_for_termination timeout
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
|
188
|
+
# Create the executor
|
189
|
+
def create_executor max_threads, max_queue
|
190
|
+
if max_threads >= 1
|
191
|
+
Concurrent::ThreadPoolExecutor.new \
|
192
|
+
min_length: 1, max_length: max_threads,
|
193
|
+
max_queue: max_queue, fallback_policy: :caller_runs,
|
194
|
+
auto_terminate: false
|
195
|
+
else
|
196
|
+
Concurrent::ImmediateExecutor.new
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Create the client promise.
|
201
|
+
# We create the client lazily so grpc doesn't get initialized until
|
202
|
+
# we actually need it. This is important because if it is intialized
|
203
|
+
# too early, before a fork, it can go into a bad state.
|
204
|
+
def create_client_promise executor, credentials, scopes, client_config,
|
205
|
+
timeout
|
206
|
+
Concurrent::Promise.new executor: executor do
|
207
|
+
Google::Cloud::Trace::V2.new(
|
208
|
+
credentials: credentials,
|
209
|
+
scopes: scopes,
|
210
|
+
client_config: client_config,
|
211
|
+
timeout: timeout,
|
212
|
+
lib_name: "opencensus",
|
213
|
+
lib_version: OpenCensus::Stackdriver::VERSION
|
214
|
+
)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Set up an at_exit hook that shuts the exporter down.
|
219
|
+
def terminate_at_exit! executor, timeout
|
220
|
+
at_exit do
|
221
|
+
executor.shutdown
|
222
|
+
unless executor.wait_for_termination timeout
|
223
|
+
executor.kill
|
224
|
+
executor.wait_for_termination timeout
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# Fall back to default project ID
|
230
|
+
def final_project_id project_id
|
231
|
+
project_id ||
|
232
|
+
Google::Cloud.configure.trace.project_id ||
|
233
|
+
Google::Cloud.configure.project_id ||
|
234
|
+
Google::Cloud.env.project_id
|
235
|
+
end
|
236
|
+
|
237
|
+
# Fall back to default credentials, and wrap in a creds object
|
238
|
+
def final_credentials credentials, scope
|
239
|
+
credentials ||=
|
240
|
+
Google::Cloud.configure.trace.credentials ||
|
241
|
+
Google::Cloud.configure.credentials ||
|
242
|
+
Google::Cloud::Trace::Credentials.default(scope: scope)
|
243
|
+
unless credentials.is_a? Google::Auth::Credentials
|
244
|
+
credentials =
|
245
|
+
Google::Cloud::Trace::Credentials.new credentials, scope: scope
|
246
|
+
end
|
247
|
+
credentials
|
248
|
+
end
|
249
|
+
|
250
|
+
# Export a list of spans in a single batch write, in the current thread
|
251
|
+
def export_as_batch client, spans
|
252
|
+
converter = Converter.new project_id
|
253
|
+
span_protos = Array(spans).map { |span| converter.convert_span span }
|
254
|
+
client.batch_write_spans "projects/#{project_id}", span_protos
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
@@ -0,0 +1,356 @@
|
|
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
|
+
require "google/devtools/cloudtrace/v2/trace_pb"
|
16
|
+
require "google/protobuf/well_known_types"
|
17
|
+
|
18
|
+
module OpenCensus
|
19
|
+
module Trace
|
20
|
+
module Exporters
|
21
|
+
class Stackdriver
|
22
|
+
##
|
23
|
+
# An object that converts OpenCensus span data objects to Stackdriver
|
24
|
+
# Trace V2 protos.
|
25
|
+
#
|
26
|
+
# You should use one converter instance to convert the spans for a
|
27
|
+
# single export request, because the converter will keep track of and
|
28
|
+
# omit duplicate stack traces. Use a new converter instance for the
|
29
|
+
# next request.
|
30
|
+
#
|
31
|
+
# @private
|
32
|
+
#
|
33
|
+
class Converter
|
34
|
+
##
|
35
|
+
# @private
|
36
|
+
# Alias for the V2 Cloudtrace protos namespace
|
37
|
+
#
|
38
|
+
TraceProtos = Google::Devtools::Cloudtrace::V2
|
39
|
+
|
40
|
+
##
|
41
|
+
# Create a converter
|
42
|
+
#
|
43
|
+
# @param [String] project_id Google project ID
|
44
|
+
#
|
45
|
+
def initialize project_id
|
46
|
+
@project_id = project_id
|
47
|
+
@stack_trace_hash_ids = {}
|
48
|
+
end
|
49
|
+
|
50
|
+
# rubocop:disable Metrics/AbcSize
|
51
|
+
|
52
|
+
##
|
53
|
+
# Convert a span object.
|
54
|
+
#
|
55
|
+
# @param [OpenCensus::Trace::Span] obj OpenCensus span object
|
56
|
+
# @return [Google::Devtools::Cloudtrace::V2::Span] The generated
|
57
|
+
# proto
|
58
|
+
#
|
59
|
+
def convert_span obj
|
60
|
+
TraceProtos::Span.new \
|
61
|
+
name: make_resource_name(@project_id, obj.trace_id, obj.span_id),
|
62
|
+
span_id: obj.span_id,
|
63
|
+
parent_span_id: obj.parent_span_id || "",
|
64
|
+
display_name: convert_truncatable_string(obj.name),
|
65
|
+
start_time: convert_time(obj.start_time),
|
66
|
+
end_time: convert_time(obj.end_time),
|
67
|
+
attributes:
|
68
|
+
convert_attributes(obj.attributes,
|
69
|
+
obj.dropped_attributes_count),
|
70
|
+
stack_trace:
|
71
|
+
convert_stack_trace(obj.stack_trace, obj.dropped_frames_count,
|
72
|
+
obj.stack_trace_hash_id),
|
73
|
+
time_events:
|
74
|
+
convert_time_events(obj.time_events,
|
75
|
+
obj.dropped_annotations_count,
|
76
|
+
obj.dropped_message_events_count),
|
77
|
+
links: convert_links(obj.links, obj.dropped_links_count),
|
78
|
+
status: convert_optional_status(obj.status),
|
79
|
+
same_process_as_parent_span:
|
80
|
+
convert_optional_bool(obj.same_process_as_parent_span),
|
81
|
+
child_span_count: convert_optional_int32(obj.child_span_count)
|
82
|
+
end
|
83
|
+
|
84
|
+
# rubocop:enable Metrics/AbcSize
|
85
|
+
|
86
|
+
##
|
87
|
+
# Make a span resource name.
|
88
|
+
#
|
89
|
+
# @param [String] project_id The project ID
|
90
|
+
# @param [String] trace_id The project ID
|
91
|
+
# @param [String] span_id The project ID
|
92
|
+
# @return [String] The resource na,e
|
93
|
+
#
|
94
|
+
def make_resource_name project_id, trace_id, span_id
|
95
|
+
"projects/#{project_id}/traces/#{trace_id}/spans/#{span_id}"
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# Create a truncatable string proto.
|
100
|
+
#
|
101
|
+
# @param [String] str The string
|
102
|
+
# @param [Integer] truncated_byte_count The number of bytes omitted.
|
103
|
+
# Defaults to 0.
|
104
|
+
# @return [Google::Devtools::Cloudtrace::V2::TruncatableString] The
|
105
|
+
# generated proto
|
106
|
+
#
|
107
|
+
def make_truncatable_string str, truncated_byte_count = 0
|
108
|
+
TraceProtos::TruncatableString.new \
|
109
|
+
value: str,
|
110
|
+
truncated_byte_count: truncated_byte_count
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Convert a truncatable string object.
|
115
|
+
#
|
116
|
+
# @param [OpenCensus::Trace::TruncatableString] obj OpenCensus
|
117
|
+
# truncatable string object
|
118
|
+
# @return [Google::Devtools::Cloudtrace::V2::TruncatableString] The
|
119
|
+
# generated proto
|
120
|
+
#
|
121
|
+
def convert_truncatable_string obj
|
122
|
+
make_truncatable_string obj.value, obj.truncated_byte_count
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Convert a time object.
|
127
|
+
#
|
128
|
+
# @param [Time] time Ruby Time object
|
129
|
+
# @return [Google::Protobuf::Timestamp] The generated proto
|
130
|
+
#
|
131
|
+
def convert_time time
|
132
|
+
proto = Google::Protobuf::Timestamp.new
|
133
|
+
proto.from_time(time)
|
134
|
+
proto
|
135
|
+
end
|
136
|
+
|
137
|
+
##
|
138
|
+
# Convert a value that can be used for an attribute.
|
139
|
+
#
|
140
|
+
# @param [OpenCensus::Trace::TruncatableString, Integer, boolean]
|
141
|
+
# obj Object to convert
|
142
|
+
# @return [Google::Devtools::Cloudtrace::V2::AttributeValue] The
|
143
|
+
# generated proto
|
144
|
+
#
|
145
|
+
def convert_attribute_value obj
|
146
|
+
case obj
|
147
|
+
when OpenCensus::Trace::TruncatableString
|
148
|
+
TraceProtos::AttributeValue.new \
|
149
|
+
string_value: convert_truncatable_string(obj)
|
150
|
+
when Integer
|
151
|
+
TraceProtos::AttributeValue.new int_value: obj
|
152
|
+
when true, false
|
153
|
+
TraceProtos::AttributeValue.new bool_value: obj
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
##
|
158
|
+
# Convert an attributes hash
|
159
|
+
#
|
160
|
+
# @param [Hash] attributes The map of attribute values to convert
|
161
|
+
# @param [Integer] dropped_attributes_count Number of dropped
|
162
|
+
# @return [Google::Devtools::Cloudtrace::V2::Attributes] The
|
163
|
+
# generated proto
|
164
|
+
#
|
165
|
+
def convert_attributes attributes, dropped_attributes_count
|
166
|
+
attribute_map = {}
|
167
|
+
attributes.each do |k, v|
|
168
|
+
attribute_map[k] = convert_attribute_value v
|
169
|
+
end
|
170
|
+
TraceProtos::Span::Attributes.new \
|
171
|
+
attribute_map: attribute_map,
|
172
|
+
dropped_attributes_count: dropped_attributes_count
|
173
|
+
end
|
174
|
+
|
175
|
+
##
|
176
|
+
# Convert a single stack frame as a Thread::Backtrace::Location
|
177
|
+
#
|
178
|
+
# @param [Thread::Backtrace::Location] frame The backtrace element to
|
179
|
+
# convert
|
180
|
+
# @return [Google::Devtools::Cloudtrace::V2::StackTrace::StackFrame]
|
181
|
+
# The generated proto
|
182
|
+
#
|
183
|
+
def convert_stack_frame frame
|
184
|
+
TraceProtos::StackTrace::StackFrame.new \
|
185
|
+
function_name: make_truncatable_string(frame.label),
|
186
|
+
file_name: make_truncatable_string(frame.path),
|
187
|
+
line_number: frame.lineno
|
188
|
+
end
|
189
|
+
|
190
|
+
##
|
191
|
+
# Convert a full backtrace.
|
192
|
+
#
|
193
|
+
# @param [Array<Thread::Backtrace::Location>] backtrace The backtrace
|
194
|
+
# element array to convert
|
195
|
+
# @param [Integer] dropped_frames_count Frames that were dropped
|
196
|
+
# @param [Integer] stack_trace_hash_id Hash of the data
|
197
|
+
# @return [Google::Devtools::Cloudtrace::V2::StackTrace] The
|
198
|
+
# generated proto
|
199
|
+
#
|
200
|
+
def convert_stack_trace backtrace, dropped_frames_count,
|
201
|
+
stack_trace_hash_id
|
202
|
+
if @stack_trace_hash_ids[stack_trace_hash_id]
|
203
|
+
return TraceProtos::StackTrace.new \
|
204
|
+
stack_trace_hash_id: stack_trace_hash_id
|
205
|
+
end
|
206
|
+
@stack_trace_hash_ids[stack_trace_hash_id] = true
|
207
|
+
frame_protos = backtrace.map { |frame| convert_stack_frame(frame) }
|
208
|
+
frames_proto = TraceProtos::StackTrace::StackFrames.new \
|
209
|
+
frame: frame_protos,
|
210
|
+
dropped_frames_count: dropped_frames_count
|
211
|
+
TraceProtos::StackTrace.new \
|
212
|
+
stack_frames: frames_proto,
|
213
|
+
stack_trace_hash_id: stack_trace_hash_id
|
214
|
+
end
|
215
|
+
|
216
|
+
##
|
217
|
+
# Convert an annotation object
|
218
|
+
#
|
219
|
+
# @param [OpenCensus::Trace::Annotation] annotation The annotation
|
220
|
+
# object to convert
|
221
|
+
# @return
|
222
|
+
# [Google::Devtools::Cloudtrace::V2::Span::TimeEvent::Annotation]
|
223
|
+
# The generated proto
|
224
|
+
#
|
225
|
+
def convert_annotation annotation
|
226
|
+
annotation_proto = TraceProtos::Span::TimeEvent::Annotation.new \
|
227
|
+
description: convert_truncatable_string(annotation.description),
|
228
|
+
attributes:
|
229
|
+
convert_attributes(annotation.attributes,
|
230
|
+
annotation.dropped_attributes_count)
|
231
|
+
TraceProtos::Span::TimeEvent.new \
|
232
|
+
time: convert_time(annotation.time),
|
233
|
+
annotation: annotation_proto
|
234
|
+
end
|
235
|
+
|
236
|
+
##
|
237
|
+
# Convert a message event object
|
238
|
+
#
|
239
|
+
# @param [OpenCensus::Trace::MessageEvent] message_event The message
|
240
|
+
# event object to convert
|
241
|
+
# @return
|
242
|
+
# [Google::Devtools::Cloudtrace::V2::Span::TimeEvent::MessageEvent]
|
243
|
+
# The generated proto
|
244
|
+
#
|
245
|
+
def convert_message_event message_event
|
246
|
+
message_event_proto =
|
247
|
+
TraceProtos::Span::TimeEvent::MessageEvent.new \
|
248
|
+
type: message_event.type,
|
249
|
+
id: message_event.id,
|
250
|
+
uncompressed_size_bytes: message_event.uncompressed_size,
|
251
|
+
compressed_size_bytes: message_event.compressed_size
|
252
|
+
Google::Devtools::Cloudtrace::V2::Span::TimeEvent.new \
|
253
|
+
time: convert_time(message_event.time),
|
254
|
+
message_event: message_event_proto
|
255
|
+
end
|
256
|
+
|
257
|
+
##
|
258
|
+
# Convert a list of time event objects
|
259
|
+
#
|
260
|
+
# @param [Array<OpenCensus::Trace::TimeEvent>] time_events The time
|
261
|
+
# event objects to convert
|
262
|
+
# @param [Integer] dropped_annotations_count Number of dropped
|
263
|
+
# annotations
|
264
|
+
# @param [Integer] dropped_message_events_count Number of dropped
|
265
|
+
# message events
|
266
|
+
# @return [Google::Devtools::Cloudtrace::V2::Span::TimeEvents] The
|
267
|
+
# generated proto
|
268
|
+
#
|
269
|
+
def convert_time_events time_events, dropped_annotations_count,
|
270
|
+
dropped_message_events_count
|
271
|
+
time_event_protos = time_events.map do |time_event|
|
272
|
+
case time_event
|
273
|
+
when OpenCensus::Trace::Annotation
|
274
|
+
convert_annotation time_event
|
275
|
+
when OpenCensus::Trace::MessageEvent
|
276
|
+
convert_message_event time_event
|
277
|
+
else
|
278
|
+
nil
|
279
|
+
end
|
280
|
+
end.compact
|
281
|
+
TraceProtos::Span::TimeEvents.new \
|
282
|
+
time_event: time_event_protos,
|
283
|
+
dropped_annotations_count: dropped_annotations_count,
|
284
|
+
dropped_message_events_count: dropped_message_events_count
|
285
|
+
end
|
286
|
+
|
287
|
+
##
|
288
|
+
# Convert a link object
|
289
|
+
#
|
290
|
+
# @param [OpenCensus::Trace::Link] link The link object to convert
|
291
|
+
# @return [Google::Devtools::Cloudtrace::V2::Span::Link] The
|
292
|
+
# generated proto
|
293
|
+
#
|
294
|
+
def convert_link link
|
295
|
+
TraceProtos::Span::Link.new \
|
296
|
+
trace_id: link.trace_id,
|
297
|
+
span_id: link.span_id,
|
298
|
+
type: link.type,
|
299
|
+
attributes:
|
300
|
+
convert_attributes(link.attributes,
|
301
|
+
link.dropped_attributes_count)
|
302
|
+
end
|
303
|
+
|
304
|
+
##
|
305
|
+
# Convert a list of link objects
|
306
|
+
#
|
307
|
+
# @param [Array<OpenCensus::Trace::Link>] links The link objects to
|
308
|
+
# convert
|
309
|
+
# @param [Integer] dropped_links_count Number of dropped links
|
310
|
+
# @return [Google::Devtools::Cloudtrace::V2::Span::Links] The
|
311
|
+
# generated proto
|
312
|
+
#
|
313
|
+
def convert_links links, dropped_links_count
|
314
|
+
TraceProtos::Span::Links.new \
|
315
|
+
link: links.map { |link| convert_link link },
|
316
|
+
dropped_links_count: dropped_links_count
|
317
|
+
end
|
318
|
+
|
319
|
+
##
|
320
|
+
# Convert a nullable status object
|
321
|
+
#
|
322
|
+
# @param [OpenCensus::Trace::Status, nil] status The status object to
|
323
|
+
# convert, or nil if absent
|
324
|
+
# @return [Google::Rpc::Status, nil] The generated proto, or nil
|
325
|
+
#
|
326
|
+
def convert_optional_status status
|
327
|
+
return nil if status.nil?
|
328
|
+
Google::Rpc::Status.new code: status.code, message: status.message
|
329
|
+
end
|
330
|
+
|
331
|
+
##
|
332
|
+
# Convert a nullable boolean object
|
333
|
+
#
|
334
|
+
# @param [boolean, nil] value The value to convert, or nil if absent
|
335
|
+
# @return [Google::Protobuf::BoolValue, nil] Generated proto, or nil
|
336
|
+
#
|
337
|
+
def convert_optional_bool value
|
338
|
+
return nil if value.nil?
|
339
|
+
Google::Protobuf::BoolValue.new value: value
|
340
|
+
end
|
341
|
+
|
342
|
+
##
|
343
|
+
# Convert a nullable int32 object
|
344
|
+
#
|
345
|
+
# @param [Integer, nil] value The value to convert, or nil if absent
|
346
|
+
# @return [Google::Protobuf::Int32Value, nil] Generated proto, or nil
|
347
|
+
#
|
348
|
+
def convert_optional_int32 value
|
349
|
+
return nil if value.nil?
|
350
|
+
Google::Protobuf::Int32Value.new value: value
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|