class Google::Cloud::Logging::Railtie
Adds the {Google::Cloud::Logging::Middleware} to Rack in a Rails environment. The middleware will set `env` to a {Google::Cloud::Logging::Logger} instance to be used by the Rails application.
The middleware is loaded only when certain conditions are met. These conditions are when the configuration `Google::Cloud.configure.use_logging` (also available as `Rails.application.config.google_cloud.use_logging` for a Rails application) is set to `true`, or, if the configuration is left unset but `Rails.env.production?` is `true`.
When loaded, the {Google::Cloud::Logging::Middleware} will be inserted before the `Rails::Rack::Logger Middleware`, which allows it to set the `env` in place of Rails's default logger. See the [Configuration Guide](googleapis.dev/ruby/stackdriver/latest/file.INSTRUMENTATION_CONFIGURATION.html) on how to configure the Railtie
and Middleware
.
Public Class Methods
@private Consolidate Rails configuration into Logging
instrumentation configuration. Also consolidate the `use_logging` setting by verifying credentials and Rails environment. The `use_logging` setting will be true if credentials are valid, and the setting is manually set to true or Rails is in production environment.
@param [Rails::Railtie::Configuration] config The
Rails.application.config
# File lib/google/cloud/logging/rails.rb, line 138 def self.consolidate_rails_config config merge_rails_config config init_default_config # Done if Google::Cloud.configure.use_logging is explicitly false return if Google::Cloud.configure.use_logging == false # Verify credentials and set use_logging to false if # credentials are invalid unless valid_credentials? Logging.configure.project_id, Logging.configure.keyfile Cloud.configure.use_logging = false return end # Otherwise set use_logging to true if Rails is running in production Google::Cloud.configure.use_logging ||= Rails.env.production? end
@private Init Logging
integration for Rails. Setup configuration and insert the Middleware
.
# File lib/google/cloud/logging/rails.rb, line 65 def self.init_middleware app project_id = Logging.configure.project_id credentials = Logging.configure.credentials resource_type = Logging.configure.monitored_resource.type resource_labels = Logging.configure.monitored_resource.labels log_name = Logging.configure.log_name labels = Logging.configure.labels logging = Google::Cloud::Logging.new project_id: project_id, credentials: credentials resource = Logging::Middleware.build_monitored_resource resource_type, resource_labels Middleware.logger = logging.logger log_name, resource, labels # Set the default Rails logger if Logging.configure.set_default_logger_on_rails_init set_default_logger end init_callback = -> { set_default_logger } app.middleware.insert_before Rails::Rack::Logger, Google::Cloud::Logging::Middleware, logger: Middleware.logger, on_init: init_callback end
This should be called once the application determines that it is safe to start background threads and open gRPC connections. It informs the middleware system that it is safe to use Google
Cloud
Logging
. This is called during Rails initialization when the `set_default_logger_on_rails_init` configuration is set.
Generally, this matters if the application forks worker processes; this method should be called only after workers are forked, since threads and network connections interact badly with fork. For example, when running Puma in [clustered mode](github.com/puma/puma#clustered-mode), this method should be called in an `on_worker_boot` block.
If the application does no forking, this method can be called any time early in the application initialization process. Or by setting the `set_default_logger_on_rails_init` configuration.
If the `set_default_logger_on_rails_init` configuration is not set, and {Railtie.set_default_logger} is not called in a post-fork hook, the default Rails logger object will not be set to use the Google
Cloud
Logging
Logger
object. For best results, an application should call this method at the appropriate time, such as a post-fork hook.
# File lib/google/cloud/logging/rails.rb, line 115 def self.set_default_logger return if Middleware.logger.nil? return if Rails.logger.is_a? Google::Cloud::Logging::Logger # configure the Middleware logger to use the same settings as Rails Middleware.logger.level = Rails.logger.level # TODO: are there more settings to be set here? # Replace the Rails default logger Rails.application.config.logger = Middleware.logger Rails.logger = Middleware.logger end
Private Class Methods
Fallback to default config values if config parameters not provided.
# File lib/google/cloud/logging/rails.rb, line 188 def self.init_default_config Logging.configure.project_id ||= Logging.default_project_id Logging.configure.log_name ||= Middleware::DEFAULT_LOG_NAME end
@private Merge Rails configuration into Logging
instrumentation configuration.
# File lib/google/cloud/logging/rails.rb, line 161 def self.merge_rails_config rails_config gcp_config = rails_config.google_cloud log_config = gcp_config.logging if Cloud.configure.use_logging.nil? Cloud.configure.use_logging = gcp_config.use_logging end Logging.configure do |config| config.project_id ||= config.project config.project_id ||= log_config.project_id || log_config.project config.project_id ||= gcp_config.project_id || gcp_config.project config.credentials ||= config.keyfile config.credentials ||= log_config.credentials || log_config.keyfile config.credentials ||= gcp_config.credentials || gcp_config.keyfile config.log_name ||= log_config.log_name config.labels ||= log_config.labels config.log_name_map ||= log_config.log_name_map config.monitored_resource.type ||= log_config.monitored_resource.type config.monitored_resource.labels ||= log_config.monitored_resource.labels.to_h if config.set_default_logger_on_rails_init.nil? config.set_default_logger_on_rails_init = log_config.set_default_logger_on_rails_init end end end
@private Verify credentials
# File lib/google/cloud/logging/rails.rb, line 195 def self.valid_credentials? project_id, credentials # Try authenticate authorize client API. Return false if unable to # authorize. begin # if credentials is nil, get default credentials ||= Logging::Credentials.default # only create a new Credentials object if the val isn't one already unless credentials.is_a? Google::Auth::Credentials # if credentials is not a Credentials object, create one Logging::Credentials.new credentials end rescue Exception => e # rubocop:disable Lint/RescueException $stdout.puts "Note: Google::Cloud::Logging is disabled because " \ "it failed to authorize with the service. (#{e.message}) " \ "Falling back to the default Rails logger." return false end if project_id.to_s.empty? $stdout.puts "Note: Google::Cloud::Logging is disabled because " \ "the project ID could not be determined. " \ "Falling back to the default Rails logger." return false end true end