Skip to content

Commit e3cac88

Browse files
committed
chore!: deprecate AppEngineHandler and ContainerEngineHandler (#310)
1 parent 81ca8c6 commit e3cac88

File tree

7 files changed

+44
-36
lines changed

7 files changed

+44
-36
lines changed

google/cloud/logging_v2/client.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
from google.cloud.logging_v2._http import _MetricsAPI as JSONMetricsAPI
3636
from google.cloud.logging_v2._http import _SinksAPI as JSONSinksAPI
3737
from google.cloud.logging_v2.handlers import CloudLoggingHandler
38-
from google.cloud.logging_v2.handlers import AppEngineHandler
39-
from google.cloud.logging_v2.handlers import ContainerEngineHandler
4038
from google.cloud.logging_v2.handlers import StructuredLogHandler
4139
from google.cloud.logging_v2.handlers import setup_logging
4240
from google.cloud.logging_v2.handlers.handlers import EXCLUDED_LOGGER_DEFAULTS
@@ -352,7 +350,7 @@ def get_default_handler(self, **kw):
352350

353351
if isinstance(monitored_resource, Resource):
354352
if monitored_resource.type == _GAE_RESOURCE_TYPE:
355-
return AppEngineHandler(self, **kw)
353+
return CloudLoggingHandler(self, resource=monitored_resource, **kw)
356354
elif monitored_resource.type == _GKE_RESOURCE_TYPE:
357355
return ContainerEngineHandler(**kw)
358356
elif monitored_resource.type == _GCF_RESOURCE_TYPE:

google/cloud/logging_v2/handlers/_helpers.py

+7-14
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import math
1818
import json
1919
import re
20+
import warnings
2021

2122
try:
2223
import flask
@@ -39,6 +40,8 @@ def format_stackdriver_json(record, message):
3940
4041
Returns:
4142
str: JSON str to be written to the log file.
43+
44+
DEPRECATED: use StructuredLogHandler to write formatted logs to standard out instead.
4245
"""
4346
subsecond, second = math.modf(record.created)
4447

@@ -48,7 +51,10 @@ def format_stackdriver_json(record, message):
4851
"thread": record.thread,
4952
"severity": record.levelname,
5053
}
51-
54+
warnings.warn(
55+
"format_stackdriver_json is deprecated. Use StructuredLogHandler instead.",
56+
DeprecationWarning,
57+
)
5258
return json.dumps(payload, ensure_ascii=False)
5359

5460

@@ -68,10 +74,7 @@ def get_request_data_from_flask():
6874
http_request = {
6975
"requestMethod": flask.request.method,
7076
"requestUrl": flask.request.url,
71-
"requestSize": flask.request.content_length,
7277
"userAgent": flask.request.user_agent.string,
73-
"remoteIp": flask.request.remote_addr,
74-
"referer": flask.request.referrer,
7578
"protocol": flask.request.environ.get(_PROTOCOL_HEADER),
7679
}
7780

@@ -96,21 +99,11 @@ def get_request_data_from_django():
9699
if request is None:
97100
return None, None, None
98101

99-
# convert content_length to int if it exists
100-
content_length = None
101-
try:
102-
content_length = int(request.META.get(_DJANGO_CONTENT_LENGTH))
103-
except (ValueError, TypeError):
104-
content_length = None
105-
106102
# build http_request
107103
http_request = {
108104
"requestMethod": request.method,
109105
"requestUrl": request.build_absolute_uri(),
110-
"requestSize": content_length,
111106
"userAgent": request.META.get(_DJANGO_USERAGENT_HEADER),
112-
"remoteIp": request.META.get(_DJANGO_REMOTE_ADDR_HEADER),
113-
"referer": request.META.get(_DJANGO_REFERER_HEADER),
114107
"protocol": request.META.get(_PROTOCOL_HEADER),
115108
}
116109

google/cloud/logging_v2/handlers/app_engine.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import logging
2222
import os
23+
import warnings
2324

2425
from google.cloud.logging_v2.handlers._helpers import get_request_data
2526
from google.cloud.logging_v2.handlers._monitored_resources import (
@@ -36,9 +37,14 @@
3637

3738
_TRACE_ID_LABEL = "appengine.googleapis.com/trace_id"
3839

40+
_DEPRECATION_MSG = "AppEngineHandler is deprecated. Use CloudLoggingHandler instead."
41+
3942

4043
class AppEngineHandler(logging.StreamHandler):
41-
"""A logging handler that sends App Engine-formatted logs to Stackdriver."""
44+
"""A logging handler that sends App Engine-formatted logs to Stackdriver.
45+
46+
DEPRECATED: use CloudLoggingHandler instead.
47+
"""
4248

4349
def __init__(
4450
self,
@@ -71,6 +77,8 @@ def __init__(
7177
self.version_id = os.environ.get(_GAE_VERSION_ENV, "")
7278
self.resource = self.get_gae_resource()
7379

80+
warnings.warn(_DEPRECATION_MSG, DeprecationWarning)
81+
7482
def get_gae_resource(self):
7583
"""Return the GAE resource using the environment variables.
7684

google/cloud/logging_v2/handlers/container_engine.py

+8
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,22 @@
2020
"""
2121

2222
import logging.handlers
23+
import warnings
2324

2425
from google.cloud.logging_v2.handlers._helpers import format_stackdriver_json
2526

27+
_DEPRECATION_MSG = (
28+
"ContainerEngineHandler is deprecated. Use StructuredLogHandler instead."
29+
)
30+
2631

2732
class ContainerEngineHandler(logging.StreamHandler):
2833
"""Handler to format log messages the format expected by GKE fluent.
2934
3035
This handler is written to format messages for the Google Container Engine
3136
(GKE) fluentd plugin, so that metadata such as log level are properly set.
37+
38+
DEPRECATED: use StructuredLogHandler to write formatted logs to standard out instead.
3239
"""
3340

3441
def __init__(self, *, name=None, stream=None):
@@ -40,6 +47,7 @@ def __init__(self, *, name=None, stream=None):
4047
"""
4148
super(ContainerEngineHandler, self).__init__(stream=stream)
4249
self.name = name
50+
warnings.warn(_DEPRECATION_MSG, DeprecationWarning)
4351

4452
def format(self, record):
4553
"""Format the message into JSON expected by fluentd.

google/cloud/logging_v2/handlers/handlers.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,15 @@
3333
"werkzeug",
3434
)
3535

36+
"""These environments require us to remove extra handlers on setup"""
3637
_CLEAR_HANDLER_RESOURCE_TYPES = ("gae_app", "cloud_function")
3738

39+
"""Extra trace label to be added on App Engine environments"""
40+
_GAE_TRACE_ID_LABEL = "appengine.googleapis.com/trace_id"
41+
42+
"""Resource name for App Engine environments"""
43+
_GAE_RESOURCE_TYPE = "gae_app"
44+
3845

3946
class CloudLoggingFilter(logging.Filter):
4047
"""Python standard ``logging`` Filter class to add Cloud Logging
@@ -45,10 +52,6 @@ class CloudLoggingFilter(logging.Filter):
4552
overwritten using the `extras` argument when writing logs.
4653
"""
4754

48-
# The subset of http_request fields have been tested to work consistently across GCP environments
49-
# https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#httprequest
50-
_supported_http_fields = ("requestMethod", "requestUrl", "userAgent", "protocol")
51-
5255
def __init__(self, project=None, default_labels=None):
5356
self.project = project
5457
self.default_labels = default_labels if default_labels else {}
@@ -80,13 +83,6 @@ def filter(self, record):
8083
user_labels = getattr(record, "labels", {})
8184
# infer request data from the environment
8285
inferred_http, inferred_trace, inferred_span = get_request_data()
83-
if inferred_http is not None:
84-
# filter inferred_http to include only well-supported fields
85-
inferred_http = {
86-
k: v
87-
for (k, v) in inferred_http.items()
88-
if k in self._supported_http_fields and v is not None
89-
}
9086
if inferred_trace is not None and self.project is not None:
9187
# add full path for detected trace
9288
inferred_trace = f"projects/{self.project}/traces/{inferred_trace}"
@@ -188,12 +184,17 @@ def emit(self, record):
188184
record (logging.LogRecord): The record to be logged.
189185
"""
190186
message = super(CloudLoggingHandler, self).format(record)
187+
labels = record._labels
188+
resource = record._resource or self.resource
189+
if resource.type == _GAE_RESOURCE_TYPE and record._trace is not None:
190+
# add GAE-specific label
191+
labels = {_GAE_TRACE_ID_LABEL: record._trace, **(labels or {})}
191192
# send off request
192193
self.transport.send(
193194
record,
194195
message,
195-
resource=(record._resource or self.resource),
196-
labels=record._labels,
196+
resource=resource,
197+
labels=labels,
197198
trace=record._trace,
198199
span_id=record._span_id,
199200
http_request=record._http_request,

tests/unit/test_client.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,7 @@ def test_get_default_handler_app_engine(self):
719719
import os
720720
from google.cloud._testing import _Monkey
721721
from google.cloud.logging_v2.handlers._monitored_resources import _GAE_ENV_VARS
722-
from google.cloud.logging.handlers import AppEngineHandler
722+
from google.cloud.logging.handlers import CloudLoggingHandler
723723

724724
credentials = _make_credentials()
725725
client = self._make_one(
@@ -733,10 +733,10 @@ def test_get_default_handler_app_engine(self):
733733

734734
handler.transport.worker.stop()
735735

736-
self.assertIsInstance(handler, AppEngineHandler)
736+
self.assertIsInstance(handler, CloudLoggingHandler)
737737

738738
def test_get_default_handler_container_engine(self):
739-
from google.cloud.logging.handlers import ContainerEngineHandler
739+
from google.cloud.logging.handlers import StructuredLogHandler
740740

741741
credentials = _make_credentials()
742742
client = self._make_one(
@@ -751,7 +751,7 @@ def test_get_default_handler_container_engine(self):
751751
with patch:
752752
handler = client.get_default_handler()
753753

754-
self.assertIsInstance(handler, ContainerEngineHandler)
754+
self.assertIsInstance(handler, StructuredLogHandler)
755755

756756
def test_get_default_handler_general(self):
757757
import io

0 commit comments

Comments
 (0)