google-cloud-trace 0.21.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +7 -0
- data/LICENSE +201 -0
- data/README.md +45 -0
- data/lib/google-cloud-trace.rb +97 -0
- data/lib/google/cloud/trace.rb +340 -0
- data/lib/google/cloud/trace/credentials.rb +41 -0
- data/lib/google/cloud/trace/label_key.rb +130 -0
- data/lib/google/cloud/trace/middleware.rb +358 -0
- data/lib/google/cloud/trace/notifications.rb +115 -0
- data/lib/google/cloud/trace/project.rb +219 -0
- data/lib/google/cloud/trace/rails.rb +231 -0
- data/lib/google/cloud/trace/result_set.rb +199 -0
- data/lib/google/cloud/trace/service.rb +166 -0
- data/lib/google/cloud/trace/span.rb +450 -0
- data/lib/google/cloud/trace/span_kind.rb +80 -0
- data/lib/google/cloud/trace/time_sampler.rb +104 -0
- data/lib/google/cloud/trace/trace_record.rb +332 -0
- data/lib/google/cloud/trace/utils.rb +46 -0
- data/lib/google/cloud/trace/v1.rb +16 -0
- data/lib/google/cloud/trace/v1/doc/google/devtools/cloudtrace/v1/trace.rb +187 -0
- data/lib/google/cloud/trace/v1/doc/google/protobuf/timestamp.rb +83 -0
- data/lib/google/cloud/trace/v1/trace_service_api.rb +307 -0
- data/lib/google/cloud/trace/v1/trace_service_client_config.json +43 -0
- data/lib/google/cloud/trace/version.rb +22 -0
- data/lib/google/devtools/cloudtrace/v1/trace_pb.rb +78 -0
- data/lib/google/devtools/cloudtrace/v1/trace_services_pb.rb +57 -0
- metadata +294 -0
@@ -0,0 +1,199 @@
|
|
1
|
+
# Copyright 2014 Google Inc. All rights reserved.
|
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
|
+
|
16
|
+
module Google
|
17
|
+
module Cloud
|
18
|
+
module Trace
|
19
|
+
##
|
20
|
+
# ResultSet represents the results of a `list_traces` request. It is
|
21
|
+
# an enumerable of the traces found, plus information about the request
|
22
|
+
# and a token to get the next page of results.
|
23
|
+
#
|
24
|
+
class ResultSet
|
25
|
+
include Enumerable
|
26
|
+
|
27
|
+
##
|
28
|
+
# Create a new ResultSet given an enumerable of result Trace objects,
|
29
|
+
# a next page token (or nil if this is the last page), and all the
|
30
|
+
# query parameters.
|
31
|
+
#
|
32
|
+
# @private
|
33
|
+
#
|
34
|
+
def initialize service, project,
|
35
|
+
results, next_page_token,
|
36
|
+
start_time, end_time,
|
37
|
+
filter: nil,
|
38
|
+
order_by: nil,
|
39
|
+
view: nil,
|
40
|
+
page_size: nil,
|
41
|
+
page_token: nil
|
42
|
+
@service = service
|
43
|
+
@project = project
|
44
|
+
@results = results
|
45
|
+
@next_page_token = next_page_token
|
46
|
+
@view = view
|
47
|
+
@page_size = page_size
|
48
|
+
@start_time = start_time
|
49
|
+
@end_time = end_time
|
50
|
+
@filter = filter
|
51
|
+
@order_by = order_by
|
52
|
+
@page_token = page_token
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# An `each` method that supports the Enumerable module. Iterates over
|
57
|
+
# the results and yields each, as a {Google::Cloud::Trace::TraceRecord}
|
58
|
+
# object, to the given block. If no block is provided, returns an
|
59
|
+
# Enumerator.
|
60
|
+
#
|
61
|
+
def each &block
|
62
|
+
@results.each(&block)
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Returns the number of traces in this page of results.
|
67
|
+
#
|
68
|
+
# @return [Integer]
|
69
|
+
#
|
70
|
+
def size
|
71
|
+
@results.size
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# The trace service client that obtained this result set
|
76
|
+
# @private
|
77
|
+
attr_reader :service
|
78
|
+
|
79
|
+
##
|
80
|
+
# The project ID string.
|
81
|
+
#
|
82
|
+
# @return [String]
|
83
|
+
#
|
84
|
+
attr_reader :project
|
85
|
+
|
86
|
+
##
|
87
|
+
# The token to pass to `list_traces` to get the next page, or nil if
|
88
|
+
# this is the last page.
|
89
|
+
#
|
90
|
+
# @return [String, nil]
|
91
|
+
#
|
92
|
+
attr_reader :next_page_token
|
93
|
+
|
94
|
+
##
|
95
|
+
# The `view` query parameter.
|
96
|
+
#
|
97
|
+
# @return [Symbol, nil]
|
98
|
+
#
|
99
|
+
attr_reader :view
|
100
|
+
|
101
|
+
##
|
102
|
+
# The `page_size` query parameter.
|
103
|
+
#
|
104
|
+
# @return [Integer, nil]
|
105
|
+
#
|
106
|
+
attr_reader :page_size
|
107
|
+
|
108
|
+
##
|
109
|
+
# The `start_time` query parameter.
|
110
|
+
#
|
111
|
+
# @return [Time, nil]
|
112
|
+
#
|
113
|
+
attr_reader :start_time
|
114
|
+
|
115
|
+
##
|
116
|
+
# The `end_time` query parameter.
|
117
|
+
#
|
118
|
+
# @return [Time, nil]
|
119
|
+
#
|
120
|
+
attr_reader :end_time
|
121
|
+
|
122
|
+
##
|
123
|
+
# The `filter` query parameter.
|
124
|
+
#
|
125
|
+
# @return [String, nil]
|
126
|
+
#
|
127
|
+
attr_reader :filter
|
128
|
+
|
129
|
+
##
|
130
|
+
# The `order_by` query parameter.
|
131
|
+
#
|
132
|
+
# @return [String, nil]
|
133
|
+
#
|
134
|
+
attr_reader :order_by
|
135
|
+
|
136
|
+
##
|
137
|
+
# The page token used to obtain this page of results.
|
138
|
+
#
|
139
|
+
# @return [String, nil]
|
140
|
+
#
|
141
|
+
attr_reader :page_token
|
142
|
+
|
143
|
+
##
|
144
|
+
# Returns true if at least one more page of results can be retrieved.
|
145
|
+
#
|
146
|
+
# @return [Boolean]
|
147
|
+
#
|
148
|
+
def results_pending?
|
149
|
+
!next_page_token.nil?
|
150
|
+
end
|
151
|
+
|
152
|
+
##
|
153
|
+
# Queries the service for the next page of results and returns a new
|
154
|
+
# ResultSet for that page. Returns `nil` if there are no more results.
|
155
|
+
#
|
156
|
+
# @return [Google::Cloud::Trace::ResultSet]
|
157
|
+
#
|
158
|
+
def next_page
|
159
|
+
return nil unless results_pending?
|
160
|
+
service.list_traces \
|
161
|
+
project, start_time, end_time,
|
162
|
+
filter: filter,
|
163
|
+
order_by: order_by,
|
164
|
+
view: view,
|
165
|
+
page_size: page_size,
|
166
|
+
page_token: next_page_token
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Create a new ResultSet given a Google::Gax::PagedEnumerable::Page,
|
171
|
+
# and all the query parameters.
|
172
|
+
#
|
173
|
+
# @private
|
174
|
+
#
|
175
|
+
def self.from_gax_page service, project_id,
|
176
|
+
page, start_time, end_time,
|
177
|
+
filter: nil,
|
178
|
+
order_by: nil,
|
179
|
+
view: nil,
|
180
|
+
page_size: nil,
|
181
|
+
page_token: nil
|
182
|
+
next_page_token = page.next_page_token
|
183
|
+
next_page_token = nil unless page.next_page_token?
|
184
|
+
results = page.map do |proto|
|
185
|
+
Google::Cloud::Trace::TraceRecord.from_grpc proto
|
186
|
+
end
|
187
|
+
new service, project_id,
|
188
|
+
results, next_page_token,
|
189
|
+
start_time, end_time,
|
190
|
+
filter: filter,
|
191
|
+
order_by: order_by,
|
192
|
+
view: view,
|
193
|
+
page_size: page_size,
|
194
|
+
page_token: page_token
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# Copyright 2014 Google Inc. All rights reserved.
|
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
|
+
|
16
|
+
require "google/cloud/errors"
|
17
|
+
require "google/cloud/trace/version"
|
18
|
+
require "google/cloud/trace/v1"
|
19
|
+
require "google/gax/errors"
|
20
|
+
|
21
|
+
module Google
|
22
|
+
module Cloud
|
23
|
+
module Trace
|
24
|
+
##
|
25
|
+
# Represents the connection to Trace, and exposes the API calls.
|
26
|
+
#
|
27
|
+
# @private
|
28
|
+
#
|
29
|
+
class Service
|
30
|
+
##
|
31
|
+
# @private
|
32
|
+
attr_accessor :project
|
33
|
+
|
34
|
+
##
|
35
|
+
# @private
|
36
|
+
attr_accessor :credentials
|
37
|
+
|
38
|
+
##
|
39
|
+
# @private
|
40
|
+
attr_accessor :host
|
41
|
+
|
42
|
+
##
|
43
|
+
# @private
|
44
|
+
attr_accessor :timeout
|
45
|
+
|
46
|
+
##
|
47
|
+
# @private
|
48
|
+
attr_accessor :client_config
|
49
|
+
|
50
|
+
##
|
51
|
+
# Creates a new Service instance.
|
52
|
+
def initialize project, credentials, host: nil, timeout: nil,
|
53
|
+
client_config: nil
|
54
|
+
@project = project
|
55
|
+
@credentials = credentials
|
56
|
+
@host = host || V1::TraceServiceApi::SERVICE_ADDRESS
|
57
|
+
@timeout = timeout
|
58
|
+
@client_config = client_config || {}
|
59
|
+
end
|
60
|
+
|
61
|
+
def channel
|
62
|
+
require "grpc"
|
63
|
+
GRPC::Core::Channel.new host, nil, chan_creds
|
64
|
+
end
|
65
|
+
|
66
|
+
def chan_creds
|
67
|
+
return credentials if insecure?
|
68
|
+
require "grpc"
|
69
|
+
GRPC::Core::ChannelCredentials.new.compose \
|
70
|
+
GRPC::Core::CallCredentials.new credentials.client.updater_proc
|
71
|
+
end
|
72
|
+
|
73
|
+
def insecure?
|
74
|
+
credentials == :this_channel_is_insecure
|
75
|
+
end
|
76
|
+
|
77
|
+
def lowlevel_client
|
78
|
+
return mocked_lowlevel_client if mocked_lowlevel_client
|
79
|
+
@lowlevel_client ||= \
|
80
|
+
V1::TraceServiceApi.new(
|
81
|
+
service_path: host,
|
82
|
+
channel: channel,
|
83
|
+
timeout: timeout,
|
84
|
+
client_config: client_config,
|
85
|
+
app_name: "gcloud-ruby",
|
86
|
+
app_version: Google::Cloud::Trace::VERSION)
|
87
|
+
end
|
88
|
+
attr_accessor :mocked_lowlevel_client
|
89
|
+
|
90
|
+
##
|
91
|
+
# Sends new traces to Stackdriver Trace or updates existing traces.
|
92
|
+
def patch_traces traces
|
93
|
+
traces = Array(traces)
|
94
|
+
traces_proto = Google::Devtools::Cloudtrace::V1::Traces.new
|
95
|
+
traces.each do |trace|
|
96
|
+
traces_proto.traces.push trace.to_grpc
|
97
|
+
end
|
98
|
+
execute do
|
99
|
+
lowlevel_client.patch_traces @project, traces_proto
|
100
|
+
end
|
101
|
+
traces
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Returns a trace given its ID
|
106
|
+
def get_trace trace_id
|
107
|
+
trace_proto = execute do
|
108
|
+
lowlevel_client.get_trace @project, trace_id
|
109
|
+
end
|
110
|
+
Google::Cloud::Trace::TraceRecord.from_grpc trace_proto
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Searches for traces matching the given criteria.
|
115
|
+
#
|
116
|
+
# rubocop:disable Metrics/MethodLength
|
117
|
+
def list_traces project_id, start_time, end_time,
|
118
|
+
filter: nil,
|
119
|
+
order_by: nil,
|
120
|
+
view: nil,
|
121
|
+
page_size: nil,
|
122
|
+
page_token: nil
|
123
|
+
if page_token
|
124
|
+
call_opts = Google::Gax::CallOptions.new page_token: page_token
|
125
|
+
else
|
126
|
+
call_opts = Google::Gax::CallOptions.new
|
127
|
+
end
|
128
|
+
start_proto = Google::Cloud::Trace::Utils.time_to_grpc start_time
|
129
|
+
end_proto = Google::Cloud::Trace::Utils.time_to_grpc end_time
|
130
|
+
paged_enum = execute do
|
131
|
+
lowlevel_client.list_traces project_id,
|
132
|
+
view: view,
|
133
|
+
page_size: page_size,
|
134
|
+
start_time: start_proto,
|
135
|
+
end_time: end_proto,
|
136
|
+
filter: filter,
|
137
|
+
order_by: order_by,
|
138
|
+
options: call_opts
|
139
|
+
end
|
140
|
+
Google::Cloud::Trace::ResultSet.from_gax_page \
|
141
|
+
self, project_id,
|
142
|
+
paged_enum.page, start_time, end_time,
|
143
|
+
filter: filter,
|
144
|
+
order_by: order_by,
|
145
|
+
view: view,
|
146
|
+
page_size: page_size,
|
147
|
+
page_token: page_token
|
148
|
+
end
|
149
|
+
|
150
|
+
# @private
|
151
|
+
def inspect
|
152
|
+
"#{self.class}(#{@project})"
|
153
|
+
end
|
154
|
+
|
155
|
+
protected
|
156
|
+
|
157
|
+
def execute
|
158
|
+
yield
|
159
|
+
rescue Google::Gax::GaxError => e
|
160
|
+
# GaxError wraps BadStatus, but exposes it as #cause
|
161
|
+
raise Google::Cloud::Error.from_error(e.cause)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,450 @@
|
|
1
|
+
# Copyright 2014 Google Inc. All rights reserved.
|
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
|
+
|
16
|
+
require "set"
|
17
|
+
require "google/devtools/cloudtrace/v1/trace_pb"
|
18
|
+
|
19
|
+
module Google
|
20
|
+
module Cloud
|
21
|
+
module Trace
|
22
|
+
##
|
23
|
+
# Span represents a span in a trace record. Spans are contained in
|
24
|
+
# a trace and arranged in a forest. That is, each span may be a root span
|
25
|
+
# or have a parent span, and may have zero or more children.
|
26
|
+
#
|
27
|
+
class Span
|
28
|
+
##
|
29
|
+
# The Trace object containing this span.
|
30
|
+
#
|
31
|
+
# @return [Google::Cloud::Trace::TraceRecord]
|
32
|
+
#
|
33
|
+
attr_reader :trace
|
34
|
+
|
35
|
+
##
|
36
|
+
# The TraceSpan object representing this span's parent, or `nil` if
|
37
|
+
# this span is a root span.
|
38
|
+
#
|
39
|
+
# @return [Google::Cloud::Trace::Span, nil]
|
40
|
+
#
|
41
|
+
attr_reader :parent
|
42
|
+
|
43
|
+
##
|
44
|
+
# The numeric ID of this span.
|
45
|
+
#
|
46
|
+
# @return [Integer]
|
47
|
+
#
|
48
|
+
attr_reader :span_id
|
49
|
+
|
50
|
+
##
|
51
|
+
# The ID of the parent span, as an integer that may be zero if this
|
52
|
+
# is a true root span.
|
53
|
+
#
|
54
|
+
# Note that it is possible for a span to be "orphaned", that is, to be
|
55
|
+
# a root span with a nonzero parent ID, indicating that parent has not
|
56
|
+
# (yet) been written. In that case, `parent` will return nil, but
|
57
|
+
# `parent_span_id` will have a value.
|
58
|
+
#
|
59
|
+
# @return [Integer]
|
60
|
+
#
|
61
|
+
attr_reader :parent_span_id
|
62
|
+
|
63
|
+
##
|
64
|
+
# The kind of this span.
|
65
|
+
#
|
66
|
+
# @return [Google::Cloud::Trace::SpanKind]
|
67
|
+
#
|
68
|
+
attr_accessor :kind
|
69
|
+
|
70
|
+
##
|
71
|
+
# The name of this span.
|
72
|
+
#
|
73
|
+
# @return [String]
|
74
|
+
#
|
75
|
+
attr_accessor :name
|
76
|
+
|
77
|
+
##
|
78
|
+
# The starting timestamp of this span in UTC, or `nil` if the
|
79
|
+
# starting timestamp has not yet been populated.
|
80
|
+
#
|
81
|
+
# @return [Time, nil]
|
82
|
+
#
|
83
|
+
attr_accessor :start_time
|
84
|
+
|
85
|
+
##
|
86
|
+
# The ending timestamp of this span in UTC, or `nil` if the
|
87
|
+
# ending timestamp has not yet been populated.
|
88
|
+
#
|
89
|
+
# @return [Time, nil]
|
90
|
+
#
|
91
|
+
attr_accessor :end_time
|
92
|
+
|
93
|
+
##
|
94
|
+
# The properties of this span.
|
95
|
+
#
|
96
|
+
# @return [Hash{String => String}]
|
97
|
+
#
|
98
|
+
attr_reader :labels
|
99
|
+
|
100
|
+
##
|
101
|
+
# Create an empty Span object.
|
102
|
+
#
|
103
|
+
# @private
|
104
|
+
#
|
105
|
+
def initialize trace, id, parent_span_id, parent, name, kind,
|
106
|
+
start_time, end_time, labels
|
107
|
+
@trace = trace
|
108
|
+
@span_id = id
|
109
|
+
@parent_span_id = parent_span_id
|
110
|
+
@parent = parent
|
111
|
+
@children = []
|
112
|
+
@name = name
|
113
|
+
@kind = kind
|
114
|
+
@start_time = start_time
|
115
|
+
@end_time = end_time
|
116
|
+
@labels = labels
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# Standard value equality check for this object.
|
121
|
+
#
|
122
|
+
# @param [Object] other
|
123
|
+
# @return [Boolean]
|
124
|
+
#
|
125
|
+
# rubocop:disable Metrics/AbcSize
|
126
|
+
def eql? other
|
127
|
+
other.is_a?(Google::Cloud::Trace::Span) &&
|
128
|
+
trace.trace_context == other.trace.trace_context &&
|
129
|
+
span_id == other.span_id &&
|
130
|
+
parent_span_id == other.parent_span_id &&
|
131
|
+
same_children?(other) &&
|
132
|
+
kind == other.kind &&
|
133
|
+
name == other.name &&
|
134
|
+
start_time == other.start_time &&
|
135
|
+
end_time == other.end_time &&
|
136
|
+
labels == other.labels
|
137
|
+
end
|
138
|
+
alias_method :==, :eql?
|
139
|
+
|
140
|
+
##
|
141
|
+
# Create a new Span object from a TraceSpan protobuf and insert it
|
142
|
+
# into the given trace.
|
143
|
+
#
|
144
|
+
# @param [Google::Devtools::Cloudtrace::V1::TraceSpan] span_proto The
|
145
|
+
# span protobuf from the V1 gRPC Trace API.
|
146
|
+
# @param [Google::Cloud::Trace::TraceRecord] trace The trace object
|
147
|
+
# to contain the span.
|
148
|
+
# @return [Google::Cloud::Trace::Span] A corresponding Span object.
|
149
|
+
#
|
150
|
+
def self.from_grpc span_proto, trace
|
151
|
+
labels = {}
|
152
|
+
span_proto.labels.each { |k, v| labels[k] = v }
|
153
|
+
span_kind = SpanKind.get span_proto.kind
|
154
|
+
start_time =
|
155
|
+
Google::Cloud::Trace::Utils.grpc_to_time span_proto.start_time
|
156
|
+
end_time =
|
157
|
+
Google::Cloud::Trace::Utils.grpc_to_time span_proto.end_time
|
158
|
+
trace.create_span span_proto.name,
|
159
|
+
parent_span_id: span_proto.parent_span_id.to_i,
|
160
|
+
span_id: span_proto.span_id.to_i,
|
161
|
+
kind: span_kind,
|
162
|
+
start_time: start_time,
|
163
|
+
end_time: end_time,
|
164
|
+
labels: labels
|
165
|
+
end
|
166
|
+
|
167
|
+
##
|
168
|
+
# Convert this Span object to an equivalent TraceSpan protobuf suitable
|
169
|
+
# for the V1 gRPC Trace API.
|
170
|
+
#
|
171
|
+
# @param [Integer] default_parent_id The parent span ID to use if the
|
172
|
+
# span has no parent in the trace tree. Optional; defaults to 0.
|
173
|
+
# @return [Google::Devtools::Cloudtrace::V1::TraceSpan] The generated
|
174
|
+
# protobuf.
|
175
|
+
#
|
176
|
+
def to_grpc default_parent_id = 0
|
177
|
+
start_proto = Google::Cloud::Trace::Utils.time_to_grpc start_time
|
178
|
+
end_proto = Google::Cloud::Trace::Utils.time_to_grpc end_time
|
179
|
+
Google::Devtools::Cloudtrace::V1::TraceSpan.new \
|
180
|
+
span_id: span_id.to_i,
|
181
|
+
kind: kind.to_sym,
|
182
|
+
name: name,
|
183
|
+
start_time: start_proto,
|
184
|
+
end_time: end_proto,
|
185
|
+
parent_span_id: parent_span_id || default_parent_id,
|
186
|
+
labels: labels
|
187
|
+
end
|
188
|
+
|
189
|
+
##
|
190
|
+
# Returns true if this span exists. A span exists until it has been
|
191
|
+
# removed from its trace.
|
192
|
+
#
|
193
|
+
# @return [Boolean]
|
194
|
+
#
|
195
|
+
def exists?
|
196
|
+
!@trace.nil?
|
197
|
+
end
|
198
|
+
|
199
|
+
##
|
200
|
+
# Returns the trace context in effect within this span.
|
201
|
+
#
|
202
|
+
# @return [Stackdriver::Core::TraceContext]
|
203
|
+
#
|
204
|
+
def trace_context
|
205
|
+
ensure_exists!
|
206
|
+
trace.trace_context.with span_id: span_id
|
207
|
+
end
|
208
|
+
|
209
|
+
##
|
210
|
+
# Returns the trace ID for this span.
|
211
|
+
#
|
212
|
+
# @return [String] The trace ID string.
|
213
|
+
#
|
214
|
+
def trace_id
|
215
|
+
ensure_exists!
|
216
|
+
trace.trace_id
|
217
|
+
end
|
218
|
+
|
219
|
+
##
|
220
|
+
# Returns a list of children of this span.
|
221
|
+
#
|
222
|
+
# @return [Array{TraceSpan}] The children.
|
223
|
+
#
|
224
|
+
def children
|
225
|
+
ensure_exists!
|
226
|
+
@children.dup
|
227
|
+
end
|
228
|
+
|
229
|
+
##
|
230
|
+
# Creates a new child span under this span.
|
231
|
+
#
|
232
|
+
# @param [String] name The name of the span.
|
233
|
+
# @param [Integer] span_id The numeric ID of the span, or nil to
|
234
|
+
# generate a new random unique ID. Optional (defaults to nil).
|
235
|
+
# @param [SpanKind] kind The kind of span. Optional.
|
236
|
+
# @param [Time] start_time The starting timestamp, or nil if not yet
|
237
|
+
# specified. Optional (defaults to nil).
|
238
|
+
# @param [Time] end_time The ending timestamp, or nil if not yet
|
239
|
+
# specified. Optional (defaults to nil).
|
240
|
+
# @param [Hash{String=>String}] labels The span properties. Optional
|
241
|
+
# (defaults to empty).
|
242
|
+
# @return [TraceSpan] The created span.
|
243
|
+
#
|
244
|
+
# @example
|
245
|
+
# require "google/cloud/trace"
|
246
|
+
#
|
247
|
+
# trace = Google::Cloud::Trace.new trace_context
|
248
|
+
# span = trace.create_span "root_span"
|
249
|
+
# subspan = span.create_span "subspan"
|
250
|
+
#
|
251
|
+
def create_span name, span_id: nil, kind: SpanKind::UNSPECIFIED,
|
252
|
+
start_time: nil, end_time: nil,
|
253
|
+
labels: {}
|
254
|
+
ensure_exists!
|
255
|
+
span = trace.internal_create_span self, span_id, self.span_id, name,
|
256
|
+
kind, start_time, end_time, labels
|
257
|
+
@children << span
|
258
|
+
span
|
259
|
+
end
|
260
|
+
|
261
|
+
##
|
262
|
+
# Creates a root span around the given block. Automatically populates
|
263
|
+
# the start and end timestamps. The span (with start time but not end
|
264
|
+
# time populated) is yielded to the block.
|
265
|
+
#
|
266
|
+
# @param [String] name The name of the span.
|
267
|
+
# @param [SpanKind] kind The kind of span. Optional.
|
268
|
+
# @param [Hash{String=>String}] labels The span properties. Optional
|
269
|
+
# (defaults to empty).
|
270
|
+
# @return [TraceSpan] The created span.
|
271
|
+
#
|
272
|
+
# @example
|
273
|
+
# require "google/cloud/trace"
|
274
|
+
#
|
275
|
+
# trace = Google::Cloud::Trace.new trace_context
|
276
|
+
# trace.in_span "root_span" do |span|
|
277
|
+
# # Do stuff...
|
278
|
+
# span.in_span "subspan" do |subspan|
|
279
|
+
# # Do subspan stuff...
|
280
|
+
# end
|
281
|
+
# # Do stuff...
|
282
|
+
# end
|
283
|
+
#
|
284
|
+
def in_span name, kind: SpanKind::UNSPECIFIED, labels: {}
|
285
|
+
span = create_span name, kind: kind, labels: labels
|
286
|
+
span.start!
|
287
|
+
yield span
|
288
|
+
ensure
|
289
|
+
span.finish!
|
290
|
+
end
|
291
|
+
|
292
|
+
##
|
293
|
+
# Sets the starting timestamp for this span to the current time.
|
294
|
+
# Asserts that the timestamp has not yet been set, and throws a
|
295
|
+
# RuntimeError if that is not the case.
|
296
|
+
# Also ensures that all ancestor spans have already started, and
|
297
|
+
# starts them if not.
|
298
|
+
#
|
299
|
+
def start!
|
300
|
+
fail "Span already started" if start_time
|
301
|
+
ensure_started
|
302
|
+
end
|
303
|
+
|
304
|
+
##
|
305
|
+
# Sets the ending timestamp for this span to the current time.
|
306
|
+
# Asserts that the timestamp has not yet been set, and throws a
|
307
|
+
# RuntimeError if that is not the case.
|
308
|
+
# Also ensures that all descendant spans have also finished, and
|
309
|
+
# finishes them if not.
|
310
|
+
#
|
311
|
+
def finish!
|
312
|
+
fail "Span not yet started" unless start_time
|
313
|
+
fail "Span already finished" if end_time
|
314
|
+
ensure_finished
|
315
|
+
end
|
316
|
+
|
317
|
+
##
|
318
|
+
# Sets the starting timestamp for this span to the current time, if
|
319
|
+
# it has not yet been set. Also ensures that all ancestor spans have
|
320
|
+
# also been started.
|
321
|
+
# Does nothing if the starting timestamp for this span is already set.
|
322
|
+
#
|
323
|
+
def ensure_started
|
324
|
+
ensure_exists!
|
325
|
+
unless start_time
|
326
|
+
self.start_time = ::Time.now.utc
|
327
|
+
parent.ensure_started if parent
|
328
|
+
end
|
329
|
+
self
|
330
|
+
end
|
331
|
+
|
332
|
+
##
|
333
|
+
# Sets the ending timestamp for this span to the current time, if
|
334
|
+
# it has not yet been set. Also ensures that all descendant spans have
|
335
|
+
# also been finished.
|
336
|
+
# Does nothing if the ending timestamp for this span is already set.
|
337
|
+
#
|
338
|
+
def ensure_finished
|
339
|
+
ensure_exists!
|
340
|
+
unless end_time
|
341
|
+
self.end_time = ::Time.now.utc
|
342
|
+
@children.each(&:ensure_finished)
|
343
|
+
end
|
344
|
+
self
|
345
|
+
end
|
346
|
+
|
347
|
+
##
|
348
|
+
# Deletes this span, and all descendant spans. After this completes,
|
349
|
+
# {Span#exists?} will return `false`.
|
350
|
+
#
|
351
|
+
def delete
|
352
|
+
ensure_exists!
|
353
|
+
@children.each(&:delete)
|
354
|
+
parent.remove_child(self) if parent
|
355
|
+
trace.remove_span(self)
|
356
|
+
@trace = nil
|
357
|
+
@parent = nil
|
358
|
+
self
|
359
|
+
end
|
360
|
+
|
361
|
+
##
|
362
|
+
# Moves this span under a new parent, which must be part of the same
|
363
|
+
# trace. The entire tree under this span moves with it.
|
364
|
+
#
|
365
|
+
# @param [Google::Cloud::Trace::Span] new_parent The new parent.
|
366
|
+
#
|
367
|
+
# @example
|
368
|
+
# require "google/cloud/trace"
|
369
|
+
#
|
370
|
+
# trace = Google::Cloud::Trace.new
|
371
|
+
# root1 = trace.create_span "root_span_1"
|
372
|
+
# root2 = trace.create_span "root_span_2"
|
373
|
+
# subspan = root1.create_span "subspan"
|
374
|
+
# subspan.move_under root2
|
375
|
+
#
|
376
|
+
def move_under new_parent
|
377
|
+
ensure_exists!
|
378
|
+
ensure_no_cycle! new_parent
|
379
|
+
if parent
|
380
|
+
parent.remove_child self
|
381
|
+
else
|
382
|
+
trace.remove_root self
|
383
|
+
end
|
384
|
+
if new_parent
|
385
|
+
new_parent.add_child self
|
386
|
+
@parent_span_id = new_parent.span_id
|
387
|
+
else
|
388
|
+
trace.add_root self
|
389
|
+
@parent_span_id = 0
|
390
|
+
end
|
391
|
+
@parent = new_parent
|
392
|
+
self
|
393
|
+
end
|
394
|
+
|
395
|
+
##
|
396
|
+
# Add the given span to this span's child list.
|
397
|
+
#
|
398
|
+
# @private
|
399
|
+
#
|
400
|
+
def add_child child
|
401
|
+
@children << child
|
402
|
+
end
|
403
|
+
|
404
|
+
##
|
405
|
+
# Remove the given span from this span's child list.
|
406
|
+
#
|
407
|
+
# @private
|
408
|
+
#
|
409
|
+
def remove_child child
|
410
|
+
@children.delete child
|
411
|
+
end
|
412
|
+
|
413
|
+
##
|
414
|
+
# Ensure this span exists (i.e. has not been deleted) and throw a
|
415
|
+
# RuntimeError if not.
|
416
|
+
#
|
417
|
+
# @private
|
418
|
+
#
|
419
|
+
def ensure_exists!
|
420
|
+
fail "Span has been deleted" unless trace
|
421
|
+
end
|
422
|
+
|
423
|
+
##
|
424
|
+
# Ensure moving this span under the given parent would not result
|
425
|
+
# in a cycle, and throw a RuntimeError if it would.
|
426
|
+
#
|
427
|
+
# @private
|
428
|
+
#
|
429
|
+
def ensure_no_cycle! new_parent
|
430
|
+
ptr = new_parent
|
431
|
+
until ptr.nil?
|
432
|
+
fail "Move would result in a cycle" if ptr.equal?(self)
|
433
|
+
ptr = ptr.parent
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
##
|
438
|
+
# Returns true if this span has the same children as the given other.
|
439
|
+
#
|
440
|
+
# @private
|
441
|
+
#
|
442
|
+
def same_children? other
|
443
|
+
child_ids = @children.map(&:span_id)
|
444
|
+
other_child_ids = other.children.map(&:span_id)
|
445
|
+
::Set.new(child_ids) == ::Set.new(other_child_ids)
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|