google-cloud-trace 0.21.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/.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
|