From bb1f1efcf39fc9649dbeae290e79ba1da1a84b22 Mon Sep 17 00:00:00 2001 From: Kevin Zheng <147537668+gkevinzheng@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:25:11 -0400 Subject: [PATCH 1/3] chore: Merge main into experimental-v4 (#906) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: Added missing import into logger.py (#896) * test: Fixed unsupported resource type in system test (#904) * fix: Added type hints to CloudLoggingHandler constructor (#903) * fix: Added type hints to CloudLoggingHandler constructor * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Removed Client typing due to circular imports --------- Co-authored-by: Owl Bot --------- Co-authored-by: Owl Bot --- google/cloud/logging_v2/handlers/handlers.py | 19 +++++++++++++------ google/cloud/logging_v2/logger.py | 1 + tests/system/test_system.py | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/google/cloud/logging_v2/handlers/handlers.py b/google/cloud/logging_v2/handlers/handlers.py index 06e131442..5b11bfe30 100644 --- a/google/cloud/logging_v2/handlers/handlers.py +++ b/google/cloud/logging_v2/handlers/handlers.py @@ -18,12 +18,19 @@ import json import logging -from google.cloud.logging_v2.handlers.transports import BackgroundThreadTransport +from typing import Optional, IO + +from google.cloud.logging_v2.handlers.transports import ( + BackgroundThreadTransport, + Transport, +) from google.cloud.logging_v2.handlers._monitored_resources import ( detect_resource, add_resource_labels, ) from google.cloud.logging_v2.handlers._helpers import get_request_data +from google.cloud.logging_v2.resource import Resource + DEFAULT_LOGGER_NAME = "python" @@ -149,11 +156,11 @@ def __init__( self, client, *, - name=DEFAULT_LOGGER_NAME, - transport=BackgroundThreadTransport, - resource=None, - labels=None, - stream=None, + name: str = DEFAULT_LOGGER_NAME, + transport: Transport = BackgroundThreadTransport, + resource: Resource = None, + labels: Optional[dict] = None, + stream: Optional[IO] = None, **kwargs, ): """ diff --git a/google/cloud/logging_v2/logger.py b/google/cloud/logging_v2/logger.py index 64130f02f..27553994b 100644 --- a/google/cloud/logging_v2/logger.py +++ b/google/cloud/logging_v2/logger.py @@ -29,6 +29,7 @@ from google.api_core.exceptions import InvalidArgument from google.rpc.error_details_pb2 import DebugInfo +import google.cloud.logging_v2 import google.protobuf.message _GLOBAL_RESOURCE = Resource(type="global", labels={}) diff --git a/tests/system/test_system.py b/tests/system/test_system.py index 801cab341..d4ec4da36 100644 --- a/tests/system/test_system.py +++ b/tests/system/test_system.py @@ -622,7 +622,7 @@ def test_handlers_w_extras(self): "trace_sampled": True, "http_request": expected_request, "source_location": expected_source, - "resource": Resource(type="cloudiot_device", labels={}), + "resource": Resource(type="global", labels={}), "labels": {"test-label": "manual"}, } cloud_logger.warning(LOG_MESSAGE, extra=extra) From f92c9b832b2644187e7dd6c10c41cf6b666026a0 Mon Sep 17 00:00:00 2001 From: Kevin Zheng <147537668+gkevinzheng@users.noreply.github.com> Date: Tue, 25 Jun 2024 10:41:55 -0400 Subject: [PATCH 2/3] feat!: Use StructuredLogHandler on App Engine instead of CloudLoggingHandler (#908) * feat!: Use StructuredLogHandler on App Engine instead of CloudLoggingHandler * linting --- google/cloud/logging_v2/client.py | 28 ++++++++++++++++++---------- tests/unit/test_client.py | 6 ++---- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/google/cloud/logging_v2/client.py b/google/cloud/logging_v2/client.py index 94c1e6ca7..13aca9e6b 100644 --- a/google/cloud/logging_v2/client.py +++ b/google/cloud/logging_v2/client.py @@ -376,18 +376,26 @@ def get_default_handler(self, **kw): """ monitored_resource = kw.pop("resource", detect_resource(self.project)) - if isinstance(monitored_resource, Resource): - if monitored_resource.type == _GAE_RESOURCE_TYPE: - return CloudLoggingHandler(self, resource=monitored_resource, **kw) - elif monitored_resource.type == _GKE_RESOURCE_TYPE: - return StructuredLogHandler(**kw, project_id=self.project) - elif monitored_resource.type == _GCF_RESOURCE_TYPE: + _structured_log_types = [ + _GAE_RESOURCE_TYPE, + _GKE_RESOURCE_TYPE, + _GCF_RESOURCE_TYPE, + _RUN_RESOURCE_TYPE, + ] + + if ( + isinstance(monitored_resource, Resource) + and monitored_resource.type in _structured_log_types + ): + if monitored_resource.type == _GCF_RESOURCE_TYPE: # __stdout__ stream required to support structured logging on Python 3.7 kw["stream"] = kw.get("stream", sys.__stdout__) - return StructuredLogHandler(**kw, project_id=self.project) - elif monitored_resource.type == _RUN_RESOURCE_TYPE: - return StructuredLogHandler(**kw, project_id=self.project) - return CloudLoggingHandler(self, resource=monitored_resource, **kw) + + handler = StructuredLogHandler(**kw, project_id=self.project) + else: + handler = CloudLoggingHandler(self, resource=monitored_resource, **kw) + + return handler def setup_logging( self, *, log_level=logging.INFO, excluded_loggers=EXCLUDED_LOGGER_DEFAULTS, **kw diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 2d12a283e..dc74009f0 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -766,7 +766,7 @@ def test_get_default_handler_app_engine(self): import os from google.cloud._testing import _Monkey from google.cloud.logging_v2.handlers._monitored_resources import _GAE_ENV_VARS - from google.cloud.logging.handlers import CloudLoggingHandler + from google.cloud.logging.handlers import StructuredLogHandler credentials = _make_credentials() client = self._make_one( @@ -778,9 +778,7 @@ def test_get_default_handler_app_engine(self): with _Monkey(os, environ=gae_env_vars): handler = client.get_default_handler() - handler.transport.worker.stop() - - self.assertIsInstance(handler, CloudLoggingHandler) + self.assertIsInstance(handler, StructuredLogHandler) def test_get_default_handler_container_engine(self): from google.cloud.logging.handlers import StructuredLogHandler From 758d439823219358eec4adbeaca77d87c3246512 Mon Sep 17 00:00:00 2001 From: Kevin Zheng <147537668+gkevinzheng@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:47:11 -0400 Subject: [PATCH 3/3] fix!: Use StructuredLogHandler for Cloud Run Job (#898) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix!: Use StructuredLogHandler for Cloud Run Job * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: Merge main into experimental-v4 (#906) * fix: Added missing import into logger.py (#896) * test: Fixed unsupported resource type in system test (#904) * fix: Added type hints to CloudLoggingHandler constructor (#903) * fix: Added type hints to CloudLoggingHandler constructor * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Removed Client typing due to circular imports --------- Co-authored-by: Owl Bot --------- Co-authored-by: Owl Bot * feat!: Use StructuredLogHandler on App Engine instead of CloudLoggingHandler (#908) * feat!: Use StructuredLogHandler on App Engine instead of CloudLoggingHandler * linting * fix!: Use StructuredLogHandler for Cloud Run Job * Removed print statement * Resolved all merge conflicts * linting --------- Co-authored-by: Owl Bot --- google/cloud/logging_v2/client.py | 16 ++++++++------- .../handlers/_monitored_resources.py | 9 +++++++++ tests/unit/test_client.py | 20 +++++++++++++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/google/cloud/logging_v2/client.py b/google/cloud/logging_v2/client.py index 13aca9e6b..9a4e52023 100644 --- a/google/cloud/logging_v2/client.py +++ b/google/cloud/logging_v2/client.py @@ -32,8 +32,14 @@ from google.cloud.logging_v2.handlers import setup_logging from google.cloud.logging_v2.handlers.handlers import EXCLUDED_LOGGER_DEFAULTS from google.cloud.logging_v2.resource import Resource -from google.cloud.logging_v2.handlers._monitored_resources import detect_resource - +from google.cloud.logging_v2.handlers._monitored_resources import ( + detect_resource, + _GAE_RESOURCE_TYPE, + _GKE_RESOURCE_TYPE, + _GCF_RESOURCE_TYPE, + _RUN_RESOURCE_TYPE, + _CLOUD_RUN_JOB_RESOURCE_TYPE, +) from google.cloud.logging_v2.logger import Logger from google.cloud.logging_v2.metric import Metric @@ -56,11 +62,6 @@ _USE_GRPC = _HAVE_GRPC and not _DISABLE_GRPC -_GAE_RESOURCE_TYPE = "gae_app" -_GKE_RESOURCE_TYPE = "k8s_container" -_GCF_RESOURCE_TYPE = "cloud_function" -_RUN_RESOURCE_TYPE = "cloud_run_revision" - class Client(ClientWithProject): """Client to bundle configuration needed for API requests.""" @@ -381,6 +382,7 @@ def get_default_handler(self, **kw): _GKE_RESOURCE_TYPE, _GCF_RESOURCE_TYPE, _RUN_RESOURCE_TYPE, + _CLOUD_RUN_JOB_RESOURCE_TYPE, ] if ( diff --git a/google/cloud/logging_v2/handlers/_monitored_resources.py b/google/cloud/logging_v2/handlers/_monitored_resources.py index 5240fe746..c15c42d7b 100644 --- a/google/cloud/logging_v2/handlers/_monitored_resources.py +++ b/google/cloud/logging_v2/handlers/_monitored_resources.py @@ -60,6 +60,9 @@ _GCE_INSTANCE_ID = "instance/id" """Attribute in metadata server for compute region and instance.""" +_GKE_RESOURCE_TYPE = "k8s_container" +"""Resource type for the GKE environment.""" + _GKE_CLUSTER_NAME = "instance/attributes/cluster-name" """Attribute in metadata server when in GKE environment.""" @@ -72,6 +75,12 @@ _GAE_RESOURCE_TYPE = "gae_app" """Resource type for App Engine environment.""" +_GCF_RESOURCE_TYPE = "cloud_function" +"""Resource type for Cloud Functions environment.""" + +_RUN_RESOURCE_TYPE = "cloud_run_revision" +"""Resource type for Cloud Run environment.""" + _CLOUD_RUN_JOB_RESOURCE_TYPE = "cloud_run_job" """Resource type for Cloud Run Jobs.""" diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index dc74009f0..4bfd984ff 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -798,6 +798,26 @@ def test_get_default_handler_container_engine(self): self.assertIsInstance(handler, StructuredLogHandler) + def test_get_default_handler_cloud_run_jobs(self): + import os + from google.cloud._testing import _Monkey + from google.cloud.logging_v2.handlers._monitored_resources import ( + _CLOUD_RUN_JOB_ENV_VARS, + ) + from google.cloud.logging.handlers import StructuredLogHandler + + credentials = _make_credentials() + client = self._make_one( + project=self.PROJECT, credentials=credentials, _use_grpc=False + ) + + cloud_run_job_env_vars = {var: "TRUE" for var in _CLOUD_RUN_JOB_ENV_VARS} + + with _Monkey(os, environ=cloud_run_job_env_vars): + handler = client.get_default_handler() + + self.assertIsInstance(handler, StructuredLogHandler) + def test_get_default_handler_general(self): import io from google.cloud.logging.handlers import CloudLoggingHandler