Skip to content

Commit 571a7bf

Browse files
myelintheacodes
authored andcommitted
Logging: support request-correlated logging in App Engine standard python37 runtime (googleapis#6118)
The python37 runtime provides the GOOGLE_CLOUD_PROJECT environment variable instead of GCLOUD_PROJECT, and for log messages to be correlated with the request in StackDriver, their 'trace' value has to be passed as a top level member of the log record rather than as an appengine.googleapis.com/trace_id label.
1 parent c24c604 commit 571a7bf

3 files changed

Lines changed: 32 additions & 15 deletions

File tree

logging/google/cloud/logging/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@
4949
_APPENGINE_FLEXIBLE_ENV_VM = 'GAE_APPENGINE_HOSTNAME'
5050
"""Environment variable set in App Engine when vm:true is set."""
5151

52-
_APPENGINE_FLEXIBLE_ENV_FLEX = 'GAE_INSTANCE'
53-
"""Environment variable set in App Engine when env:flex is set."""
52+
_APPENGINE_INSTANCE_ID = 'GAE_INSTANCE'
53+
"""Environment variable set in App Engine standard and flexible environment."""
5454

5555
_GKE_CLUSTER_NAME = 'instance/attributes/cluster-name'
5656
"""Attribute in metadata server when in GKE environment."""
@@ -301,7 +301,7 @@ def get_default_handler(self):
301301
gke_cluster_name = retrieve_metadata_server(_GKE_CLUSTER_NAME)
302302

303303
if (_APPENGINE_FLEXIBLE_ENV_VM in os.environ or
304-
_APPENGINE_FLEXIBLE_ENV_FLEX in os.environ):
304+
_APPENGINE_INSTANCE_ID in os.environ):
305305
return AppEngineHandler(self)
306306
elif gke_cluster_name is not None:
307307
return ContainerEngineHandler()

logging/google/cloud/logging/handlers/app_engine.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727

2828
_DEFAULT_GAE_LOGGER_NAME = 'app'
2929

30-
_GAE_PROJECT_ENV = 'GCLOUD_PROJECT'
30+
_GAE_PROJECT_ENV_FLEX = 'GCLOUD_PROJECT'
31+
_GAE_PROJECT_ENV_STANDARD = 'GOOGLE_CLOUD_PROJECT'
3132
_GAE_SERVICE_ENV = 'GAE_SERVICE'
3233
_GAE_VERSION_ENV = 'GAE_VERSION'
3334

@@ -54,6 +55,11 @@ def __init__(self, client,
5455
self.name = name
5556
self.client = client
5657
self.transport = transport(client, name)
58+
self.project_id = os.environ.get(
59+
_GAE_PROJECT_ENV_FLEX,
60+
os.environ.get(_GAE_PROJECT_ENV_STANDARD, ''))
61+
self.module_id = os.environ.get(_GAE_SERVICE_ENV, '')
62+
self.version_id = os.environ.get(_GAE_VERSION_ENV, '')
5763
self.resource = self.get_gae_resource()
5864

5965
def get_gae_resource(self):
@@ -65,9 +71,9 @@ def get_gae_resource(self):
6571
gae_resource = Resource(
6672
type='gae_app',
6773
labels={
68-
'project_id': os.environ.get(_GAE_PROJECT_ENV),
69-
'module_id': os.environ.get(_GAE_SERVICE_ENV),
70-
'version_id': os.environ.get(_GAE_VERSION_ENV),
74+
'project_id': self.project_id,
75+
'module_id': self.module_id,
76+
'version_id': self.version_id,
7177
},
7278
)
7379
return gae_resource
@@ -100,8 +106,15 @@ def emit(self, record):
100106
:param record: The record to be logged.
101107
"""
102108
message = super(AppEngineHandler, self).format(record)
109+
gae_labels = self.get_gae_labels()
110+
trace_id = ('projects/%s/traces/%s' % (self.project_id,
111+
gae_labels[_TRACE_ID_LABEL])
112+
if _TRACE_ID_LABEL in gae_labels
113+
else None)
103114
self.transport.send(
104115
record,
105116
message,
106117
resource=self.resource,
107-
labels=self.get_gae_labels())
118+
labels=gae_labels,
119+
trace=trace_id,
120+
)

logging/tests/unit/handlers/test_app_engine.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,18 @@ def _make_one(self, *args, **kw):
3030
return self._get_target_class()(*args, **kw)
3131

3232
def test_constructor(self):
33-
from google.cloud.logging.handlers.app_engine import _GAE_PROJECT_ENV
33+
from google.cloud.logging.handlers.app_engine import (
34+
_GAE_PROJECT_ENV_STANDARD)
3435
from google.cloud.logging.handlers.app_engine import _GAE_SERVICE_ENV
3536
from google.cloud.logging.handlers.app_engine import _GAE_VERSION_ENV
3637

3738
client = mock.Mock(project=self.PROJECT, spec=['project'])
3839

39-
with mock.patch('os.environ', new={_GAE_PROJECT_ENV: 'test_project',
40-
_GAE_SERVICE_ENV: 'test_service',
41-
_GAE_VERSION_ENV: 'test_version'}):
40+
with mock.patch('os.environ', new={
41+
_GAE_PROJECT_ENV_STANDARD: 'test_project',
42+
_GAE_SERVICE_ENV: 'test_service',
43+
_GAE_VERSION_ENV: 'test_version',
44+
}):
4245
handler = self._make_one(client, transport=_Transport)
4346
self.assertIs(handler.client, client)
4447
self.assertEqual(handler.resource.type, 'gae_app')
@@ -51,6 +54,7 @@ def test_emit(self):
5154
handler = self._make_one(client, transport=_Transport)
5255
gae_resource = handler.get_gae_resource()
5356
gae_labels = handler.get_gae_labels()
57+
trace = None
5458
logname = 'app'
5559
message = 'hello world'
5660
record = logging.LogRecord(logname, logging, None, None, message,
@@ -61,7 +65,7 @@ def test_emit(self):
6165
self.assertEqual(handler.transport.name, logname)
6266
self.assertEqual(
6367
handler.transport.send_called_with,
64-
(record, message, gae_resource, gae_labels))
68+
(record, message, gae_resource, gae_labels, trace))
6569

6670
def _get_gae_labels_helper(self, trace_id):
6771
get_trace_patch = mock.patch(
@@ -98,5 +102,5 @@ def __init__(self, client, name):
98102
self.client = client
99103
self.name = name
100104

101-
def send(self, record, message, resource, labels):
102-
self.send_called_with = (record, message, resource, labels)
105+
def send(self, record, message, resource, labels, trace):
106+
self.send_called_with = (record, message, resource, labels, trace)

0 commit comments

Comments
 (0)