Class: Google::Cloud::Trace::Middleware

Inherits:
Object
  • Object
show all
Defined in:
lib/google/cloud/trace/middleware.rb

Overview

Trace Middleware

A Rack middleware that manages trace context and captures a trace of the request. Specifically, it:

  • Reads the trace context from the request headers, if present. Otherwise, generates a new trace context.
  • Makes a sampling decision if one is not already specified.
  • Records a span measuring the entire handling of the request, annotated with a set of standard request data.
  • Makes the trace context available so downstream middlewares and the app can add further spans to the trace.
  • Sends the completed trace to the Stackdriver service.

Installing

To use this middleware, simply install it in your middleware stack. Here is an example Sinatra application that includes the Trace middleware:

# Simple sinatra application

require "sinatra"
require "google/cloud/trace"

use Google::Cloud::Trace::Middleware

get "/" do
  "Hello World!"
end

Here is an example config.ru file for a web application that uses the standard Rack configuration mechanism.

# config.ru for simple Rack application

require "google/cloud/trace"
use Google::Cloud::Trace::Middleware

run MyApp

If your application uses Ruby On Rails, you may also use the provided Railtie for close integration with Rails and ActiveRecord.

Custom measurements

By default, this middleware creates traces that measure just the http request handling as a whole. If you want to provide more detailed measurements of smaller processes, use the classes provided in this library. Below is a Sinatra example to get you started.

# Simple sinatra application

require "sinatra"
require "google/cloud/trace"

use Google::Cloud::Trace::Middleware

get "/" do
  Google::Cloud::Trace.in_span "Sleeping on the job!" do
    sleep rand
  end
  "Hello World!"
end

Error handling

An error encountered during the reporting of traces by the middleware can be handled using a Proc set in the on_error configuration. (See configure.) The Proc must take the error object as the single argument.

# Configure error handling

require "sinatra"
require "google/cloud/trace"
require "google/cloud/error_reporting"

Google::Cloud::Trace.configure do |config|
  config.on_error = lambda do |error|
    Google::Cloud::ErrorReporting.report error
  end
end

use Google::Cloud::Trace::Middleware

get "/" do
  Google::Cloud::Trace.in_span "Sleeping on the job!" do
    sleep rand
  end
  "Hello World!"
end

Sampling and blacklisting

A sampler makes the decision whether to record a trace for each request (if the decision was not made by the context, e.g. by providing a request header). By default, this sampler is the default TimeSampler, which enforces a maximum QPS per process, and blacklists a small number of request paths such as health checks sent by Google App Engine. You may adjust this behavior by providing an alternate sampler. See TimeSampler.

Constant Summary collapse

AGENT_NAME =

The name of this trace agent as reported to the Stackdriver backend.

"ruby #{Google::Cloud::Trace::VERSION}".freeze

Instance Method Summary collapse

Constructor Details

#initialize(app, service: nil, **kwargs) ⇒ Middleware

Create a new Middleware for traces

Parameters:

  • app (Rack Application)

    Rack application

  • service (Google::Cloud::Trace::Service, AsyncReporter) (defaults to: nil)

    The service object to update traces. Optional if running on GCE.

  • kwargs (Hash)

    Hash of configuration settings. Used for backward API compatibility. See the Instrumentation Guide and Configuration Guide for the prefered way to set configuration parameters.



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/google/cloud/trace/middleware.rb', line 154

def initialize app, service: nil, **kwargs
  @app = app

  load_config(**kwargs)

  if service
    @service = service
  else
    project_id = configuration.project_id

    if project_id
      credentials = configuration.credentials
      tracer = Google::Cloud::Trace.new project_id: project_id,
                                        credentials: credentials
      @service = Google::Cloud::Trace::AsyncReporter.new tracer.service
    end
  end
end

Instance Method Details

#call(env) ⇒ Rack::Response

Implementation of the trace middleware. Creates a trace for this request, populates it with a root span for the entire request, and ensures it is reported back to Stackdriver.

Parameters:

  • env (Hash)

    Rack environment hash

Returns:

  • (Rack::Response)

    The response from downstream Rack app



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/google/cloud/trace/middleware.rb', line 181

def call env
  trace = create_trace env
  begin
    Google::Cloud::Trace.set trace
    Google::Cloud::Trace.in_span "rack-request" do |span|
      configure_span span, env
      result = @app.call env
      configure_result span, result
      result
    end
  ensure
    Google::Cloud::Trace.set nil
    send_trace trace, env
  end
end