首页 > 解决方案 > App Engine 堆栈驱动程序记录到全局日志而不是服务日志

问题描述

我正在尝试为在 GAE 上作为 App Engine 服务托管的 django 应用程序设置日志记录。

我已成功设置日志记录,但日志记录显示在整个项目的全局日志中,而不是该服务的日志中。我希望日志只显示在特定的服务日志中

这是我的 django 日志配置:

from google.cloud import logging as google_cloud_logging


log_client = google_cloud_logging.Client()
log_client.setup_logging()

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'stackdriver_logging': {
            'class': 'google.cloud.logging.handlers.CloudLoggingHandler',
            'client': log_client
        },
    },
    'loggers': {
        '': {
            'handlers': ['stackdriver_logging'],
            'level': 'INFO',
        }
    },
}

我可以通过这样的调用成功登录到全局项目日志:

def fetch_orders(request):
    logger.error('test error')
    logger.critical('test critical')
    logger.warning('test warning')
    logger.info('test info')
    return redirect('dashboard')

我想知道是否可以将记录器配置为始终将日志用于正在运行的服务。

编辑:

我尝试了下面的建议,但是现在它返回以下错误:

Traceback (most recent call last):
  File "/env/lib/python3.7/site-packages/google/cloud/logging/handlers/transports/background_thread.py", line 122, in _safely_commit_batch
    batch.commit()
  File "/env/lib/python3.7/site-packages/google/cloud/logging/logger.py", line 381, in commit
    entries = [entry.to_api_repr() for entry in self.entries]
  File "/env/lib/python3.7/site-packages/google/cloud/logging/logger.py", line 381, in <listcomp>
    entries = [entry.to_api_repr() for entry in self.entries]
  File "/env/lib/python3.7/site-packages/google/cloud/logging/entries.py", line 318, in to_api_repr
    info = super(StructEntry, self).to_api_repr()
  File "/env/lib/python3.7/site-packages/google/cloud/logging/entries.py", line 241, in to_api_repr
    info["resource"] = self.resource._to_dict()
AttributeError: 'ConvertingDict' object has no attribute '_to_dict'

我可以在包源代码中覆盖它以使其工作,但是 GAE 环境要求我使用 google 提供的包来进行云日志记录。有什么办法可以从这里出发吗?

标签: djangogoogle-app-engineloggingstackdriver

解决方案


据我了解,使用CloudLoggingHandlerresource选项应该可以完成您想要的操作。在 Stackdriver Logging(和 Stackdriver Monitoring)API 中,每个对象(日志行、时间序列点)都与一个“资源”(项目中存在的、可以配置的、可以作为日志来源的东西)相关联或时间序列或正在写入日志或时间序列的事物)。当省略该选项时,默认为您所观察到的。resourceCloudLoggingHandlerglobal

有许多受监控的资源类型,包括gae_app,可用于表示部署在 GAE 上的特定服务的特定版本。根据您的代码,这看起来像:

from google.cloud.logging import resource


def get_monitored_resource():
  project_id = get_project_id()
  gae_service = get_gae_service()
  gae_service_version = get_gae_service_version()
  resource_type = 'gae_app'
  resource_labels = {
    'project_id': project_id,
    'module_id': gae_service,
    'version_id': gae_service_version
  }
  return resource.Resource(resource_type, resource_labels)


GAE_APP_RESOURCE = get_monitored_resource() 
LOGGING = {
    # ...
    'handlers': {
        'stackdriver_logging': {
            'class': 'google.cloud.logging.handlers.CloudLoggingHandler',
            'client': log_client,
            'resource': GAE_APP_RESOURCE,
        },
    },
    # ...
}

在上面的代码中,函数get_project_id,get_gae_serviceget_gae_service_version可以根据环境变量GOOGLE_CLOUD_PROJECT,GAE_SERVICEGAE_VERSION在 Python 灵活环境中实现,如灵活 Python 运行时所述,如下所示:

def get_project_id():
  return os.getenv('GOOGLE_CLOUD_PROJECT')

推荐阅读