Environment details
- OS: macOS Tahoe
- Ruby version: ruby 3.4.8
- Gem name and version: google-cloud-pubsub version 3.2.0
Description:
The Google::Cloud::PubSub::Service class accepts a logger: parameter in its constructor and stores it in @logger, but does not pass this logger to the underlying v1 API clients (TopicAdmin::Client and SubscriptionAdmin::Client) when they are initialized.
Expected behavior:
The logger passed to PubSub.new should be propagated to the underlying v1 API clients so that all SDK logging respects the same logger configuration.
Steps to reproduce
- When creating a PubSub client with a custom logger:
rubyclient = Google::Cloud::PubSub.new(
project_id: "my-project",
logger: Rails.logger # Custom logger at >=INFO level
)
- Publish binary data PubSub.client.publisher(binary_data) and monitor the log.
- Observe warning as below:
JSON.generate: UTF-8 string passed as BINARY, this will raise an encoding error in json 3.0
/usr/local/bundle/gems/json-2.18.1/lib/json/common.rb:443:in 'JSON::Ext::Generator::State.generate'
/usr/local/bundle/gems/json-2.18.1/lib/json/common.rb:443:in 'JSON.generate'
/usr/local/bundle/gems/google-logging-utils-0.2.0/lib/google/logging/message.rb:264:in 'Google::Logging::Message#interpret_message'
/usr/local/bundle/gems/google-logging-utils-0.2.0/lib/google/logging/message.rb:108:in 'Google::Logging::Message#initialize'
/usr/local/bundle/gems/google-logging-utils-0.2.0/lib/google/logging/message.rb:67:in 'Class#new'
/usr/local/bundle/gems/google-logging-utils-0.2.0/lib/google/logging/message.rb:67:in 'Google::Logging::Message.from'
/usr/local/bundle/gems/gapic-common-1.2.0/lib/gapic/logging_concerns.rb:132:in 'Gapic::LoggingConcerns::StubLogger::LogEntryBuilder#build'
/usr/local/bundle/gems/gapic-common-1.2.0/lib/gapic/logging_concerns.rb:56:in 'block in Gapic::LoggingConcerns::StubLogger#log'
/usr/local/bundle/gems/logger-1.7.0/lib/logger.rb:685:in 'Logger#add'
/usr/local/bundle/gems/gapic-common-1.2.0/lib/gapic/logging_concerns.rb:52:in 'Gapic::LoggingConcerns::StubLogger#log'
/usr/local/bundle/gems/gapic-common-1.2.0/lib/gapic/logging_concerns.rb:67:in 'Gapic::LoggingConcerns::StubLogger#debug'
/usr/local/bundle/gems/gapic-common-1.2.0/lib/gapic/grpc/service_stub/rpc_call.rb:213:in 'Gapic::ServiceStub::RpcCall#log_single_request'
/usr/local/bundle/gems/gapic-common-1.2.0/lib/gapic/grpc/service_stub/rpc_call.rb:206:in 'Gapic::ServiceStub::RpcCall#log_request'
/usr/local/bundle/gems/gapic-common-1.2.0/lib/gapic/grpc/service_stub/rpc_call.rb:128:in 'Gapic::ServiceStub::RpcCall#call'
/usr/local/bundle/gems/gapic-common-1.2.0/lib/gapic/grpc/service_stub.rb:217:in 'Gapic::ServiceStub#call_rpc'
/usr/local/bundle/gems/google-cloud-pubsub-v1-1.14.2/lib/google/cloud/pubsub/v1/topic_admin/client.rb:550:in 'Google::Cloud::PubSub::TopicAdmin::Client#publish'
/usr/local/bundle/gems/google-cloud-pubsub-3.2.0/lib/google/cloud/pubsub/service.rb:128:in 'Google::Cloud::PubSub::Service#publish'
The logger is stored in the Service object but is not passed to the v1 clients. As a result, the v1 clients use the default :default logger configuration, which creates a DEBUG-level logger that triggered log_single_request unexpectedly.
Source code evidence:
In lib/google/cloud/pubsub/service.rb:
def topic_admin
return mocked_topic_admin if mocked_topic_admin
@topic_admin ||= TopicAdmin::Client.new do |config|
config.credentials = credentials if credentials
override_client_config_timeouts config if timeout
config.endpoint = host if host
config.universe_domain = universe_domain
config.lib_name = "gccl"
config.lib_version = Google::Cloud::PubSub::VERSION
config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
# Missing: config.logger = @logger
end
end
The same issue exists in the subscription_admin method.
Work Around
Currently, we are able to bypass the bug by configuring the v1 clients directly via global configuration:
# config/initializers/google_cloud.rb
require "google/cloud/pubsub/v1"
custom_logger = Logger.new($stdout)
custom_logger.level = Logger::INFO
custom_logger.progname = "google-cloud-pubsub"
Google::Cloud::PubSub::V1::TopicAdmin::Client.configure do |config|
config.logger = custom_logger
end
Google::Cloud::PubSub::V1::SubscriptionAdmin::Client.configure do |config|
config.logger = custom_logger
end
Proposed Fix
The topic_admin and subscription_admin methods should pass the logger to the client configuration:
def topic_admin
return mocked_topic_admin if mocked_topic_admin
@topic_admin ||= TopicAdmin::Client.new do |config|
config.credentials = credentials if credentials
override_client_config_timeouts config if timeout
config.endpoint = host if host
config.universe_domain = universe_domain
config.lib_name = "gccl"
config.lib_version = Google::Cloud::PubSub::VERSION
config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
config.logger = @logger if @logger # ← Add this line
end
end
Environment details
Description:
The Google::Cloud::PubSub::Service class accepts a logger: parameter in its constructor and stores it in @logger, but does not pass this logger to the underlying v1 API clients (TopicAdmin::Client and SubscriptionAdmin::Client) when they are initialized.
Expected behavior:
The logger passed to PubSub.new should be propagated to the underlying v1 API clients so that all SDK logging respects the same logger configuration.
Steps to reproduce
The logger is stored in the Service object but is not passed to the v1 clients. As a result, the v1 clients use the default :default logger configuration, which creates a DEBUG-level logger that triggered log_single_request unexpectedly.
Source code evidence:
In lib/google/cloud/pubsub/service.rb:
The same issue exists in the subscription_admin method.
Work Around
Currently, we are able to bypass the bug by configuring the v1 clients directly via global configuration:
Proposed Fix
The topic_admin and subscription_admin methods should pass the logger to the client configuration: