Class: Google::Cloud::Logging::Middleware

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, logger: nil) ⇒ Google::Cloud::Logging::Middleware

Create a new AppEngine logging Middleware.

Parameters:

  • app (Rack Application)

    Rack application

  • logger (Google::Cloud::Logging::Logger)

    A logger to be used by this middleware. The middleware will be interacting with the logger to track Stackdriver request trace ID. It also properly sets env["rack.logger"] to this assigned logger for accessing.



36
37
38
39
# File 'lib/google/cloud/logging/middleware.rb', line 36

def initialize app, logger: nil
  @app = app
  @logger = logger
end

Instance Attribute Details

#loggerObject (readonly)

The Google::Cloud::Logging::Logger instance



22
23
24
# File 'lib/google/cloud/logging/middleware.rb', line 22

def logger
  @logger
end

Class Method Details

.build_monitored_resource(type = nil, labels = nil) ⇒ Google::Cloud::Logging::Resource

Construct a monitored resource based on the given type and label if both are provided. Otherwise, construct a default monitored resource based on the current environment.

Reference https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/MonitoredResource for a full list of monitoring resources

Examples:

If both type and labels are provided, it returns resource:

rc = Google::Cloud::Logging::Middleware.build_monitored_resource(
       "aws_ec2_instance",
       {
         instance_id: "ec2-id",
         aws_account: "aws-id"
       }
     )
rc.type   #=> "aws_ec2_instance"
rc.labels #=> { instance_id: "ec2-id", aws_account: "aws-id" }

If running from GAE, returns default resource:

rc = Google::Cloud::Logging::Middleware.build_monitored_resource
rc.type   #=> "gae_app"
rc.labels # { module_id: [GAE module name],
          #   version_id: [GAE module version] }

If running from GKE, returns default resource:

rc = Google::Cloud::Logging::Middleware.build_monitored_resource
rc.type   #=> "container"
rc.labels # { cluster_name: [GKE cluster name],
          #   namespace_id: [GKE namespace_id] }

If running from GCE, return default resource:

rc = Google::Cloud::Logging::Middleware.build_monitored_resource
rc.type   #=> "gce_instance"
rc.labels # { instance_id: [GCE VM instance id],
          #   zone: [GCE vm group zone] }

Otherwise default to generic "global" type:

rc = Google::Cloud::Logging::Middleware.build_monitored_resource
rc.type   #=> "global"
rc.labels #=> {}

Parameters:

  • type (String) (defaults to: nil)

    Type of Google::Cloud::Logging::Resource

  • labels (Hash<String, String>) (defaults to: nil)

    Metadata lebels of Google::Cloud::Logging::Resource

Returns:



123
124
125
126
127
128
129
130
131
132
# File 'lib/google/cloud/logging/middleware.rb', line 123

def self.build_monitored_resource type = nil, labels = nil
  if type && labels
    Google::Cloud::Logging::Resource.new.tap do |r|
      r.type = type
      r.labels = labels
    end
  else
    default_monitored_resource
  end
end

Instance Method Details

#call(env) ⇒ Rack::Response

Rack middleware entry point. In most Rack based frameworks, a request is served by one thread. So entry point, we associate the GCP request trace_id with the current thread's object_id in logger. All the logs written by logger beyond this point will carry this request's trace_id. Untrack the trace_id with this thread upon exiting.

Parameters:

  • env (Hash)

    Rack environment hash

Returns:

  • (Rack::Response)

    The response from downstream Rack app



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/google/cloud/logging/middleware.rb', line 52

def call env
  env["rack.logger"] = logger
  trace_id = extract_trace_id(env)
  logger.add_trace_id trace_id

  begin
    @app.call env
  ensure
    logger.delete_trace_id
  end
end

#extract_trace_id(env) ⇒ String

Extract the trace_id from HTTP request header HTTP_X_CLOUD_TRACE_CONTEXT.

Returns:

  • (String)

    The trace_id or nil if trace_id is empty.



69
70
71
72
73
# File 'lib/google/cloud/logging/middleware.rb', line 69

def extract_trace_id env
  trace_context = env["HTTP_X_CLOUD_TRACE_CONTEXT"].to_s
  return nil if trace_context.empty?
  trace_context.sub(%r{/.*}, "")
end