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,41 @@
|
|
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/credentials"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Trace
|
21
|
+
##
|
22
|
+
# @private Represents the OAuth 2.0 signing logic for Trace.
|
23
|
+
class Credentials < Google::Cloud::Credentials
|
24
|
+
SCOPE = ["https://www.googleapis.com/auth/cloud-platform"]
|
25
|
+
PATH_ENV_VARS = %w(TRACE_KEYFILE GOOGLE_CLOUD_KEYFILE GCLOUD_KEYFILE)
|
26
|
+
JSON_ENV_VARS = %w(TRACE_KEYFILE_JSON GOOGLE_CLOUD_KEYFILE_JSON
|
27
|
+
GCLOUD_KEYFILE_JSON)
|
28
|
+
|
29
|
+
##
|
30
|
+
# @private Create credentials with given scope and/or keyfile
|
31
|
+
def self.credentials_with_scope keyfile, scope = nil
|
32
|
+
if keyfile.nil?
|
33
|
+
default(scope: scope)
|
34
|
+
else
|
35
|
+
new(keyfile, scope: scope)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,130 @@
|
|
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 "json"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Trace
|
21
|
+
##
|
22
|
+
# A collection of well-known label keys for trace spans.
|
23
|
+
#
|
24
|
+
module LabelKey
|
25
|
+
AGENT = "/agent"
|
26
|
+
COMPONENT = "/component"
|
27
|
+
ERROR_MESSAGE = "/error/message"
|
28
|
+
ERROR_NAME = "/error/name"
|
29
|
+
HTTP_CLIENT_CITY = "/http/client_city"
|
30
|
+
HTTP_CLIENT_COUNTRY = "/http/client_country"
|
31
|
+
HTTP_CLIENT_PROTOCOL = "/http/client_protocol"
|
32
|
+
HTTP_CLIENT_REGION = "/http/client_region"
|
33
|
+
HTTP_HOST = "/http/host"
|
34
|
+
HTTP_METHOD = "/http/method"
|
35
|
+
HTTP_REDIRECTED_URL = "/http/redirected_url"
|
36
|
+
HTTP_REQUEST_SIZE = "/http/request/size"
|
37
|
+
HTTP_RESPONSE_SIZE = "/http/response/size"
|
38
|
+
HTTP_STATUS_CODE = "/http/status_code"
|
39
|
+
HTTP_URL = "/http/url"
|
40
|
+
HTTP_USER_AGENT = "/http/user_agent"
|
41
|
+
PID = "/pid"
|
42
|
+
STACKTRACE = "/stacktrace"
|
43
|
+
TID = "/tid"
|
44
|
+
|
45
|
+
GAE_APPLICATION_ERROR = "g.co/gae/application_error"
|
46
|
+
GAE_APP_MODULE = "g.co/gae/app/module"
|
47
|
+
GAE_APP_MODULE_VERSION = "g.co/gae/app/module_version"
|
48
|
+
GAE_APP_VERSION = "g.co/gae/app/version"
|
49
|
+
GAE_DATASTORE_COUNT = "g.co/gae/datastore/count"
|
50
|
+
GAE_DATASTORE_CURSOR = "g.co/gae/datastore/cursor"
|
51
|
+
GAE_DATASTORE_ENTITY_WRITES = "g.co/gae/datastore/entity_writes"
|
52
|
+
GAE_DATASTORE_HAS_ANCESTOR = "g.co/gae/datastore/has_ancestor"
|
53
|
+
GAE_DATASTORE_HAS_CURSOR = "g.co/gae/datastore/has_cursor"
|
54
|
+
GAE_DATASTORE_HAS_TRANSACTION = "g.co/gae/datastore/has_transaction"
|
55
|
+
GAE_DATASTORE_INDEX_WRITES = "g.co/gae/datastore/index_writes"
|
56
|
+
GAE_DATASTORE_KIND = "g.co/gae/datastore/kind"
|
57
|
+
GAE_DATASTORE_LIMIT = "g.co/gae/datastore/limit"
|
58
|
+
GAE_DATASTORE_MORE_RESULTS = "g.co/gae/datastore/more_results"
|
59
|
+
GAE_DATASTORE_OFFSET = "g.co/gae/datastore/offset"
|
60
|
+
GAE_DATASTORE_REQUESTED_ENTITY_DELETES =
|
61
|
+
"g.co/gae/datastore/requested_entity_deletes"
|
62
|
+
GAE_DATASTORE_REQUESTED_ENTITY_PUTS =
|
63
|
+
"g.co/gae/datastore/requested_entity_puts"
|
64
|
+
GAE_DATASTORE_SIZE = "g.co/gae/datastore/size"
|
65
|
+
GAE_DATASTORE_SKIPPED = "g.co/gae/datastore/skipped"
|
66
|
+
GAE_DATASTORE_TRANSACTION_HANDLE =
|
67
|
+
"g.co/gae/datastore/transaction_handle"
|
68
|
+
GAE_ERROR_MESSAGE = "g.co/gae/error_message"
|
69
|
+
GAE_MEMCACHE_COUNT = "g.co/gae/memcache/count"
|
70
|
+
GAE_MEMCACHE_SIZE = "g.co/gae/memcache/size"
|
71
|
+
GAE_REQUEST_LOG_ID = "g.co/gae/request_log_id"
|
72
|
+
|
73
|
+
##
|
74
|
+
# Set the stack trace label in the given labels hash. The current call
|
75
|
+
# stack is formatted so the Stackdriver UI will display it.
|
76
|
+
#
|
77
|
+
# @param [Hash] labels The labels hash in which to set the stack trace
|
78
|
+
# label value.
|
79
|
+
# @param [Array<Thread::Backtrace::Location>] stack_frames The current
|
80
|
+
# caller stack as returned from `::Kernel.caller_locations`. If
|
81
|
+
# not set, `::Kernel.caller_locations` is called internally.
|
82
|
+
# @param [Integer] skip_frames Passed to the internal invocation of
|
83
|
+
# `::Kernel.caller_locations` if one is needed.
|
84
|
+
# @param [Proc] truncate_stack A procedure that allows skipping of
|
85
|
+
# the "topmost" stack frames. Stack frames, represented by
|
86
|
+
# instances of `Thread::Backtrace::Location`, are passed to this
|
87
|
+
# proc beginning with the topmost frame. As long as the proc
|
88
|
+
# returns a falsy value, those frames are dropped. Once the proc
|
89
|
+
# returns true for the first time, that frame and all remaining
|
90
|
+
# frames (possibly subject to `filter_stack`) are used. If not set,
|
91
|
+
# no frames are skipped.
|
92
|
+
# @param [Proc] filter_stack A procedure that allows skipping of
|
93
|
+
# stack frames in the middle of the stack trace. After possibly
|
94
|
+
# skipping frames using `truncate_stack`, all remaining frames are
|
95
|
+
# passed to this proc as `Thread::Backtrace::Location` objects.
|
96
|
+
# Those for whom the proc returns a falsy value are skipped. If
|
97
|
+
# this parameter is not set, no filtering is done and all frames
|
98
|
+
# are presented in the stack trace.
|
99
|
+
#
|
100
|
+
# @example
|
101
|
+
# require "google/cloud/trace"
|
102
|
+
#
|
103
|
+
# trace = Google::Cloud::Trace.new
|
104
|
+
# span = trace.create_span "root_span"
|
105
|
+
# Google::Cloud::Trace::LabelKey.set_stack_trace span.labels
|
106
|
+
#
|
107
|
+
def self.set_stack_trace labels,
|
108
|
+
stack_frames: nil, skip_frames: 1,
|
109
|
+
truncate_stack: nil, filter_stack: nil
|
110
|
+
stack_frames ||= ::Kernel.caller_locations skip_frames
|
111
|
+
json_frames = []
|
112
|
+
collecting_frames = !truncate_stack
|
113
|
+
stack_frames.each do |frame|
|
114
|
+
collecting_frames ||= truncate_stack.call(frame)
|
115
|
+
next unless collecting_frames
|
116
|
+
next unless !filter_stack || filter_stack.call(frame)
|
117
|
+
json_frames <<
|
118
|
+
{
|
119
|
+
file_name: frame.absolute_path,
|
120
|
+
line_number: frame.lineno,
|
121
|
+
method_name: frame.label
|
122
|
+
}
|
123
|
+
end
|
124
|
+
json_object = { stack_frame: json_frames }
|
125
|
+
labels[STACKTRACE] = JSON.generate json_object
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,358 @@
|
|
1
|
+
# Copyright 2016 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/core/environment"
|
17
|
+
require "stackdriver/core/trace_context"
|
18
|
+
|
19
|
+
module Google
|
20
|
+
module Cloud
|
21
|
+
module Trace
|
22
|
+
##
|
23
|
+
# # Trace Middleware
|
24
|
+
#
|
25
|
+
# A Rack middleware that manages trace context and captures a trace of
|
26
|
+
# the request. Specifically, it:
|
27
|
+
#
|
28
|
+
# * Reads the trace context from the request headers, if present.
|
29
|
+
# Otherwise, generates a new trace context.
|
30
|
+
# * Makes a sampling decision if one is not already specified.
|
31
|
+
# * Records a span measuring the entire handling of the request,
|
32
|
+
# annotated with a set of standard request data.
|
33
|
+
# * Makes the trace context available so downstream middlewares and the
|
34
|
+
# app can add further spans to the trace.
|
35
|
+
# * Sends the completed trace to the Stackdriver service.
|
36
|
+
#
|
37
|
+
# ## Installing
|
38
|
+
#
|
39
|
+
# To use this middleware, simply install it in your middleware stack.
|
40
|
+
# Here is an example Sinatra application that includes the Trace
|
41
|
+
# middleware:
|
42
|
+
#
|
43
|
+
# ```ruby
|
44
|
+
# # Simple sinatra application
|
45
|
+
#
|
46
|
+
# require "sinatra"
|
47
|
+
# require "google/cloud/trace"
|
48
|
+
#
|
49
|
+
# use Google::Cloud::Trace::Middleware
|
50
|
+
#
|
51
|
+
# get "/" do
|
52
|
+
# "Hello World!"
|
53
|
+
# end
|
54
|
+
# ```
|
55
|
+
#
|
56
|
+
# Here is an example `config.ru` file for a web application that uses
|
57
|
+
# the standard Rack configuration mechanism.
|
58
|
+
#
|
59
|
+
# ```ruby
|
60
|
+
# # config.ru for simple Rack application
|
61
|
+
#
|
62
|
+
# require "google/cloud/trace"
|
63
|
+
# use Google::Cloud::Trace::Middleware
|
64
|
+
#
|
65
|
+
# run MyApp
|
66
|
+
# ```
|
67
|
+
#
|
68
|
+
# If your application uses Ruby On Rails, you may also use the provided
|
69
|
+
# {Google::Cloud::Trace::Railtie} for close integration with Rails and
|
70
|
+
# ActiveRecord.
|
71
|
+
#
|
72
|
+
# ## Custom measurements
|
73
|
+
#
|
74
|
+
# By default, this middleware creates traces that measure just the http
|
75
|
+
# request handling as a whole. If you want to provide more detailed
|
76
|
+
# measurements of smaller processes, use the classes provided in this
|
77
|
+
# library. Below is a Sinatra example to get you started.
|
78
|
+
#
|
79
|
+
# ```ruby
|
80
|
+
# # Simple sinatra application
|
81
|
+
#
|
82
|
+
# require "sinatra"
|
83
|
+
# require "google/cloud/trace"
|
84
|
+
#
|
85
|
+
# use Google::Cloud::Trace::Middleware
|
86
|
+
#
|
87
|
+
# get "/" do
|
88
|
+
# Google::Cloud::Trace.in_span "Sleeping on the job!" do
|
89
|
+
# sleep rand
|
90
|
+
# end
|
91
|
+
# "Hello World!"
|
92
|
+
# end
|
93
|
+
# ```
|
94
|
+
#
|
95
|
+
# ## Sampling and blacklisting
|
96
|
+
#
|
97
|
+
# A sampler makes the decision whether to record a trace for each
|
98
|
+
# request (if the decision was not made by the context, e.g. by providing
|
99
|
+
# a request header). By default, this sampler is the default
|
100
|
+
# {Google::Cloud::Trace::TimeSampler}, which enforces a maximum QPS per
|
101
|
+
# process, and blacklists a small number of request paths such as
|
102
|
+
# health checks sent by Google App Engine. You may adjust this behavior
|
103
|
+
# by providing an alternate sampler. See
|
104
|
+
# {Google::Cloud::Trace::TimeSampler}.
|
105
|
+
#
|
106
|
+
class Middleware
|
107
|
+
##
|
108
|
+
# The name of this trace agent as reported to the Stackdriver backend.
|
109
|
+
AGENT_NAME = "ruby #{Google::Cloud::Trace::VERSION}".freeze
|
110
|
+
|
111
|
+
##
|
112
|
+
# Create a new Middleware for traces
|
113
|
+
#
|
114
|
+
# @param [Rack Application] app Rack application
|
115
|
+
# @param [Google::Cloud::Trace::Service] service The service object.
|
116
|
+
# Optional if running on GCE.
|
117
|
+
# @param [Boolean] capture_stack Whether to capture stack traces for
|
118
|
+
# each span. Default is false.
|
119
|
+
# @param [Proc] sampler A sampler to use, or `nil` to use the default.
|
120
|
+
# See {Google::Cloud::Trace::TimeSampler}. Note that the sampler
|
121
|
+
# may be any Proc that implements the sampling contract.
|
122
|
+
#
|
123
|
+
def initialize app,
|
124
|
+
service: nil,
|
125
|
+
capture_stack: false,
|
126
|
+
sampler: nil,
|
127
|
+
span_id_generator: nil
|
128
|
+
@app = app
|
129
|
+
@capture_stack = capture_stack
|
130
|
+
@sampler = sampler
|
131
|
+
@span_id_generator = span_id_generator
|
132
|
+
if service
|
133
|
+
@service = service
|
134
|
+
else
|
135
|
+
project_id = Google::Cloud::Trace::Project.default_project
|
136
|
+
@service = Google::Cloud::Trace.new.service if project_id
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# Implementation of the trace middleware. Creates a trace for this
|
142
|
+
# request, populates it with a root span for the entire request, and
|
143
|
+
# ensures it is reported back to Stackdriver.
|
144
|
+
#
|
145
|
+
# @param [Hash] env Rack environment hash
|
146
|
+
# @return [Rack::Response] The response from downstream Rack app
|
147
|
+
#
|
148
|
+
def call env
|
149
|
+
trace = create_trace env
|
150
|
+
begin
|
151
|
+
Google::Cloud::Trace.set trace
|
152
|
+
Google::Cloud::Trace.in_span "rack-request" do |span|
|
153
|
+
configure_span span, env
|
154
|
+
result = @app.call env
|
155
|
+
configure_result span, result
|
156
|
+
result
|
157
|
+
end
|
158
|
+
ensure
|
159
|
+
Google::Cloud::Trace.set nil
|
160
|
+
send_trace trace, env
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
##
|
165
|
+
# Gets the current trace context from the given Rack environment.
|
166
|
+
# Makes a sampling decision if one has not been made already.
|
167
|
+
#
|
168
|
+
# @private
|
169
|
+
# @param [Hash] env Rack environment hash
|
170
|
+
# @return [Stackdriver::Core::TraceContext] The trace context.
|
171
|
+
#
|
172
|
+
def get_trace_context env
|
173
|
+
Stackdriver::Core::TraceContext.parse_rack_env(env) do |tc|
|
174
|
+
if tc.sampled?.nil?
|
175
|
+
sampler = @sampler || Google::Cloud::Trace::TimeSampler.default
|
176
|
+
sampled = sampler.call env
|
177
|
+
tc = Stackdriver::Core::TraceContext.new \
|
178
|
+
trace_id: tc.trace_id,
|
179
|
+
span_id: tc.span_id,
|
180
|
+
sampled: sampled,
|
181
|
+
capture_stack: sampled && @capture_stack
|
182
|
+
end
|
183
|
+
tc
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
##
|
188
|
+
# Create a new trace for this request.
|
189
|
+
#
|
190
|
+
# @private
|
191
|
+
# @param [Hash] env The Rack environment.
|
192
|
+
#
|
193
|
+
def create_trace env
|
194
|
+
trace_context = get_trace_context env
|
195
|
+
Google::Cloud::Trace::TraceRecord.new \
|
196
|
+
@service.project,
|
197
|
+
trace_context,
|
198
|
+
span_id_generator: @span_id_generator
|
199
|
+
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# Send the given trace to the trace service, if requested.
|
203
|
+
#
|
204
|
+
# @private
|
205
|
+
# @param [Google::Cloud::Trace::TraceRecord] trace The trace to send.
|
206
|
+
# @param [Hash] env The Rack environment.
|
207
|
+
#
|
208
|
+
def send_trace trace, env
|
209
|
+
if @service && trace.trace_context.sampled?
|
210
|
+
begin
|
211
|
+
@service.patch_traces trace
|
212
|
+
rescue => ex
|
213
|
+
msg = "Transmit to Stackdriver Trace failed: #{ex.inspect}"
|
214
|
+
logger = env["rack.logger"]
|
215
|
+
if logger
|
216
|
+
logger.error msg
|
217
|
+
else
|
218
|
+
warn msg
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
##
|
225
|
+
# Gets the URI path from the given Rack environment.
|
226
|
+
#
|
227
|
+
# @private
|
228
|
+
# @param [Hash] env Rack environment hash
|
229
|
+
# @return [String] The URI path.
|
230
|
+
#
|
231
|
+
def get_path env
|
232
|
+
path = "#{env['SCRIPT_NAME']}#{env['PATH_INFO']}"
|
233
|
+
path = "/#{path}" unless path.start_with? "/"
|
234
|
+
path
|
235
|
+
end
|
236
|
+
|
237
|
+
##
|
238
|
+
# Gets the URI hostname from the given Rack environment.
|
239
|
+
#
|
240
|
+
# @private
|
241
|
+
# @param [Hash] env Rack environment hash
|
242
|
+
# @return [String] The hostname.
|
243
|
+
#
|
244
|
+
def get_host env
|
245
|
+
env["HTTP_HOST"] || env["SERVER_NAME"]
|
246
|
+
end
|
247
|
+
|
248
|
+
##
|
249
|
+
# Gets the full URL from the given Rack environment.
|
250
|
+
#
|
251
|
+
# @private
|
252
|
+
# @param [Hash] env Rack environment hash
|
253
|
+
# @return [String] The URL.
|
254
|
+
#
|
255
|
+
def get_url env
|
256
|
+
path = get_path env
|
257
|
+
host = get_host env
|
258
|
+
scheme = env["rack.url_scheme"]
|
259
|
+
query_string = env["QUERY_STRING"].to_s
|
260
|
+
url = "#{scheme}://#{host}#{path}"
|
261
|
+
url = "#{url}?#{query_string}" unless query_string.empty?
|
262
|
+
url
|
263
|
+
end
|
264
|
+
|
265
|
+
##
|
266
|
+
# Configures the root span for this request. This may be called
|
267
|
+
# before the request is actually handled because it doesn't depend
|
268
|
+
# on the result.
|
269
|
+
#
|
270
|
+
# @private
|
271
|
+
# @param [Google::Cloud::Trace::TraceSpan] span The root span to
|
272
|
+
# configure.
|
273
|
+
# @param [Hash] env Rack environment hash
|
274
|
+
#
|
275
|
+
def configure_span span, env
|
276
|
+
span.name = get_path env
|
277
|
+
set_basic_labels span.labels, env
|
278
|
+
set_extended_labels span.labels,
|
279
|
+
span.trace.trace_context.capture_stack?
|
280
|
+
span
|
281
|
+
end
|
282
|
+
|
283
|
+
##
|
284
|
+
# Configures standard labels.
|
285
|
+
# @private
|
286
|
+
#
|
287
|
+
def set_basic_labels labels, env
|
288
|
+
set_label labels, Google::Cloud::Trace::LabelKey::AGENT, AGENT_NAME
|
289
|
+
set_label labels, Google::Cloud::Trace::LabelKey::HTTP_HOST,
|
290
|
+
get_host(env)
|
291
|
+
set_label labels, Google::Cloud::Trace::LabelKey::HTTP_METHOD,
|
292
|
+
env["REQUEST_METHOD"]
|
293
|
+
set_label labels,
|
294
|
+
Google::Cloud::Trace::LabelKey::HTTP_CLIENT_PROTOCOL,
|
295
|
+
env["SERVER_PROTOCOL"]
|
296
|
+
set_label labels, Google::Cloud::Trace::LabelKey::HTTP_USER_AGENT,
|
297
|
+
env["HTTP_USER_AGENT"]
|
298
|
+
set_label labels, Google::Cloud::Trace::LabelKey::HTTP_URL,
|
299
|
+
get_url(env)
|
300
|
+
set_label labels, Google::Cloud::Trace::LabelKey::PID,
|
301
|
+
::Process.pid.to_s
|
302
|
+
set_label labels, Google::Cloud::Trace::LabelKey::TID,
|
303
|
+
::Thread.current.object_id.to_s
|
304
|
+
end
|
305
|
+
|
306
|
+
##
|
307
|
+
# Configures stack and gae labels.
|
308
|
+
# @private
|
309
|
+
#
|
310
|
+
def set_extended_labels labels, capture_stack
|
311
|
+
if capture_stack
|
312
|
+
Google::Cloud::Trace::LabelKey.set_stack_trace labels,
|
313
|
+
skip_frames: 3
|
314
|
+
end
|
315
|
+
if Google::Cloud::Core::Environment.gae?
|
316
|
+
set_label labels, Google::Cloud::Trace::LabelKey::GAE_APP_MODULE,
|
317
|
+
Google::Cloud::Core::Environment.gae_module_id
|
318
|
+
set_label labels,
|
319
|
+
Google::Cloud::Trace::LabelKey::GAE_APP_MODULE_VERSION,
|
320
|
+
Google::Cloud::Core::Environment.gae_module_version
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
##
|
325
|
+
# Sets the given label if the given value is a proper string.
|
326
|
+
#
|
327
|
+
# @private
|
328
|
+
# @param [Hash] labels The labels hash.
|
329
|
+
# @param [String] key The key of the label to set.
|
330
|
+
# @param [Object] value The value to set.
|
331
|
+
#
|
332
|
+
def set_label labels, key, value
|
333
|
+
labels[key] = value if value.is_a? ::String
|
334
|
+
end
|
335
|
+
|
336
|
+
##
|
337
|
+
# Performs post-request tasks, including adding result-dependent
|
338
|
+
# labels to the root span, and adding trace context headers to the
|
339
|
+
# HTTP response.
|
340
|
+
#
|
341
|
+
# @private
|
342
|
+
# @param [Google::Cloud::Trace::TraceSpan] span The root span to
|
343
|
+
# configure.
|
344
|
+
# @param [Array] result The Rack response.
|
345
|
+
#
|
346
|
+
def configure_result span, result
|
347
|
+
if result.is_a?(::Array) && result.size == 3
|
348
|
+
span.labels[Google::Cloud::Trace::LabelKey::HTTP_STATUS_CODE] =
|
349
|
+
result[0].to_s
|
350
|
+
result[1]["X-Cloud-Trace-Context"] =
|
351
|
+
span.trace.trace_context.to_string
|
352
|
+
end
|
353
|
+
result
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|