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,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
|