跟踪#

为了帮助调试和监控 Ray 应用,Ray 集成了 OpenTelemetry,以便将跟踪导出到 Jaeger 等外部跟踪栈。

注意

跟踪是一项 Alpha 功能,已不再积极开发/维护。API 可能会发生变化。

安装#

首先,安装 OpenTelemetry

pip install opentelemetry-api==1.1.0
pip install opentelemetry-sdk==1.1.0
pip install opentelemetry-exporter-otlp==1.1.0

跟踪启动钩子#

要启用跟踪,必须提供一个跟踪启动钩子,其中包含一个函数,该函数设置跟踪器提供者(Tracer Provider)远程 Span 处理器(Remote Span Processors)附加 Instrumentation(Additional Instruments)。跟踪启动钩子应该是一个不带 args 或 kwargs 的函数。这个钩子需要在所有 worker 进程的 Python 环境中可用。

下面是一个跟踪启动钩子示例,它设置了默认的跟踪提供者,将 span 导出到 /tmp/spans 目录下的文件中,并且没有任何附加 Instrumentation。

import ray
import os
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
    ConsoleSpanExporter,
    SimpleSpanProcessor,
)


def setup_tracing() -> None:
    # Creates /tmp/spans folder
    os.makedirs("/tmp/spans", exist_ok=True)
    # Sets the tracer_provider. This is only allowed once per execution
    # context and will log a warning if attempted multiple times.
    trace.set_tracer_provider(TracerProvider())
    trace.get_tracer_provider().add_span_processor(
        SimpleSpanProcessor(
            ConsoleSpanExporter(
                out=open(f"/tmp/spans/{os.getpid()}.json", "a")
                )
        )
    )

对于想要尝试跟踪的开源用户,Ray 提供了一个默认的跟踪启动钩子,它将 span 导出到 /tmp/spans 文件夹。要使用此默认钩子运行,请运行以下代码示例来设置跟踪并跟踪一个简单的 Ray 任务。

$ ray start --head --tracing-startup-hook=ray.util.tracing.setup_local_tmp_tracing:setup_tracing
$ python
    ray.init()
    @ray.remote
    def my_function():
        return 1

    obj_ref = my_function.remote()
ray.init(_tracing_startup_hook="ray.util.tracing.setup_local_tmp_tracing:setup_tracing")

@ray.remote
def my_function():
    return 1

obj_ref = my_function.remote()

如果你想提供自己的自定义跟踪启动钩子,请使用 module:attribute 格式提供,其中 attribute 是要运行的 setup_tracing 函数。

跟踪器提供者#

这配置了如何收集跟踪。在此处查看 TracerProvider API here

远程 Span 处理器#

这配置了将跟踪导出到何处。在此处查看 SpanProcessor API here

想要尝试跟踪的用户可以配置他们的远程 Span 处理器将 span 导出到本地 JSON 文件。本地开发的高级用户可以通过 Jaeger exporter 将他们的跟踪推送到 Jaeger 容器。

附加 Instrumentation#

如果你正在使用具有内置跟踪支持的库,你提供的 setup_tracing 函数也应该修补这些库。你可以在 here 找到这些库的 Instrumentation 的更多文档。

自定义跟踪#

在你的程序中添加自定义跟踪。在程序内部,使用 trace.get_tracer(__name__) 获取 tracer 对象,并使用 tracer.start_as_current_span(...) 启动一个新的 span。

参见下文获取添加自定义跟踪的简单示例。

from opentelemetry import trace

@ray.remote
def my_func():
    tracer = trace.get_tracer(__name__)

    with tracer.start_as_current_span("foo"):
        print("Hello world from OpenTelemetry Python!")