Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Infer default resource in logger #315

Merged
merged 13 commits into from
Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/.OwlBot.lock.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
docker:
image: gcr.io/repo-automation-bots/owlbot-python:latest
digest: sha256:c66ba3c8d7bc8566f47df841f98cd0097b28fff0b1864c86f5817f4c8c3e8600
digest: sha256:58c7342b0bccf85028100adaa3d856cb4a871c22ca9c01960d996e66c40548ce
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@

[1]: https://pypi.org/project/google-cloud-logging/#history

## [2.5.0](https://www.github.com/googleapis/python-logging/compare/v2.4.0...v2.5.0) (2021-06-10)


### Features

* support AuditLog and RequestLog protos ([#274](https://www.github.com/googleapis/python-logging/issues/274)) ([5d91be9](https://www.github.com/googleapis/python-logging/commit/5d91be9f121c364cbd53c6a9fffc4fb6ca6bd324))


### Bug Fixes

* **deps:** add packaging requirement ([#300](https://www.github.com/googleapis/python-logging/issues/300)) ([68c5cec](https://www.github.com/googleapis/python-logging/commit/68c5ceced3288253af8e3c6013a35fa3954b37bc))
* structured log handler formatting issues ([#319](https://www.github.com/googleapis/python-logging/issues/319)) ([db9da37](https://www.github.com/googleapis/python-logging/commit/db9da3700511b5a24c3c44c9f4377705937caf46))

## [2.4.0](https://www.github.com/googleapis/python-logging/compare/v2.3.1...v2.4.0) (2021-05-12)


Expand Down
12 changes: 6 additions & 6 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@
master_doc = "index"

# General information about the project.
project = u"google-cloud-logging"
copyright = u"2019, Google"
author = u"Google APIs"
project = "google-cloud-logging"
copyright = "2019, Google"
author = "Google APIs"

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down Expand Up @@ -281,7 +281,7 @@
(
master_doc,
"google-cloud-logging.tex",
u"google-cloud-logging Documentation",
"google-cloud-logging Documentation",
author,
"manual",
)
Expand Down Expand Up @@ -316,7 +316,7 @@
(
master_doc,
"google-cloud-logging",
u"google-cloud-logging Documentation",
"google-cloud-logging Documentation",
[author],
1,
)
Expand All @@ -335,7 +335,7 @@
(
master_doc,
"google-cloud-logging",
u"google-cloud-logging Documentation",
"google-cloud-logging Documentation",
author,
"google-cloud-logging",
"google-cloud-logging Library",
Expand Down
9 changes: 7 additions & 2 deletions google/cloud/logging_v2/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,16 +182,21 @@ def metrics_api(self):
self._metrics_api = JSONMetricsAPI(self)
return self._metrics_api

def logger(self, name):
def logger(self, name, *, labels=None, resource=None):
"""Creates a logger bound to the current client.

Args:
name (str): The name of the logger to be constructed.
resource (Optional[~logging_v2.Resource]): a monitored resource object
representing the resource the code was run on. If not given, will
be inferred from the environment.
labels (Optional[dict]): Mapping of default labels for entries written
via this logger.

Returns:
~logging_v2.logger.Logger: Logger created with the current client.
"""
return Logger(name, client=self)
return Logger(name, client=self, labels=labels, resource=resource)

def list_entries(
self,
Expand Down
8 changes: 5 additions & 3 deletions google/cloud/logging_v2/handlers/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import json
import logging

from google.cloud.logging_v2.logger import _GLOBAL_RESOURCE
from google.cloud.logging_v2.handlers.transports import BackgroundThreadTransport
from google.cloud.logging_v2.handlers._monitored_resources import detect_resource
from google.cloud.logging_v2.handlers._helpers import get_request_data
Expand Down Expand Up @@ -144,7 +143,7 @@ def __init__(
*,
name=DEFAULT_LOGGER_NAME,
transport=BackgroundThreadTransport,
resource=_GLOBAL_RESOURCE,
resource=None,
labels=None,
stream=None,
):
Expand All @@ -163,11 +162,14 @@ def __init__(
:class:`.BackgroundThreadTransport`. The other
option is :class:`.SyncTransport`.
resource (~logging_v2.resource.Resource):
Resource for this Handler. Defaults to ``global``.
Resource for this Handler. If not given, will be inferred from the environment.
labels (Optional[dict]): Additional labels to attach to logs.
stream (Optional[IO]): Stream to be used by the handler.
"""
super(CloudLoggingHandler, self).__init__(stream)
if not resource:
# infer the correct monitored resource from the local environment
resource = detect_resource(client.project)
self.name = name
self.client = client
self.transport = transport(client, name)
Expand Down
11 changes: 8 additions & 3 deletions google/cloud/logging_v2/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from google.cloud.logging_v2.entries import StructEntry
from google.cloud.logging_v2.entries import TextEntry
from google.cloud.logging_v2.resource import Resource
from google.cloud.logging_v2.handlers._monitored_resources import detect_resource

import google.protobuf.message

Expand Down Expand Up @@ -51,19 +52,23 @@ class Logger(object):
See https://cloud.google.com/logging/docs/reference/v2/rest/v2/projects.logs
"""

def __init__(self, name, client, *, labels=None, resource=_GLOBAL_RESOURCE):
def __init__(self, name, client, *, labels=None, resource=None):
"""
Args:
name (str): The name of the logger.
client (~logging_v2.client.Client):
A client which holds credentials and project configuration
for the logger (which requires a project).
resource (~logging_v2.Resource): a monitored resource object
representing the resource the code was run on.
resource (Optional[~logging_v2.Resource]): a monitored resource object
representing the resource the code was run on. If not given, will
be inferred from the environment.
labels (Optional[dict]): Mapping of default labels for entries written
via this logger.

"""
if not resource:
# infer the correct monitored resource from the local environment
resource = detect_resource(client.project)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this default to "global" in case the environment wasn't detected? (i.e. the code is running in dataflow job)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, global is the fallback for detect_resource

self.name = name
self._client = client
self.labels = labels
Expand Down
11 changes: 9 additions & 2 deletions samples/snippets/usage_guide.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,19 @@ def _sink_pubsub_setup(client):
) # API call
# [END sink_topic_permissions]

return topic
# create callback wrapper to delete topic when done
class TopicDeleter:
def delete(self):
client.delete_topic(request={"topic": topic_path})

return topic, TopicDeleter()


@snippet
def sink_pubsub(client, to_delete):
"""Sink log entries to pubsub."""
topic = _sink_pubsub_setup(client)
topic, topic_deleter = _sink_pubsub_setup(client)
to_delete.append(topic_deleter)
sink_name = "robots-pubsub-%d" % (_millis(),)
filter_str = "logName:apache-access AND textPayload:robot"
updated_filter = "textPayload:robot"
Expand All @@ -282,6 +288,7 @@ def sink_pubsub(client, to_delete):
sink.create() # API call
assert sink.exists() # API call
# [END sink_pubsub_create]
to_delete.append(sink)
created_sink = sink

# [START client_list_sinks]
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

name = "google-cloud-logging"
description = "Stackdriver Logging API client library"
version = "2.4.0"
version = "2.5.0"
# Should be one of:
# 'Development Status :: 3 - Alpha'
# 'Development Status :: 4 - Beta'
Expand Down
7 changes: 5 additions & 2 deletions tests/unit/handlers/test_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,9 @@ def _make_one(self, *args, **kw):

def test_ctor_defaults(self):
import sys
from google.cloud.logging_v2.logger import _GLOBAL_RESOURCE
from google.cloud.logging_v2.handlers._monitored_resources import (
_create_global_resource,
)
from google.cloud.logging_v2.handlers.handlers import DEFAULT_LOGGER_NAME

patch = mock.patch(
Expand All @@ -251,7 +253,8 @@ def test_ctor_defaults(self):
self.assertIsInstance(handler.transport, _Transport)
self.assertIs(handler.transport.client, client)
self.assertEqual(handler.transport.name, DEFAULT_LOGGER_NAME)
self.assertEqual(handler.resource, _GLOBAL_RESOURCE)
global_resource = _create_global_resource(self.PROJECT)
self.assertEqual(handler.resource, global_resource)
self.assertIsNone(handler.labels)
self.assertIs(handler.stream, sys.stderr)

Expand Down
8 changes: 7 additions & 1 deletion tests/unit/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,14 +239,20 @@ def make_api(client_obj):

def test_logger(self):
from google.cloud.logging import Logger
from google.cloud.logging_v2.logger import _GLOBAL_RESOURCE

creds = _make_credentials()
client = self._make_one(project=self.PROJECT, credentials=creds)
logger = client.logger(self.LOGGER_NAME)
labels = {"test": "true"}
logger = client.logger(
self.LOGGER_NAME, resource=_GLOBAL_RESOURCE, labels=labels
)
self.assertIsInstance(logger, Logger)
self.assertEqual(logger.name, self.LOGGER_NAME)
self.assertIs(logger.client, client)
self.assertEqual(logger.project, self.PROJECT)
self.assertEqual(logger.default_resource, _GLOBAL_RESOURCE)
self.assertEqual(logger.labels, labels)

def test_list_entries_defaults(self):
from google.cloud.logging import TextEntry
Expand Down
Loading