Gunicorn 和 Falcon 上的 OpenTelemetry 未正确显示跨度

问题描述 投票:0回答:1

我有一个使用 Falcon 和 Gunicorn 组合运行的应用程序。我正在尝试使用 OpenTelemetry 来检测它并将跟踪发送到 Jaeger。

以下是我的代码:

pyproject.toml:

opentelemetry-distro = {extras = ["otlp"], version = "0.44b0" }
opentelemetry-instrumentation = "0.44b0"
opentelemetry-instrumentation-falcon = "0.44b0"

gunicorn_conf.py:

from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

def post_fork(server, worker):
    from opentelemetry.instrumentation.auto_instrumentation import sitecustomize
    server.log.info("Worker spawned (pid: %s)", worker.pid)

    resource = Resource.create(attributes={
        "service.name": "my-app"
    })

    trace.set_tracer_provider(TracerProvider(resource=resource))
    span_processor = BatchSpanProcessor(
        OTLPSpanExporter(endpoint=telemetry_endpoint, insecure=telemetry_insecure)
    )
    trace.get_tracer_provider().add_span_processor(span_processor)

启动命令:

OTEL_RESOURCE_ATTRIBUTES=service.name={app_name} OTEL_EXPORTER_OTLP_TRACES_ENDPOINT={telemetry_endpoint} OTEL_EXPORTER_OTLP_METRICS_ENDPOINT={telemetry_endpoint} OTEL_EXPORTER_OTLP_INSECURE={telemetry_insecure} OTEL_TRACES_EXPORTER=otlp OTEL_METRICS_EXPORTER=none opentelemetry-instrument gunicorn -c gunicorn_conf.py

因此应用程序运行,然后跟踪出现在 Jaeger 上,但显示为单个函数调用,而不是多个调用,即使存在数据库调用或外部 api 调用也是如此。

Attached image for reference

python gunicorn open-telemetry otel falcon
1个回答
0
投票

我认为您需要在应用程序代码中手动传播跟踪上下文。我遇到了类似的问题。我从标头中获取了traceparentid(在我的例子中是接收kafka消息的标头):

        value = headers_dict['traceparent']
        value_string =value.decode('utf-8')
        carrier ={'traceparent':value_string}
        ctx = TraceContextTextMapPropagator().extract(carrier=carrier)

以下代码使用 http 调用,因此我还确保在生成的跟踪中提供 ctx,如下所示:

def getLocationDetails(self, ctx, headers):
        tracer = trace.get_tracer(__name__)
      
        with tracer.start_span("get geo data", context=ctx):
            try:
                response = requests.request("GET", self.url, headers=headers, data=payload)
                ...
                return location_data
            
            except HTTPError as http_err:
                
                return http_err

然后还将 ctx 包含在我用来创建用于发送 kafka 消息的跨度的跟踪器中。

  def send(self, topic, key, message,ctx, header):
        tracer = trace.get_tracer(__name__)
        with tracer.start_span("send kafka message", context=ctx):
            self.producer.send(topic, value=message, key=key, headers=header)

对于我来说,传播跟踪父项已经成功,我现在可以在一条跟踪中看到我的所有跨度。我不确定这是否是最好的解决方案,但我希望它有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.