gpt4 book ai didi

Google Kubernetes Engine 上的 Django、Apache2 将 Opencensus Traces 写入 Stackdriver Trace

转载 作者:行者123 更新时间:2023-12-03 14:29:58 28 4
gpt4 key购买 nike

我有一个从 Apache2 提供的 Django Web 应用程序,在 Docker 容器中使用 mod_wsgi,该容器运行在 Google Cloud Platform 的 Kubernetes 集群上,受 Identity-Aware Proxy 保护。一切都很好,但我想为所有请求发送 GCP Stackdriver 跟踪,而不是为我的项目中的每个 View 编写一个。我使用 Opencensus 找到了处理这个问题的中间件。我经历了this documentation ,并且能够通过指定 StackdriverExporter 在我的项目中手动生成导出到 Stackdriver Trace 的跟踪。并通过 project_id参数为 Google Cloud Platform Project Number对于我的项目。

现在为了让所有请求都自动完成,我按照说明设置了中间件。在 settings.py 中,我将模块添加到 INSTALLED_APPS , MIDDLEWARE , 并设置 OPENCENSUS_TRACE选项字典。我还添加了 OPENCENSUS_TRACE_PARAMS .这适用于默认导出器“opencensus.trace.exporters.print_exporter.PrintExporter”,因为我可以在我的 Apache2 Web 服务器日志中看到 Trace 和 Span 信息,包括 Trace ID 和所有详细信息。但是,我想将这些发送到我的 Stackdriver Trace 处理器进行分析。

我尝试设置 EXPORTER opencensus.trace.exporters.stackdriver_exporter.StackdriverExporter 的参数,只要您提供项目编号,它就可以在从 shell 手动运行时工作。

当它设置为使用 StackdriverExporter ,网页不会响应加载,健康检查开始失败,最终网页返回 502 错误,说明我应该在 30 秒后重试(我相信 Identity-Aware Proxy 正在生成此错误,一次它检测到失败的健康检查),但服务器没有生成错误,并且没有访问日志或 Apache2 错误。

settings.py 中有另一个字典,名为 OPENCENSUS_TRACE_PARAMS ,我认为需要确定导出商应该使用哪个项目编号。该示例有 GCP_EXPORTER_PROJECT设为None , 和 SERVICE_NAME设为'my_service' .

我需要设置哪些选项才能让导出器发送回 Stackdriver 而不是打印到日志?你知道我该如何设置吗?

设置.py

MIDDLEWARE = (
...
'opencensus.trace.ext.django.middleware.OpencensusMiddleware',
)
INSTALLED_APPS = (
...
'opencensus.trace.ext.django',
)

OPENCENSUS_TRACE = {
'SAMPLER': 'opencensus.trace.samplers.probability.ProbabilitySampler',
'EXPORTER': 'opencensus.trace.exporters.stackdriver_exporter.StackdriverExporter', # This one just makes the server hang with no response or error and kills the health check.
'PROPAGATOR': 'opencensus.trace.propagation.google_cloud_format.GoogleCloudFormatPropagator',
# 'EXPORTER': 'opencensus.trace.exporters.print_exporter.PrintExporter', # This one works to print the Trace and Span with IDs and details in the logs.
}

OPENCENSUS_TRACE_PARAMS = {
'BLACKLIST_PATHS': ['/health'],
'GCP_EXPORTER_PROJECT': 'my_project_number', # Should this be None like the example, or Project ID, or Project Number?
'SAMPLING_RATE': 0.5,
'SERVICE_NAME': 'my_service', # Not sure if this is my app name or some other service name.
'ZIPKIN_EXPORTER_HOST_NAME': 'localhost', # Are the following even necessary, or are they causing a failure that is not detected by Apache2?
'ZIPKIN_EXPORTER_PORT': 9411,
'ZIPKIN_EXPORTER_PROTOCOL': 'http',
'JAEGER_EXPORTER_HOST_NAME': None,
'JAEGER_EXPORTER_PORT': None,
'JAEGER_EXPORTER_AGENT_HOST_NAME': 'localhost',
'JAEGER_EXPORTER_AGENT_PORT': 6831
}

这是 Apache2 日志设置为使用 PrintExporter 时的示例(我美化了格式以提高可读性)。 :
[Fri Feb 08 09:00:32.427575 2019]
[wsgi:error]
[pid 1097:tid 139801302882048]
[client 10.48.0.1:43988]
[SpanData(
name='services.views.my_view',
context=SpanContext(
trace_id=e882f23e49e34fc09df621867d753532,
span_id=None,
trace_options=TraceOptions(enabled=True),
tracestate=None
),
span_id='bcbe7b96906a482a',
parent_span_id=None,
attributes={
'http.status_code': '200',
'http.method': 'GET',
'http.url': '/',
'django.user.name': ''
},
start_time='2019-02-08T17:00:29.845733Z',
end_time='2019-02-08T17:00:32.427455Z',
child_span_count=0,
stack_trace=None,
time_events=[],
links=[],
status=None,
same_process_as_parent_span=None,
span_kind=1
)]

提前感谢您提供任何提示、帮助或故障排除建议!

UTC 时间 2019 年 2 月 8 日下午 6:56 编辑:

我在中间件中找到了这个:
# Initialize the exporter
transport = convert_to_import(settings.params.get(TRANSPORT))

if self._exporter.__name__ == 'GoogleCloudExporter':
_project_id = settings.params.get(GCP_EXPORTER_PROJECT, None)
self.exporter = self._exporter(
project_id=_project_id,
transport=transport)
elif self._exporter.__name__ == 'ZipkinExporter':
_service_name = self._get_service_name(settings.params)
_zipkin_host_name = settings.params.get(
ZIPKIN_EXPORTER_HOST_NAME, 'localhost')
_zipkin_port = settings.params.get(
ZIPKIN_EXPORTER_PORT, 9411)
_zipkin_protocol = settings.params.get(
ZIPKIN_EXPORTER_PROTOCOL, 'http')
self.exporter = self._exporter(
service_name=_service_name,
host_name=_zipkin_host_name,
port=_zipkin_port,
protocol=_zipkin_protocol,
transport=transport)
elif self._exporter.__name__ == 'TraceExporter':
_service_name = self._get_service_name(settings.params)
_endpoint = settings.params.get(
OCAGENT_TRACE_EXPORTER_ENDPOINT, None)
self.exporter = self._exporter(
service_name=_service_name,
endpoint=_endpoint,
transport=transport)
elif self._exporter.__name__ == 'JaegerExporter':
_service_name = self._get_service_name(settings.params)
self.exporter = self._exporter(
service_name=_service_name,
transport=transport)
else:
self.exporter = self._exporter(transport=transport)

导出商现在被命名为 StackdriverExporter , 而不是 GoogleCloudExporter .我在我的应用程序中设置了一个名为 GoogleCloudExporter 的类(class)继承 StackdriverExporter ,并更新了我的 settings.py 以使用 GoogleCloudExporter ,但它似乎没有工作,我想知道是否有其他代码引用这些旧命名方案,可能用于传输。我正在寻找源代码中的线索...这至少告诉我我可以摆脱 ZIPKIN 和 JAEGER 参数选项,因为这是在 EXPORTER 上确定的。参数。

编辑 2019-02-08 晚上 11:58 UTC:

我放弃了 Apache2 来隔离问题,只是将我的 docker 镜像设置为使用 Django 的内置网络服务器 CMD ["python", "/path/to/manage.py", "runserver", "0.0.0.0:80"]它有效!当我访问该站点时,它会为每个请求将跟踪写入 Stackdriver Trace,Span 名称是正在执行的模块和方法。

不知何故 Apache2 不允许发送这些,但我可以在以 root 身份运行时从 shell 发送这些。我在问题中添加了 Apache2 和 mod-wsgi 标签,因为我有一种有趣的感觉,这与 Apache2 和 mod-WSGI 中的子进程 fork 有关。由于 apache2 的子进程是沙盒的,因此无法创建子进程,或者这可能是权限问题?这似乎很奇怪,因为我知道它只是调用 python 模块,没有外部系统操作系统二进制文件。任何其他想法将不胜感激!

最佳答案

我在使用带有 gevent 作为 worker 类(Class)的 gunicorn 时遇到了这个问题。要解决并使云跟踪工作,解决方案是像这样猴子补丁 grpc

from gevent import monkey
monkey.patch_all()

import grpc.experimental.gevent as grpc_gevent
grpc_gevent.init_gevent()

https://github.com/grpc/grpc/issues/4629#issuecomment-376962677

关于Google Kubernetes Engine 上的 Django、Apache2 将 Opencensus Traces 写入 Stackdriver Trace,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54597464/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com