Python 3.x Google云日志、Python3.8标准环境、按跟踪id列出的组请求相关日志

Python 3.x Google云日志、Python3.8标准环境、按跟踪id列出的组请求相关日志,python-3.x,google-app-engine,google-cloud-logging,Python 3.x,Google App Engine,Google Cloud Logging,在Google App Engine标准环境中为Python3.8安装Google云日志时,我遇到了这个问题。 我正在对unicorn使用FastAPI。我的代码日志记录配置: import logging.config import sys from google.cloud import logging as google_logging from app.settings import ENV, _settings if _settings.ENV == ENV.LOCAL:

在Google App Engine标准环境中为Python3.8安装Google云日志时,我遇到了这个问题。 我正在对unicorn使用FastAPI。我的代码日志记录配置:

import logging.config
import sys

from google.cloud import logging as google_logging

from app.settings import ENV, _settings


if _settings.ENV == ENV.LOCAL:
    MAIN_LOGGER = 'console'
    LOGGER_CONF_DICT = {
        'class': 'logging.StreamHandler',
        'formatter': 'verbose',
        'stream': sys.stdout,
        'level': _settings.LOG_LEVEL.upper(),
    }
else:
    log_client = google_logging.Client()
    MAIN_LOGGER = 'stackdriver_logging'
    LOGGER_CONF_DICT = {
        'class': 'app.gcloud_logs.GCLHandler',
        'client': log_client,
        'name': 'appengine.googleapis.com%2Frequest_log'
        # I've tried other names: stdout, %2FA instead of / symbol, appengine.googleapis.com/stdout
        # the same result or no logs at all
    }

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(log_color)s%(asctime)s [%(levelname)s] [%(name)s] %(message)s (%(filename)s:%(lineno)d)',
            '()': 'colorlog.ColoredFormatter',
            'log_colors': {
                'DEBUG': 'cyan',
                'INFO': 'green',
                'WARNING': 'yellow',
                'ERROR': 'red',
                'CRITICAL': 'bold_red',
            },
        }
    },
    'handlers': {
        MAIN_LOGGER: {**LOGGER_CONF_DICT},
        'blackhole': {'level': 'DEBUG', 'class': 'logging.NullHandler'},
    },
    'loggers': {
        'fastapi': {'level': 'INFO', 'handlers': [MAIN_LOGGER]},
        'uvicorn.error': {'level': 'INFO', 'handlers': [MAIN_LOGGER], 'propagate': False},
        'uvicorn.access': {'level': 'INFO', 'handlers': [MAIN_LOGGER], 'propagate': False},
        'uvicorn': {'level': 'INFO', 'handlers': [MAIN_LOGGER], 'propagate': False},
        'google.cloud.logging.handlers.transports.background_thread': {'level': 'DEBUG', 'handlers': ['blackhole'],
                                                                       'propagate': False},
        '': {
            'level': _settings.LOG_LEVEL.upper(),
            'handlers': [MAIN_LOGGER],
            'propagate': True,
        },

    }
}

logging.config.dictConfig(LOGGING)
和我的日志处理程序代码:

import os
from typing import Any, Dict, Optional

from google.cloud.logging.handlers import CloudLoggingHandler
from google.cloud.logging.resource import Resource
from starlette.requests import Request
from starlette_context import context

from app.settings import _settings


class GCLHandler(CloudLoggingHandler):
    def emit(self, record):
        message = super(GCLHandler, self).format(record)
        request: Optional[Request] = None
        trace: Optional[str] = None
        span_id: Optional[str] = None
        user_id: Optional[int] = None
        resource = Resource(
            type='gae_app',
            labels={
                'module_id': os.environ['GAE_SERVICE'],
                'project_id': _settings.PROJECT_NAME,
                'version_id': os.environ['GAE_VERSION'],
                'zone': 'us16'  # tried without zone - the same result
            }
        )

        labels: Dict[str, Any] = {}

        if context.exists():  # I'm sure that it works
            request = context.get('request')  # I'm sure that it works
            user_id = context.get('user_id')  # I'm sure that it works

        if user_id is not None:
            labels['user_id'] = user_id

        if request:
            if request.headers.get('X-Cloud-Trace-Context'):
                cloud_trace = request.headers.get('X-Cloud-Trace-Context').split('/')
                if len(cloud_trace) > 1:
                    span_id = cloud_trace[1].split(';')[0]

                trace = f'projects/{_settings.PROJECT_NAME}/traces/{cloud_trace[0]}'
                labels['logging.googleapis.com/trace'] = cloud_trace[0]  # Found in some guides, not sure that its neccessary
                labels['appengine.googleapis.com/trace_id'] = cloud_trace[0]  # Found in some guides, not sure that its neccessary

        self.transport.send(
            record,
            message,
            resource=resource,
            labels=labels,
            trace=trace,
            span_id=span_id
        )
我在logs viewer中得到一些奇怪的结果,我的日志与请求日志具有相同的跟踪,但它们没有分组


有什么想法吗?

登录有两种类型:

  • 请求日志:发送到应用程序的请求日志。应用程序引擎会自动在请求日志中创建条目

  • 应用程序日志:如本页所述,记录写入受支持框架或文件的条目

这两个日志都由App Engine Standard自动发送到云日志代理

在第一次请求时,应用程序日志和请求日志不相关,这就是为什么没有在组中显示,这是一个错误。但是,在第二个请求中,您可以看到日志显示在一个组中

已为此行为创建了中的功能请求,您将从中获得有关修复的所有更新

log_client = google_logging.Client()
MAIN_LOGGER = 'stackdriver_logging'
LOGGER_CONF_DICT = {
    'class': 'app.gcloud_logs.GCLHandler',
    'client': log_client,
    'name': 'app'
}

将名称更改为
app
有帮助

请求日志的严重性(日志级别)是多少?它是“any”还是基于子(嵌套)日志的日志严重性?您好,您能告诉我如何设置请求日志的严重性吗?我可以使用跟踪对它们进行分组,但是请求日志的严重性总是“Any”,它应该等于子(嵌套)日志的最高严重性级别