python-3.x - 如何对相关请求日志条目进行分组 GAE python 3.7 标准环境

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

我使用的是 Google App Engine python 3.7 标准,我正在尝试对相关的请求日志条目进行分组。 根据Writing Application Logs文档,我应该:

Set the trace identifier in the LogEntry trace field of your app log entries. The expected format is projects/[PROJECT_ID]/traces/[TRACE_ID]

应该在哪里/如何使用 LogEntry?

Stackdriver Logging documentation没有说明这是怎么可能的。我错过了什么吗?

代码示例将不胜感激。

[更新] 正在关注Duck Hunt Duo建议,我尝试了以下方法,但没有成功:

    trace_id = request.headers.get('X-Cloud-Trace-Context', 'no_trace_id').split('/')[0]
    client = logging.Client()
    logger = client.logger('appengine.googleapis.com%2Fstdout')  # Not shown
    # logger = client.logger('projects/{}/logs/stdout'.format(GOOGLE_CLOUD_PROJECT)) # error
    # logger = client.logger('projects/{}/logs/appengine.googleapis.com%2Fstdout'.format(GOOGLE_CLOUD_PROJECT)) # error

    logger.log_text('log_message', trace=trace_id)

日志未出现在 GAE service log web console

最佳答案

这是我的基本解决方案:

    trace_id = request.headers.get('X-Cloud-Trace-Context', 'no_trace_id').split('/')[0]
    trace_str = "projects/{}/traces/{}".format(os.getenv('GOOGLE_CLOUD_PROJECT'), trace_id)
    log_client = logging.Client()

    # This is the resource type of the log
    log_name = 'stdout'

    # Inside the resource, nest the required labels specific to the resource type
    labels = {
        'module_id': os.getenv('GAE_SERVICE'),
        'project_id': os.getenv('GOOGLE_CLOUD_PROJECT'),
        'version_id': os.getenv('GAE_VERSION')
    }
    res = Resource(type="gae_app",
                   labels=labels,
                   )
    logger = log_client.logger(log_name)
    logger.log_text("MESSAGE_STRING_TO_LOG", resource=res, severity='ERROR', trace=trace_str)

在它开始工作后,我将它包装在一个文件中,这样它就可以像谷歌的 python2.7 记录器一样工作。

这是 my_gae_logging.py:

import logging as python_logging
import os

from flask import request
from google.cloud import logging as gcp_logging
from google.cloud.logging.resource import Resource

# From GCP logging lib for Python2.7
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

_levelNames = {
    CRITICAL: 'CRITICAL',
    ERROR: 'ERROR',
    WARNING: 'WARNING',
    INFO: 'INFO',
    DEBUG: 'DEBUG',
    NOTSET: 'NOTSET',
    'CRITICAL': CRITICAL,
    'ERROR': ERROR,
    'WARN': WARNING,
    'WARNING': WARNING,
    'INFO': INFO,
    'DEBUG': DEBUG,
    'NOTSET': NOTSET,
}


def get_trace_id():
    trace_str = None
    try:
        trace_id = request.headers.get('X-Cloud-Trace-Context', 'no_trace_id').split('/')[0]
        trace_str = "projects/{project_id}/traces/{trace_id}".format(
            project_id=os.getenv('GOOGLE_CLOUD_PROJECT'),
            trace_id=trace_id)
    except:
        pass
    return trace_str


class Logging:
def __init__(self):
    self._logger = None

@property
def logger(self):
    if self._logger is not None:
        return self._logger

    log_client = gcp_logging.Client()

    # This is the resource type of the log
    log_name = 'appengine.googleapis.com%2Fstdout'

    # Inside the resource, nest the required labels specific to the resource type

    self._logger = log_client.logger(log_name)
    return self._logger

@property
def resource(self):
    resource = Resource(
        type="gae_app",
        labels={
            'module_id': os.getenv('GAE_SERVICE'),
            'project_id': os.getenv('GOOGLE_CLOUD_PROJECT'),
            'version_id': os.getenv('GAE_VERSION')
        }
    )
    return resource

def log(self, text):
    text = str(text)
    self.logger.log_text(text, resource=self.resource, trace=get_trace_id())

def debug(self, text):
    text = str(text)
    self.logger.log_text(text, resource=self.resource, severity=_levelNames.get(DEBUG), trace=get_trace_id())

def info(self, text):
    text = str(text)
    self.logger.log_text(text, resource=self.resource, severity=_levelNames.get(INFO), trace=get_trace_id())

def warning(self, text):
    text = str(text)
    self.logger.log_text(text, resource=self.resource, severity=_levelNames.get(WARNING), trace=get_trace_id())

def warn(self, text):
    return self.warning(text)

def error(self, text):
    text = str(text)
    self.logger.log_text(text, resource=self.resource, severity=_levelNames.get(ERROR), trace=get_trace_id())

def critical(self, text):
    text = str(text)
    self.logger.log_text(text, resource=self.resource, severity=_levelNames.get(CRITICAL), trace=get_trace_id())


if os.getenv('GAE_VERSION'):  # check if running under gcp env
    logging = Logging()
else:
    # when not running under gcp env, use standard python_logging
    logging = python_logging

用法:

from my_gae_logging import logging

logging.warn('this is my warning')

关于python-3.x - 如何对相关请求日志条目进行分组 GAE python 3.7 标准环境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56113604/

相关文章:

python - scipy.misc.factorial : The truth value of an array with more than one element is ambiguous. 使用 a.any() 或 a.all()

python - 没有 sys 或 os 的相对导入校正

google-app-engine - 在 Datastore 中搜索 10 个最近的位置

logging - Phoenix 删除 [调试] 日志记录

python - 在 Android 上的 Kivy Launcher 中启动应用程序时生成的日志

java - 如何为记录器生成实例?

python - 弹性 beantalk 需要 python 3.5

java - 从 GAE/J 调用 SOAP 服务

unit-testing - 谷歌应用引擎 + GWT + Eclipse : where do your unit tests live?

Python subprocess.Popen + ffmpeg 中断终端输入