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".freeze
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",
"/healthz"    => "ruby_health_check_log" }.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

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

Create a new AppEngine logging Middleware.

Parameters:

  • app (Rack Application)

    Rack application

  • logger (Google::Cloud::Logging::Logger) (defaults to: nil)

    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.

  • on_init (Proc) (defaults to: nil)

    A callback to be invoked when the middleware is initialized. The callback takes no arguments. Optional.

  • kwargs (Hash)

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



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/google/cloud/logging/middleware.rb', line 57

def initialize app, logger: nil, on_init: nil, **kwargs
  @app = app

  load_config(**kwargs)

  logger ||= Middleware.logger
  logger ||= begin
    log_name = configuration.log_name
    logging = Logging.new project_id:  configuration.project_id,
                          credentials: configuration.credentials
    resource = Middleware.build_monitored_resource(
      configuration.monitored_resource.type,
      configuration.monitored_resource.labels
    )
    Middleware.logger = logging.logger log_name, resource
  end

  on_init&.call

  @logger = logger
end

Instance Attribute Details

#loggerObject (readonly)

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



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

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:



183
184
185
186
187
188
189
190
191
192
# File 'lib/google/cloud/logging/middleware.rb', line 183

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



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/google/cloud/logging/middleware.rb', line 90

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,
                          env: env
  begin
    @app.call env
  ensure
    logger.delete_request_info
  end
end