产品评论服务
此服务负责返回产品评论,并根据产品描述和评论回答有关特定产品的问题。
它使用一个兼容 OpenAI 的 LLM 来回答终端用户关于特定产品的问题。
产品评论存储在数据库(PostgreSQL)中。
LLM 配置
默认情况下,此服务使用符合 OpenAI API 格式的模拟 LLM。通过在 .env.override 文件中填充以下环境变量,可以将其替换为实际的 OpenAI LLM。
LLM_BASE_URL=https://api.openai.com/v1
LLM_MODEL=gpt-4o-mini
OPENAI_API_KEY=<replace with API key>
自动仪表化
此基于 Python 的服务利用 OpenTelemetry 自动检测器(auto-instrumentor)来实现,这是通过利用 opentelemetry-instrument Python 包装器来运行脚本完成的。这可以在服务 Dockerfile 的 ENTRYPOINT 命令中完成。
ENTRYPOINT [ "opentelemetry-instrument", "python", "product_reviews_server.py" ]
追踪
初始化追踪
OpenTelemetry SDK 在 __main__ 代码块中初始化。此代码将创建一个跟踪器提供程序(tracer provider),并建立一个 Span Processor 来使用。导出终结点、资源属性和服务名称会根据环境变量由 OpenTelemetry 自动检测器自动设置。
tracer = trace.get_tracer_provider().get_tracer("product-reviews")
为自动仪表化的 Span 添加属性
在自动仪表化代码的执行过程中,您可以从上下文中获取当前的 Span。
span = trace.get_current_span()
通过使用 Span 对象上的 set_attribute 来添加属性到 Span。在 get_product_reviews 函数中,会向 Span 添加一个属性来捕获请求中传递的产品 ID。
span.set_attribute("app.product.id", request_product_id)
创建新跨度
可以使用 OpenTelemetry Tracer 对象中的 start_as_current_span 来创建新的 Span 并将其放入活动上下文中。当与 with 块结合使用时,Span 会在块结束执行时自动结束。这在 get_product_reviews 函数中完成。
with tracer.start_as_current_span("get_product_reviews") as span:
指标
初始化指标
OpenTelemetry SDK 在 __main__ 代码块中初始化。此代码将创建一个 Meter Provider。导出终结点、资源属性和服务名称会根据环境变量由 OpenTelemetry 自动检测器自动设置。
meter = metrics.get_meter_provider().get_meter("product-reviews")
自定义指标
目前提供以下自定义指标
app_product_review_counter: 服务返回的产品评论数量的累积计数。app_ai_assistant_counter: 发送到产品 AI 助手(product AI Assistant)的总问题数量的累积计数。
自动检测的指标
以下指标通过自动检测器提供,这是 opentelemetry-instrumentation-system-metrics 的功劳,该库在构建产品评论服务 Docker 镜像时作为 opentelemetry-bootstrap 的一部分安装。
runtime.cpython.cpu_timeruntime.cpython.memoryruntime.cpython.gc_count
日志
初始化日志
OpenTelemetry SDK 在 __main__ 代码块中初始化。以下代码创建一个具有批处理处理器(batch processor)、OTLP 日志导出器(exporter)和日志处理程序(handler)的日志提供程序(logger provider)。最后,它创建一个供应用程序使用的日志记录器(logger)。
logger_provider = LoggerProvider(
resource=Resource.create(
{
'service.name': service_name,
}
),
)
set_logger_provider(logger_provider)
log_exporter = OTLPLogExporter(insecure=True)
logger_provider.add_log_record_processor(BatchLogRecordProcessor(log_exporter))
handler = LoggingHandler(level=logging.NOTSET, logger_provider=logger_provider)
logger = logging.getLogger('main')
logger.addHandler(handler)
创建日志记录
使用日志记录器创建日志。可以在 get_ai_assistant_response 函数中找到示例。
logger.info(f"Model wants to call {len(tool_calls)} tool(s)")
如您所见,初始化后,日志记录的创建方式与标准 Python 相同。OpenTelemetry 库会自动为每个日志记录添加跟踪 ID 和 Span ID,从而能够关联日志和跟踪。
备注
Python 的日志功能仍处于实验阶段,可能会有一些变更。本服务中的实现遵循 Python 日志示例。