【问题标题】:Why is my App Engine app hitting the Stackdriver Logging 256KB limit?为什么我的 App Engine 应用达到 Stackdriver Logging 256KB 限制?
【发布时间】:2020-04-11 09:17:31
【问题描述】:

我正在将 Python 2 App Engine Standard 应用迁移到新的 Python 3 Standard 运行时,即very different。一大区别是您明确使用 Google Cloud API,包括Stackdriver Logging。我正在使用 google-cloud-loggingApp Engine Handler 并将其配置为将日志与 HTTP 请求相关联:

import google.cloud.logging
logging_client = google.cloud.logging.Client()

from google.cloud.logging.handlers import AppEngineHandler, setup_logging
setup_logging(AppEngineHandler(logging_client, name='stdout'))

这很好用!...除了它点击a 256KB log entry limit 并且经常崩溃。下面的堆栈跟踪。这发生在做大量工作的长时间运行的后台请求中,但是当我计算崩溃请求中记录的文本总量(包括字符串时间戳)时,它平均只有 5-15KB 左右,远小于 256KB。 (是的,文档警告This approximate limit is based on internal data sizes,但很难相信开销是 15-50 倍。)

App Engine 处理程序默认为BackgroundThreadTransport。我尝试将其 batch_size 从 10(默认值)降低到 1,然后切换到 SyncTransport,但没有运气。

知道我错过了什么吗?提前谢谢!

Traceback (most recent call last):
  File "/env/lib/python3.7/site-packages/google/cloud/logging/handlers/transports/background_thread.py", line 123, in _safely_commit_batch
    batch.commit()
  File "/env/lib/python3.7/site-packages/google/cloud/logging/logger.py", line 383, in commit
    client.logging_api.write_entries(entries, **kwargs)
  File "/env/lib/python3.7/site-packages/google/cloud/logging/_gapic.py", line 126, in write_entries
    partial_success=partial_success,
  File "/env/lib/python3.7/site-packages/google/cloud/logging_v2/gapic/logging_service_v2_client.py", line 477, in write_log_entries
    request, retry=retry, timeout=timeout, metadata=metadata
  File "/env/lib/python3.7/site-packages/google/api_core/gapic_v1/method.py", line 143, in __call__
    return wrapped_func(*args, **kwargs)
  File "/env/lib/python3.7/site-packages/google/api_core/retry.py", line 277, in retry_wrapped_func
    on_error=on_error,
  File "/env/lib/python3.7/site-packages/google/api_core/retry.py", line 182, in retry_target
    return target()
  File "/env/lib/python3.7/site-packages/google/api_core/timeout.py", line 214, in func_with_timeout
    return func(*args, **kwargs)
  File "/env/lib/python3.7/site-packages/google/api_core/grpc_helpers.py", line 59, in error_remapped_callable
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.InvalidArgument: 400 Log entry with size 258.3K exceeds maximum size of 256.0K

【问题讨论】:

  • 您超出了 Stackdriver 条目的最大大小。您需要缩小对 Stackdriver 发出的每个请求(小于 256 KB)。由于您没有向您展示代码和为 Stackdriver 生成的日志记录数据,因此我无法告诉您要更改什么。
  • 谢谢!是的,我明白这一点,但我没有明确向 Stackdriver 提出请求。我正在使用google.cloud.logging.handlers.AppEngineHandler,如问题中所述,然后仅使用logging.info(...) 等调用,每个HTTP 请求最多仅累积5-15KB 的文本。
  • 在您的问题中,logging.info(...) 的示例在哪里?展示我们可以帮助您的东西。
  • 同意!孤立的可重现测试用例绝对是理想的。不过,它们并不总是现实的,我这里也没有。我还没有在生产之外复制这个,可能是因为它是由于 HTTP 请求的交互。这可以解释它如何在每个 Stackdriver 请求中积累如此多的数据,而不是任何单个 HTTP 请求的日志。不过我不知道。我希望任何熟悉google.cloud.logging 和我在这里使用的AppEngineHandler 的人都能在这里获得见解。

标签: python-3.x google-app-engine google-cloud-platform google-app-engine-python google-cloud-stackdriver


【解决方案1】:

Stackdriver Log Entry Size 构成硬限制,已从 100KB 扩展到 256KB(参见Public Issue TrackerRelease Notes 上的帖子)。

作为一种解决方法,您可以探索多个阶段的日志记录,以避免出现此限制错误。您可以将单个条目拆分为多个条目并照此记录。

此外,您可以将应用程序中的完整日志直接存储在 Cloud Storage 上,并且只将部分日志发送到 Stackdriver,这足以让您知道您是否对完整日志感兴趣行与否。通常,如果您只能在 Stackdriver 中存储最少的信息并使用不同的存储系统(云存储中的存储桶、spanner 或 CloudSQL db,或任何其他 SQL 或非 SQL 数据库)来存储更详细的信息,那会更好,然后用 UUID 将两者链接起来。

此外,为方便起见,我建议您排除不必要的日志以最小化文件大小。 (见Log ExclusionsPreventing Log Waste)。之前也可以export these excluded log entries,以免永久丢失。

希望这些信息对您有用。

【讨论】:

  • 感谢您的回复!我很感激。不过,我绝对知道这一切。如前所述,我使用的是google.cloud.logging.handlers.AppEngineHandler,没有明确向 Stackdriver 发出请求,因此我无法查看或控制它发送的日志条目。更重要的是,我每个 HTTP 请求最多只记录约 5-15KB 的文本,远不及 256KB,所以我怀疑AppEngineHandler 正在收集多个 HTTP 请求的日志。我还没有找到控制或禁用它的方法。
猜你喜欢
  • 2018-04-23
  • 1970-01-01
  • 1970-01-01
  • 2020-04-16
  • 1970-01-01
  • 1970-01-01
  • 2020-01-06
  • 2015-08-11
  • 1970-01-01
相关资源
最近更新 更多