Skip to content

Commit

Permalink
feat(gapic): Support request-response debug logging from generated GA…
Browse files Browse the repository at this point in the history
…PICs (#1113)
  • Loading branch information
dazuma authored Dec 6, 2024
1 parent 79077d5 commit 39d9795
Show file tree
Hide file tree
Showing 218 changed files with 4,491 additions and 2,013 deletions.
2 changes: 1 addition & 1 deletion gapic-generator-ads/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,4 @@ DEPENDENCIES
yard (~> 0.9)

BUNDLED WITH
2.4.19
2.5.16
2 changes: 1 addition & 1 deletion gapic-generator-cloud/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,4 @@ DEPENDENCIES
yard (~> 0.9)

BUNDLED WITH
2.4.19
2.5.16
53 changes: 33 additions & 20 deletions gapic-generator-cloud/templates/cloud/gem/readme.erb
Original file line number Diff line number Diff line change
Expand Up @@ -69,33 +69,46 @@ See also the [Product Documentation](<%= gem.product_documentation_url %>)
for general usage information.

<%- end -%>
<%- if gem.show_grpc_logging_docs? -%>
## Enabling Logging
<%- if gem.show_logging_docs? -%>
## Debug Logging

This library comes with opt-in Debug Logging that can help you troubleshoot
your application's integration with the API. When logging is activated, key
events such as requests and responses, along with data payloads and metadata
such as headers and client configuration, are logged to the standard error
stream.

**WARNING:** Client Library Debug Logging includes your data payloads in
plaintext, which could include sensitive data such as PII for yourself or your
customers, private keys, or other security data that could be compromising if
leaked. Always practice good data hygiene with your application logs, and follow
the principle of least access. Google also recommends that Client Library Debug
Logging be enabled only temporarily during active debugging, and not used
permanently in production.

To enable logging, set the environment variable `GOOGLE_SDK_RUBY_LOGGING_GEMS`
to the value `all`. Alternatively, you can set the value to a comma-delimited
list of client library gem names. This will select the default logging behavior,
which writes logs to the standard error stream. On a local workstation, this may
result in logs appearing on the console. When running on a Google Cloud hosting
service such as [Google Cloud Run](https://cloud.google.com/run), this generally
results in logs appearing alongside your application logs in the
[Google Cloud Logging](https://cloud.google.com/logging/) service.

To enable logging for this library, set the logger for the underlying [gRPC](https://github.com/grpc/grpc/tree/master/src/ruby) library.
The logger that you set may be a Ruby stdlib [`Logger`](https://ruby-doc.org/current/stdlibs/logger/Logger.html) as shown below,
or a [`Google::Cloud::Logging::Logger`](https://cloud.google.com/ruby/docs/reference/google-cloud-logging/latest)
that will write logs to [Cloud Logging](https://cloud.google.com/logging/). See [grpc/logconfig.rb](https://github.com/grpc/grpc/blob/master/src/ruby/lib/grpc/logconfig.rb)
and the gRPC [spec_helper.rb](https://github.com/grpc/grpc/blob/master/src/ruby/spec/spec_helper.rb) for additional information.

Configuring a Ruby stdlib logger:
<%- service = gem.quick_start_service.usable_service_presenter -%>
<%- if service -%>
You can customize logging by modifying the `logger` configuration when
constructing a client object. For example:

```ruby
require "<%= gem.entrypoint_require %>"
require "logger"

module MyLogger
LOGGER = Logger.new $stderr, level: Logger::WARN
def logger
LOGGER
end
end

# Define a gRPC module-level logger method before grpc/logconfig.rb loads.
module GRPC
extend MyLogger
client = <%= service.create_client_call %> do |config|
config.logger = Logger.new "my-app.log"
end
```

<%- end -%>
<%- end -%>

## Google Cloud Samples
Expand Down
51 changes: 24 additions & 27 deletions gapic-generator-cloud/templates/cloud/wrapper_gem/readme.erb
Original file line number Diff line number Diff line change
Expand Up @@ -63,34 +63,31 @@ versions of this library will likely require updates to use this version.
See the {file:MIGRATING.md MIGRATING.md} document for more information.

<%- end -%>
<%- unless gem.generate_rest_clients? -%>
## Enabling Logging

To enable logging for this library, set the logger for the underlying [gRPC](https://github.com/grpc/grpc/tree/master/src/ruby) library.
The logger that you set may be a Ruby stdlib [`Logger`](https://ruby-doc.org/current/stdlibs/logger/Logger.html) as shown below,
or a [`Google::Cloud::Logging::Logger`](https://cloud.google.com/ruby/docs/reference/google-cloud-logging/latest)
that will write logs to [Cloud Logging](https://cloud.google.com/logging/). See [grpc/logconfig.rb](https://github.com/grpc/grpc/blob/master/src/ruby/lib/grpc/logconfig.rb)
and the gRPC [spec_helper.rb](https://github.com/grpc/grpc/blob/master/src/ruby/spec/spec_helper.rb) for additional information.

Configuring a Ruby stdlib logger:

```ruby
require "logger"

module MyLogger
LOGGER = Logger.new $stderr, level: Logger::WARN
def logger
LOGGER
end
end

# Define a gRPC module-level logger method before grpc/logconfig.rb loads.
module GRPC
extend MyLogger
end
```
## Debug Logging

This library comes with opt-in Debug Logging that can help you troubleshoot
your application's integration with the API. When logging is activated, key
events such as requests and responses, along with data payloads and metadata
such as headers and client configuration, are logged to the standard error
stream.

**WARNING:** Client Library Debug Logging includes your data payloads in
plaintext, which could include sensitive data such as PII for yourself or your
customers, private keys, or other security data that could be compromising if
leaked. Always practice good data hygiene with your application logs, and follow
the principle of least access. Google also recommends that Client Library Debug
Logging be enabled only temporarily during active debugging, and not used
permanently in production.

To enable logging, set the environment variable `GOOGLE_SDK_RUBY_LOGGING_GEMS`
to the value `all`. Alternatively, you can set the value to a comma-delimited
list of client library gem names. This will select the default logging behavior,
which writes logs to the standard error stream. On a local workstation, this may
result in logs appearing on the console. When running on a Google Cloud hosting
service such as [Google Cloud Run](https://cloud.google.com/run), this generally
results in logs appearing alongside your application logs in the
[Google Cloud Logging](https://cloud.google.com/logging/) service.

<%- end -%>
## Supported Ruby Versions

This library is supported on Ruby 2.7+.
Expand Down
2 changes: 1 addition & 1 deletion gapic-generator/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,4 @@ DEPENDENCIES
yard (~> 0.9)

BUNDLED WITH
2.4.19
2.5.16
11 changes: 5 additions & 6 deletions gapic-generator/lib/gapic/presenters/gem_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def extra_files

def dependencies
@dependencies ||= begin
deps = { "gapic-common" => [">= 0.21.1", "< 2.a"] }
deps = { "gapic-common" => [">= 0.24.0", "< 2.a"] }
deps["grpc-google-iam-v1"] = "~> 1.1" if iam_dependency?
extra_deps = gem_config_dependencies
deps.merge! mixins_model.dependencies if mixins_model.mixins?
Expand Down Expand Up @@ -309,14 +309,13 @@ def quick_start_service
end

##
# Whether the "Enabling (gRPC) Logging" section of the readme should
# appear. This is true if there is a quick-start service displayed in the
# readme, AND it uses gRPC.
# Whether the "Enabling Logging" section of the readme should appear.
# This is true if there is a quick-start service displayed in the readme.
#
# @return [Boolean]
#
def show_grpc_logging_docs?
packages? && quick_start_service.usable_service_presenter.is_a?(ServicePresenter)
def show_logging_docs?
packages? && !quick_start_service.usable_service_presenter.nil?
end

##
Expand Down
23 changes: 22 additions & 1 deletion gapic-generator/templates/default/service/client/_client.erb
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,27 @@ class <%= service.client_name %>
universe_domain: @config.universe_domain,
channel_args: @config.channel_args,
interceptors: @config.interceptors,
channel_pool_config: @config.channel_pool
channel_pool_config: @config.channel_pool,
logger: @config.logger
)

@<%= service.stub_name %>.stub_logger&.info do |entry|
entry.set_system_name
entry.set_service
entry.message = "Created client for #{entry.service}"
entry.set_credentials_fields credentials
entry.set "customEndpoint", @config.endpoint if @config.endpoint
entry.set "defaultTimeout", @config.timeout if @config.timeout
entry.set "quotaProject", @quota_project_id if @quota_project_id
end
<%- service.mixin_presenters.each do |subclient| -%>

@<%= subclient.client_var_name %> = <%= subclient.client_class_name %>.new do |config|
config.credentials = credentials
config.quota_project = @quota_project_id
config.endpoint = @<%= service.stub_name %>.endpoint
config.universe_domain = @<%= service.stub_name %>.universe_domain
config.logger = @<%= service.stub_name %>.logger if config.respond_to? :logger=
end
<%- end -%>
end
Expand All @@ -173,6 +185,15 @@ class <%= service.client_name %>

<%- end -%>
<%- end -%>
##
# The logger used for request/response debug logging.
#
# @return [Logger]
#
def logger
@<%= service.stub_name %>.logger
end

# Service calls
<%- service.methods.each do |method| -%>

Expand Down
6 changes: 6 additions & 0 deletions gapic-generator/templates/default/service/client/_config.erb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@
# default endpoint URL. The default value of nil uses the environment
# universe (usually the default "googleapis.com" universe).
# @return [::String,nil]
# @!attribute [rw] logger
# A custom logger to use for request/response debug logging, or the value
# `:default` (the default) to construct a default logger, or `nil` to
# explicitly disable logging.
# @return [::Logger,:default,nil]
#
class Configuration
extend ::Gapic::Config
Expand All @@ -109,6 +114,7 @@ class Configuration
config_attr :retry_policy, nil, ::Hash, ::Proc, nil
config_attr :quota_project, nil, ::String, nil
config_attr :universe_domain, nil, ::String, nil
config_attr :logger, :default, ::Logger, nil, :default

# @private
def initialize parent_config = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
<%= render partial: "service/client/method/def/response_paged", locals: { method: method } -%>
<%- elsif method.rest.nonstandard_lro? -%>
<%= render partial: "service/client/method/def/response_nonstandard_lro", locals: { method: method } -%>
<%- elsif method.lro? -%>
<%= render partial: "service/client/method/def/response_normal_lro", locals: { method: method } -%>
<%- else -%>
<%= render partial: "service/client/method/def/response_normal", locals: { method: method } -%>
<%- end -%>
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
options: options
)
yield result, response if block_given?
return result
throw :response, result
end
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
<%- assert_locals method -%>
@<%= method.service.stub_name %>.call_rpc :<%= method.name %>, request, options: options do |response, operation|
<%- if method.lro? -%>
response = ::Gapic::Operation.new response, <%= method.service.lro_client_ivar %>, options: options
<%- end -%>
yield response, operation if block_given?
return response
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<%- assert_locals method -%>
@<%= method.service.stub_name %>.call_rpc :<%= method.name %>, request, options: options do |response, operation|
response = ::Gapic::Operation.new response, <%= method.service.lro_client_ivar %>, options: options
yield response, operation if block_given?
throw :response, response
end
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
<%- end -%>
response = ::Gapic::PagedEnumerable.new @<%= method.service.stub_name %>, :<%= method.name %>, request, response, operation, options<%- if method.lro? -%>, format_resource: wrap_lro_operation<%- end -%>
yield response, operation if block_given?
return response
throw :response, response
end
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,19 @@ class <%= service.rest.client_name %>
endpoint: @config.endpoint,
endpoint_template: DEFAULT_ENDPOINT_TEMPLATE,
universe_domain: @config.universe_domain,
credentials: credentials
credentials: credentials,
logger: @config.logger
)

@<%= service.stub_name %>.logger(stub: true)&.info do |entry|
entry.set_system_name
entry.set_service
entry.message = "Created client for #{entry.service}"
entry.set_credentials_fields credentials
entry.set "customEndpoint", @config.endpoint if @config.endpoint
entry.set "defaultTimeout", @config.timeout if @config.timeout
entry.set "quotaProject", @quota_project_id if @quota_project_id
end
<%- service.rest.mixin_presenters.each do |subclient| -%>

@<%= subclient.client_var_name %> = <%= subclient.client_class_docname %>.new do |config|
Expand All @@ -156,6 +167,7 @@ class <%= service.rest.client_name %>
<%- if subclient.respond_to?(:bindings_override) && !subclient.bindings_override.empty? -%>
config.bindings_override = @config.bindings_override
<%- end -%>
config.logger = @<%= service.stub_name %>.logger if config.respond_to? :logger=
end
<%- end -%>
end
Expand All @@ -171,6 +183,15 @@ class <%= service.rest.client_name %>

<%- end -%>
<%- end -%>
##
# The logger used for request/response debug logging.
#
# @return [Logger]
#
def logger
@<%= service.stub_name %>.logger
end

# Service calls
<%- service.rest.methods.each do |method| -%>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@
# default endpoint URL. The default value of nil uses the environment
# universe (usually the default "googleapis.com" universe).
# @return [::String,nil]
# @!attribute [rw] logger
# A custom logger to use for request/response debug logging, or the value
# `:default` (the default) to construct a default logger, or `nil` to
# explicitly disable logging.
# @return [::Logger,:default,nil]
#
class Configuration
extend ::Gapic::Config
Expand Down Expand Up @@ -106,6 +111,7 @@ class Configuration
# @return [::Hash{::Symbol=>::Array<::Gapic::Rest::GrpcTranscoder::HttpBinding>}]
config_attr :bindings_override, {}, ::Hash, nil
<%- end -%>
config_attr :logger, :default, ::Logger, nil, :default

# @private
def initialize parent_config = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
<%= render partial: "service/rest/client/method/def/response_nonstandard_lro", locals: { method: method } -%>
<%- elsif method.rest.server_streaming? -%>
<%= render partial: "service/rest/client/method/def/response_server_streaming", locals: { method: method } -%>
<%- elsif method.lro? -%>
<%= render partial: "service/rest/client/method/def/response_normal_lro", locals: { method: method } -%>
<%- else -%>
<%= render partial: "service/rest/client/method/def/response_normal", locals: { method: method } -%>
<%- end -%>
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
options: options
)
yield result, response if block_given?
return result
result
end
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
<%- assert_locals method -%>
<%- boverr_str = method.service.rest.is_main_mixin_service? ? ", bindings_override: bindings_override" : "" -%>
@<%= method.service.stub_name %>.<%= method.name %> request, options<%= boverr_str %> do |result, operation|
<%- if method.lro? -%>
result = ::Gapic::Operation.new result, <%= method.service.lro_client_ivar %>, options: options
<%- end -%>
yield result, operation if block_given?
return result
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<%- assert_locals method -%>
<%- boverr_str = method.service.rest.is_main_mixin_service? ? ", bindings_override: bindings_override" : "" -%>
@<%= method.service.stub_name %>.<%= method.name %> request, options<%= boverr_str %> do |result, operation|
result = ::Gapic::Operation.new result, <%= method.service.lro_client_ivar %>, options: options
yield result, operation if block_given?
throw :response, result
end
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
@<%= method.service.stub_name %>.<%= method.name %> request, options<%= boverr_str %> do |result, operation|
result = ::Gapic::Rest::PagedEnumerable.new @<%= method.service.stub_name %>, :<%= method.name %>, "<%= method.rest.pagination.response_repeated_field_name %>", request, result, options
yield result, operation if block_given?
return result
throw :response, result
end
Loading

0 comments on commit 39d9795

Please sign in to comment.