Skip to content

Commit ef66ac5

Browse files
committed
address PR feedback
1 parent 48b9ed9 commit ef66ac5

File tree

2 files changed

+66
-21
lines changed

2 files changed

+66
-21
lines changed

google/api_core/client_logging.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
import os
55

66
_LOGGING_INITIALIZED = False
7-
8-
# TODO(<add-link>): Update Request / Response messages.
7+
_BASE_LOGGER_NAME = "google"
8+
# TODO(https://github.com/googleapis/python-api-core/issues/760): Update Request / Response messages.
99
REQUEST_MESSAGE = "Sending request ..."
1010
RESPONSE_MESSAGE = "Receiving response ..."
1111

12-
# TODO(<add-link>): Update this list to support additional logging fields
12+
# TODO(https://github.com/googleapis/python-api-core/issues/761): Update this list to support additional logging fields
1313
_recognized_logging_fields = ["httpRequest", "rpcName", "serviceName"] # Additional fields to be Logged.
1414

1515
def logger_configured(logger):
16-
return logger.hasHandlers() or logger.level != logging.NOTSET or logger.propagate == False
16+
return logger.handlers != [] or logger.level != logging.NOTSET or logger.propagate == False
1717

1818
def initialize_logging():
1919
global _LOGGING_INITIALIZED
@@ -26,8 +26,9 @@ def initialize_logging():
2626
def parse_logging_scopes(scopes):
2727
if not scopes:
2828
return []
29-
# TODO(<add-link>): check if the namespace is a valid namespace.
30-
# TODO(<add-link>): parse a list of namespaces. Current flow expects a single string for now.
29+
# TODO(https://github.com/googleapis/python-api-core/issues/759): check if the namespace is a valid namespace.
30+
# TODO(b/380481951): Support logging multiple scopes.
31+
# TODO(b/380483756): Raise or log a warning for an invalid scope.
3132
namespaces = [scopes]
3233
return namespaces
3334

@@ -40,23 +41,25 @@ def configure_defaults(logger):
4041
console_handler.setFormatter(formatter)
4142
logger.addHandler(console_handler)
4243

43-
def setup_logging(scopes):
44-
# disable log propagation at base logger level to the root logger only if a base logger is not already configured via code changes.
45-
base_logger = logging.getLogger("google")
46-
if not logger_configured(base_logger):
47-
base_logger.propagate = False
44+
def setup_logging(scopes=[]):
4845

4946
# only returns valid logger scopes (namespaces)
5047
# this list has at most one element.
51-
loggers = parse_logging_scopes(scopes)
48+
logger_names = parse_logging_scopes(scopes)
5249

53-
for namespace in loggers:
50+
for namespace in logger_names:
5451
# This will either create a module level logger or get the reference of the base logger instantiated above.
5552
logger = logging.getLogger(namespace)
5653

5754
# Configure default settings.
5855
configure_defaults(logger)
5956

57+
# disable log propagation at base logger level to the root logger only if a base logger is not already configured via code changes.
58+
# Maybe we do this at the end?
59+
base_logger = logging.getLogger(_BASE_LOGGER_NAME)
60+
if not logger_configured(base_logger):
61+
base_logger.propagate = False
62+
6063
class StructuredLogFormatter(logging.Formatter):
6164
def format(self, record):
6265
log_obj = {

tests/unit/test_client_logging.py

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,62 @@
11
import logging
22
import pytest
33

4+
from google.api_core.client_logging import setup_logging
45
# Test expected behaviour for warnings, propagation, handler + formatter.
56

7+
def reset_logger(scope):
8+
logger = logging.getLogger(scope)
9+
logger.handlers = []
10+
logger.setLevel(logging.NOTSET)
11+
logger.propagate = True
12+
613
def test_setup_logging_w_no_scopes():
7-
# TODO(in-progress):
8-
pass
14+
setup_logging()
15+
base_logger = logging.getLogger("google")
16+
assert base_logger.handlers == []
17+
assert base_logger.propagate == False
18+
assert base_logger.level == logging.NOTSET
19+
20+
reset_logger("google")
21+
922

1023
def test_setup_logging_w_base_scope():
11-
# TODO(in-progress):
12-
pass
24+
setup_logging("google")
25+
base_logger = logging.getLogger("google")
26+
assert isinstance(base_logger.handlers[0], logging.StreamHandler)
27+
assert base_logger.propagate == False
28+
assert base_logger.level == logging.DEBUG
29+
30+
reset_logger("google")
1331

1432
def test_setup_logging_w_module_scope():
15-
# TODO(in-progress):
16-
pass
33+
setup_logging("google.foo")
34+
35+
base_logger = logging.getLogger("google")
36+
assert base_logger.handlers == []
37+
assert base_logger.propagate == False
38+
assert base_logger.level == logging.NOTSET
39+
40+
module_logger = logging.getLogger("google.foo")
41+
assert isinstance(module_logger.handlers[0], logging.StreamHandler)
42+
assert module_logger.propagate == False
43+
assert module_logger.level == logging.DEBUG
44+
45+
46+
reset_logger("google")
1747

1848
def test_setup_logging_w_incorrect_scope():
19-
# TODO(in-progress):
20-
pass
49+
setup_logging("foo")
50+
51+
base_logger = logging.getLogger("google")
52+
assert base_logger.handlers == []
53+
assert base_logger.propagate == False
54+
assert base_logger.level == logging.NOTSET
55+
56+
# TODO: update test once we add logic to ignore an incorrect scope.
57+
logger = logging.getLogger("foo")
58+
assert isinstance(logger.handlers[0], logging.StreamHandler)
59+
assert logger.propagate == False
60+
assert logger.level == logging.DEBUG
61+
62+
reset_logger("google")

0 commit comments

Comments
 (0)