Skip to content

Commit

Permalink
feat: Add support for opt-in debug logging (#323)
Browse files Browse the repository at this point in the history
* feat: Add support for opt-in debug logging
fix: Fix typing issue with gRPC metadata when key ends in -bin
chore: Update gapic-generator-python to v1.21.0

PiperOrigin-RevId: 705285820

Source-Link: googleapis/googleapis@f9b8b91

Source-Link: googleapis/googleapis-gen@ca1e0a1
Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiY2ExZTBhMWU0NzJkNmU2ZjVkZTg4M2E1Y2I1NDcyNGYxMTJjZTM0OCJ9

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

---------

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
  • Loading branch information
gcf-owl-bot[bot] and gcf-owl-bot[bot] authored Dec 27, 2024
1 parent ca4848a commit c896824
Show file tree
Hide file tree
Showing 8 changed files with 1,171 additions and 203 deletions.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def __init__(
*,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
metadata: Sequence[Tuple[str, str]] = ()
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiate the pager.
Expand All @@ -81,8 +81,10 @@ def __init__(
retry (google.api_core.retry.Retry): Designation of what errors,
if any, should be retried.
timeout (float): The timeout for this request.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
sent along with the request as metadata. Normally, each value must be of type `str`,
but for metadata keys ending with the suffix `-bin`, the corresponding values must
be of type `bytes`.
"""
self._method = method
self._request = orgpolicy.ListConstraintsRequest(request)
Expand Down Expand Up @@ -141,7 +143,7 @@ def __init__(
*,
retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
metadata: Sequence[Tuple[str, str]] = ()
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiates the pager.
Expand All @@ -155,8 +157,10 @@ def __init__(
retry (google.api_core.retry.AsyncRetry): Designation of what errors,
if any, should be retried.
timeout (float): The timeout for this request.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
sent along with the request as metadata. Normally, each value must be of type `str`,
but for metadata keys ending with the suffix `-bin`, the corresponding values must
be of type `bytes`.
"""
self._method = method
self._request = orgpolicy.ListConstraintsRequest(request)
Expand Down Expand Up @@ -219,7 +223,7 @@ def __init__(
*,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
metadata: Sequence[Tuple[str, str]] = ()
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiate the pager.
Expand All @@ -233,8 +237,10 @@ def __init__(
retry (google.api_core.retry.Retry): Designation of what errors,
if any, should be retried.
timeout (float): The timeout for this request.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
sent along with the request as metadata. Normally, each value must be of type `str`,
but for metadata keys ending with the suffix `-bin`, the corresponding values must
be of type `bytes`.
"""
self._method = method
self._request = orgpolicy.ListPoliciesRequest(request)
Expand Down Expand Up @@ -293,7 +299,7 @@ def __init__(
*,
retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
metadata: Sequence[Tuple[str, str]] = ()
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiates the pager.
Expand All @@ -307,8 +313,10 @@ def __init__(
retry (google.api_core.retry.AsyncRetry): Designation of what errors,
if any, should be retried.
timeout (float): The timeout for this request.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
sent along with the request as metadata. Normally, each value must be of type `str`,
but for metadata keys ending with the suffix `-bin`, the corresponding values must
be of type `bytes`.
"""
self._method = method
self._request = orgpolicy.ListPoliciesRequest(request)
Expand Down Expand Up @@ -371,7 +379,7 @@ def __init__(
*,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
metadata: Sequence[Tuple[str, str]] = ()
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiate the pager.
Expand All @@ -385,8 +393,10 @@ def __init__(
retry (google.api_core.retry.Retry): Designation of what errors,
if any, should be retried.
timeout (float): The timeout for this request.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
sent along with the request as metadata. Normally, each value must be of type `str`,
but for metadata keys ending with the suffix `-bin`, the corresponding values must
be of type `bytes`.
"""
self._method = method
self._request = orgpolicy.ListCustomConstraintsRequest(request)
Expand Down Expand Up @@ -445,7 +455,7 @@ def __init__(
*,
retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
metadata: Sequence[Tuple[str, str]] = ()
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiates the pager.
Expand All @@ -459,8 +469,10 @@ def __init__(
retry (google.api_core.retry.AsyncRetry): Designation of what errors,
if any, should be retried.
timeout (float): The timeout for this request.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
sent along with the request as metadata. Normally, each value must be of type `str`,
but for metadata keys ending with the suffix `-bin`, the corresponding values must
be of type `bytes`.
"""
self._method = method
self._request = orgpolicy.ListCustomConstraintsRequest(request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
import json
import logging as std_logging
import pickle
from typing import Callable, Dict, Optional, Sequence, Tuple, Union
import warnings

Expand All @@ -21,12 +24,90 @@
from google.auth import credentials as ga_credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
from google.protobuf import empty_pb2 # type: ignore
from google.protobuf.json_format import MessageToJson
import google.protobuf.message
import grpc # type: ignore
import proto # type: ignore

from google.cloud.orgpolicy_v2.types import constraint, orgpolicy

from .base import DEFAULT_CLIENT_INFO, OrgPolicyTransport

try:
from google.api_core import client_logging # type: ignore

CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
except ImportError: # pragma: NO COVER
CLIENT_LOGGING_SUPPORTED = False

_LOGGER = std_logging.getLogger(__name__)


class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER
def intercept_unary_unary(self, continuation, client_call_details, request):
logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
std_logging.DEBUG
)
if logging_enabled: # pragma: NO COVER
request_metadata = client_call_details.metadata
if isinstance(request, proto.Message):
request_payload = type(request).to_json(request)
elif isinstance(request, google.protobuf.message.Message):
request_payload = MessageToJson(request)
else:
request_payload = f"{type(request).__name__}: {pickle.dumps(request)}"

request_metadata = {
key: value.decode("utf-8") if isinstance(value, bytes) else value
for key, value in request_metadata
}
grpc_request = {
"payload": request_payload,
"requestMethod": "grpc",
"metadata": dict(request_metadata),
}
_LOGGER.debug(
f"Sending request for {client_call_details.method}",
extra={
"serviceName": "google.cloud.orgpolicy.v2.OrgPolicy",
"rpcName": client_call_details.method,
"request": grpc_request,
"metadata": grpc_request["metadata"],
},
)

response = continuation(client_call_details, request)
if logging_enabled: # pragma: NO COVER
response_metadata = response.trailing_metadata()
# Convert gRPC metadata `<class 'grpc.aio._metadata.Metadata'>` to list of tuples
metadata = (
dict([(k, str(v)) for k, v in response_metadata])
if response_metadata
else None
)
result = response.result()
if isinstance(result, proto.Message):
response_payload = type(result).to_json(result)
elif isinstance(result, google.protobuf.message.Message):
response_payload = MessageToJson(result)
else:
response_payload = f"{type(result).__name__}: {pickle.dumps(result)}"
grpc_response = {
"payload": response_payload,
"metadata": metadata,
"status": "OK",
}
_LOGGER.debug(
f"Received response for {client_call_details.method}.",
extra={
"serviceName": "google.cloud.orgpolicy.v2.OrgPolicy",
"rpcName": client_call_details.method,
"response": grpc_response,
"metadata": grpc_response["metadata"],
},
)
return response


class OrgPolicyGrpcTransport(OrgPolicyTransport):
"""gRPC backend transport for OrgPolicy.
Expand Down Expand Up @@ -201,7 +282,12 @@ def __init__(
],
)

# Wrap messages. This must be done after self._grpc_channel exists
self._interceptor = _LoggingClientInterceptor()
self._logged_channel = grpc.intercept_channel(
self._grpc_channel, self._interceptor
)

# Wrap messages. This must be done after self._logged_channel exists
self._prep_wrapped_messages(client_info)

@classmethod
Expand Down Expand Up @@ -278,7 +364,7 @@ def list_constraints(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_constraints" not in self._stubs:
self._stubs["list_constraints"] = self.grpc_channel.unary_unary(
self._stubs["list_constraints"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/ListConstraints",
request_serializer=orgpolicy.ListConstraintsRequest.serialize,
response_deserializer=orgpolicy.ListConstraintsResponse.deserialize,
Expand All @@ -305,7 +391,7 @@ def list_policies(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_policies" not in self._stubs:
self._stubs["list_policies"] = self.grpc_channel.unary_unary(
self._stubs["list_policies"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/ListPolicies",
request_serializer=orgpolicy.ListPoliciesRequest.serialize,
response_deserializer=orgpolicy.ListPoliciesResponse.deserialize,
Expand Down Expand Up @@ -333,7 +419,7 @@ def get_policy(self) -> Callable[[orgpolicy.GetPolicyRequest], orgpolicy.Policy]
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_policy" not in self._stubs:
self._stubs["get_policy"] = self.grpc_channel.unary_unary(
self._stubs["get_policy"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/GetPolicy",
request_serializer=orgpolicy.GetPolicyRequest.serialize,
response_deserializer=orgpolicy.Policy.deserialize,
Expand Down Expand Up @@ -364,7 +450,7 @@ def get_effective_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_effective_policy" not in self._stubs:
self._stubs["get_effective_policy"] = self.grpc_channel.unary_unary(
self._stubs["get_effective_policy"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/GetEffectivePolicy",
request_serializer=orgpolicy.GetEffectivePolicyRequest.serialize,
response_deserializer=orgpolicy.Policy.deserialize,
Expand Down Expand Up @@ -396,7 +482,7 @@ def create_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_policy" not in self._stubs:
self._stubs["create_policy"] = self.grpc_channel.unary_unary(
self._stubs["create_policy"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/CreatePolicy",
request_serializer=orgpolicy.CreatePolicyRequest.serialize,
response_deserializer=orgpolicy.Policy.deserialize,
Expand Down Expand Up @@ -431,7 +517,7 @@ def update_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "update_policy" not in self._stubs:
self._stubs["update_policy"] = self.grpc_channel.unary_unary(
self._stubs["update_policy"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/UpdatePolicy",
request_serializer=orgpolicy.UpdatePolicyRequest.serialize,
response_deserializer=orgpolicy.Policy.deserialize,
Expand Down Expand Up @@ -461,7 +547,7 @@ def delete_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_policy" not in self._stubs:
self._stubs["delete_policy"] = self.grpc_channel.unary_unary(
self._stubs["delete_policy"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/DeletePolicy",
request_serializer=orgpolicy.DeletePolicyRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
Expand Down Expand Up @@ -495,7 +581,7 @@ def create_custom_constraint(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_custom_constraint" not in self._stubs:
self._stubs["create_custom_constraint"] = self.grpc_channel.unary_unary(
self._stubs["create_custom_constraint"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/CreateCustomConstraint",
request_serializer=orgpolicy.CreateCustomConstraintRequest.serialize,
response_deserializer=constraint.CustomConstraint.deserialize,
Expand Down Expand Up @@ -529,7 +615,7 @@ def update_custom_constraint(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "update_custom_constraint" not in self._stubs:
self._stubs["update_custom_constraint"] = self.grpc_channel.unary_unary(
self._stubs["update_custom_constraint"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/UpdateCustomConstraint",
request_serializer=orgpolicy.UpdateCustomConstraintRequest.serialize,
response_deserializer=constraint.CustomConstraint.deserialize,
Expand Down Expand Up @@ -559,7 +645,7 @@ def get_custom_constraint(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_custom_constraint" not in self._stubs:
self._stubs["get_custom_constraint"] = self.grpc_channel.unary_unary(
self._stubs["get_custom_constraint"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/GetCustomConstraint",
request_serializer=orgpolicy.GetCustomConstraintRequest.serialize,
response_deserializer=constraint.CustomConstraint.deserialize,
Expand Down Expand Up @@ -589,7 +675,7 @@ def list_custom_constraints(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_custom_constraints" not in self._stubs:
self._stubs["list_custom_constraints"] = self.grpc_channel.unary_unary(
self._stubs["list_custom_constraints"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/ListCustomConstraints",
request_serializer=orgpolicy.ListCustomConstraintsRequest.serialize,
response_deserializer=orgpolicy.ListCustomConstraintsResponse.deserialize,
Expand Down Expand Up @@ -618,15 +704,15 @@ def delete_custom_constraint(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_custom_constraint" not in self._stubs:
self._stubs["delete_custom_constraint"] = self.grpc_channel.unary_unary(
self._stubs["delete_custom_constraint"] = self._logged_channel.unary_unary(
"/google.cloud.orgpolicy.v2.OrgPolicy/DeleteCustomConstraint",
request_serializer=orgpolicy.DeleteCustomConstraintRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
)
return self._stubs["delete_custom_constraint"]

def close(self):
self.grpc_channel.close()
self._logged_channel.close()

@property
def kind(self) -> str:
Expand Down
Loading

0 comments on commit c896824

Please sign in to comment.