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

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

Constant Summary collapse

DEFAULT_LOG_NAME =

The default log name used to instantiate the default logger if one isn't provided.

"ruby_app_log"
DEFAULT_LOG_NAME_MAP =

A default value for the log_name_map argument. Directs health check logs to a separate log name so they don't spam the main log.

{ "/_ah/health" => "ruby_health_check_log" }

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, logger: nil, project_id: nil, keyfile: nil, log_name_map: DEFAULT_LOG_NAME_MAP) ⇒ 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. If not specified, a default logger with be used.

  • project_id (String)

    Project identifier for the Stackdriver Logging service. Used to create a default logger if one isn't specified and a service account is used for authentication. Optional.

  • keyfile (String, Hash)

    Keyfile downloaded from Google Cloud. If file path the file must be readable. Used to create a default logger if one isn't specified and a service account is used for authentication. Optional.

  • log_name_map (Hash)

    A map from URI path to log name override. The path may be a string or regex. If a request path matches an entry in this map, the log name is set accordingly, otherwise the logger's default log_name is used.



61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/google/cloud/logging/middleware.rb', line 61

def initialize app, logger: nil, project_id: nil, keyfile: nil,
               log_name_map: DEFAULT_LOG_NAME_MAP
  @app = app
  if logger
    @logger = logger
  else
    logging = Google::Cloud::Logging.new project: project_id,
                                         keyfile: keyfile
    resource = Middleware.build_monitored_resource
    @logger = logging.logger DEFAULT_LOG_NAME, resource
  end
  @log_name_map = log_name_map
end

Instance Attribute Details

#loggerObject (readonly)

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



34
35
36
# File 'lib/google/cloud/logging/middleware.rb', line 34

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.

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:

See Also:



177
178
179
180
181
182
183
184
185
186
# File 'lib/google/cloud/logging/middleware.rb', line 177

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



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/google/cloud/logging/middleware.rb', line 86

def call env
  env["rack.logger"] = logger
  trace_id = get_trace_id env
  log_name = get_log_name env
  logger.add_request_info trace_id: trace_id, log_name: log_name
  begin
    @app.call env
  ensure
    logger.delete_request_info
  end
end