我有一个使用 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 调用也是如此。
我认为您需要在应用程序代码中手动传播跟踪上下文。我遇到了类似的问题。我从标头中获取了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)
对于我来说,传播跟踪父项已经成功,我现在可以在一条跟踪中看到我的所有跨度。我不确定这是否是最好的解决方案,但我希望它有所帮助。