Observability:使用 OpenTelemetry 和 Elastic 监控 OpenAI API 和 GPT 模型
作者: 来自 Elastic David Hope

ChatGPT 现在非常火爆,甚至席卷了整个互联网。 作为 ChatGPT 的狂热用户和 ChatGPT 应用程序的开发人员,我对这项技术的可能性感到非常兴奋。 我看到的情况是,基于 ChatGPT 的解决方案将会呈指数级增长,人们将需要监控这些解决方案。
由于这是一项相当新技术,我们不想让专有技术给我们闪亮的新代码带来负担,不是吗? 不,我们不会,这就是为什么我们将在本博客中使用 OpenTelemetry 来监控我们的 ChatGPT 代码。 这对我来说尤其重要,因为我最近创建了一项通过 Zoom 通话生成会议记录的服务(需要使用 OpenAI 服务)。 如果我要任意使用这个功能,需要花费多少钱以及如何确保它可用?
OpenAI API 来救援
毫无疑问,OpenAI API 非常棒。 它还为我们提供了对每个 API 调用的每个响应中如下所示的信息,这可以帮助我们了解我们所收取的费用。 通过使用 OpenAI 在其网站上发布的 token 数量、模型和定价,我们可以计算成本。 问题是,我们如何将这些信息输入到我们的监控工具中?
{"choices": [{"finish_reason": "length","index": 0,"logprobs": null,"text": "\n\nElastic is an amazing observability tool because it provides a comprehensive set of features for monitoring"}],"created": 1680281710,"id": "cmpl-70CJq07gibupTcSM8xOWekOTV5FRF","model": "text-davinci-003","object": "text_completion","usage": {"completion_tokens": 20,"prompt_tokens": 9,"total_tokens": 29}
}
OpenTelemetry 来救援
OpenTelemetry 确实是一项出色的工作。 多年来,它得到了如此多的采用和投入,似乎真的已经到了我们可以将其称为 “可观察性 Linux” 的地步。 我们可以使用它来记录日志、指标和跟踪,并以供应商中立的方式将它们放入我们最喜欢的可观察性工具中 - 在本例中为 Elastic Observability。
借助 Python 中最新最好的 otel 库,我们可以自动检测外部调用,这将帮助我们了解 OpenAI 调用的执行情况。 让我们先看一下我们的示例 Python 应用程序,它实现了 Flask 和 ChatGPT API,并且还具有 OpenTelemetry。 如果你想亲自尝试一下,请查看本博客末尾的 GitHub 链接并按照以下步骤操作。
设置 Elastic Cloud 帐户(如果你还没有)
- 请访问 https://www.elastic.co/cloud/elasticsearch-service/signup 注册为期两周的免费试用。
- 创建部署。
登录后,单击添加集成。

单击 APM integrations。

然后向下滚动以获取此博客所需的详细信息:

请务必设置以下环境变量,将变量替换为你从上面的 Elastic 和此处的 OpenAI 获得的数据,然后在命令行上运行这些 export 命令。
export OPEN_AI_KEY=sk-abcdefgh5ijk2l173mnop3qrstuvwxyzab2cde47fP2g9jij
export OTEL_EXPORTER_OTLP_AUTH_HEADER=abc9ldeofghij3klmn
export OTEL_EXPORTER_OTLP_ENDPOINT=https://123456abcdef.apm.us-west2.gcp.elastic-cloud.com:443
并安装以下 Python 库:
pip3 install opentelemetry-api
pip3 install opentelemetry-sdk
pip3 install opentelemetry-exporter-otlp
pip3 install opentelemetry-instrumentation
pip3 install opentelemetry-instrumentation-requests
pip3 install openai
pip3 install flask
下面是我们用于示例应用程序的代码。 在现实世界中,这将是你自己的代码。 所有这一切都是通过以下消息调用 OpenAI API:“Why is Elastic an amazing observability tool?”
import openai
from flask import Flask
import monitor # Import the module
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
import urllib
import os
from opentelemetry import trace
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.instrumentation.requests import RequestsInstrumentor# OpenTelemetry setup up code here, feel free to replace the “your-service-name” attribute here.
resource = Resource(attributes={SERVICE_NAME: "your-service-name"
})
provider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint=os.getenv('OTEL_EXPORTER_OTLP_ENDPOINT'),headers="Authorization=Bearer%20"+os.getenv('OTEL_EXPORTER_OTLP_AUTH_HEADER')))
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)
RequestsInstrumentor().instrument()# Initialize Flask app and instrument itapp = Flask(__name__)
# Set OpenAI API key
openai.api_key = os.getenv('OPEN_AI_KEY')@app.route("/completion")
@tracer.start_as_current_span("do_work")
def completion():response = openai.Completion.create(model="text-davinci-003",prompt="Why is Elastic an amazing observability tool?",max_tokens=20,temperature=0)return response.choices[0].text.strip()if __name__ == "__main__":app.run()
使用 Monkey patching (猴子补丁)
在 monitor.py 代码中,你会看到我们做了一些叫做 “Monkey Patching” 的事情。 猴子修补是 Python 中的一项技术,你可以通过修改类或模块的属性或方法在运行时动态修改类或模块的行为。 猴子补丁允许你更改类或模块的功能,而无需修改其源代码。 当你需要修改你无法控制或无法直接修改的现有类或模块的行为时,它会很有用。
我们在这里要做的是修改 “Completion” 调用的行为,以便我们可以 “窃取” 响应指标并将它们添加到我们的 OpenTelemetry 范围中。 你可以在下面看到我们如何做到这一点:
def count_completion_requests_and_tokens(func):@wraps(func)def wrapper(*args, **kwargs):counters['completion_count'] += 1response = func(*args, **kwargs)token_count = response.usage.total_tokensprompt_tokens = response.usage.prompt_tokenscompletion_tokens = response.usage.completion_tokenscost = calculate_cost(response)strResponse = json.dumps(response)# Set OpenTelemetry attributesspan = trace.get_current_span()if span:span.set_attribute("completion_count", counters['completion_count'])span.set_attribute("token_count", token_count)span.set_attribute("prompt_tokens", prompt_tokens)span.set_attribute("completion_tokens", completion_tokens)span.set_attribute("model", response.model)span.set_attribute("cost", cost)span.set_attribute("response", strResponse)return responsereturn wrapper
# Monkey-patch the openai.Completion.create function
openai.Completion.create = count_completion_requests_and_tokens(openai.Completion.create)
通过将所有这些数据添加到我们的 Span,我们实际上可以将其发送到我们的 OpenTelemetry OTLP 端点(在本例中它将是 Elastic 的)。 这样做的好处是你可以轻松使用数据进行搜索或构建仪表板和可视化。 在最后一步中,我们还要计算成本。 我们通过实现以下函数来实现这一点,该函数将计算对 OpenAI API 的单个请求的成本。
def calculate_cost(response):if response.model in ['gpt-4', 'gpt-4-0314']:cost = (response.usage.prompt_tokens * 0.03 + response.usage.completion_tokens * 0.06) / 1000elif response.model in ['gpt-4-32k', 'gpt-4-32k-0314']:cost = (response.usage.prompt_tokens * 0.06 + response.usage.completion_tokens * 0.12) / 1000elif 'gpt-3.5-turbo' in response.model:cost = response.usage.total_tokens * 0.002 / 1000elif 'davinci' in response.model:cost = response.usage.total_tokens * 0.02 / 1000elif 'curie' in response.model:cost = response.usage.total_tokens * 0.002 / 1000elif 'babbage' in response.model:cost = response.usage.total_tokens * 0.0005 / 1000elif 'ada' in response.model:cost = response.usage.total_tokens * 0.0004 / 1000else:cost = 0return cost
Elastic 来拯救
一旦我们捕获了所有这些数据,就可以在 Elastic 中享受一些乐趣了。 在 Discover 中,我们可以看到使用 OpenTelemetry 库发送的所有数据点:

有了这些标签,构建仪表板就变得非常容易。 看一下我之前构建的这个(也已并入到我的 GitHub 存储库):

我们还可以看到 OpenAI 服务的 transactions、延迟以及与 ChatGPT 服务调用相关的所有 span。



在 transaction 视图中,我们还可以看到特定 OpenAI 调用花费了多长时间:

此处对 OpenAI 的某些请求花费了超过 3 秒的时间。 ChatGPT 可能非常慢,因此我们必须了解其速度有多慢以及用户是否感到沮丧。
概括
我们研究了通过 OpenTelemetry 和 Elastic 监控 ChatGPT。 ChatGPT 是一种全球现象,毫无疑问它会不断发展壮大,很快每个人都会使用它。 由于获取响应的速度可能很慢,因此人们能够了解使用此服务的任何代码的性能至关重要。
还有成本问题,因为了解这项服务是否会侵蚀你的利润以及你所要求的服务是否能为你的业务带来利润非常重要。 在当前的经济环境下,我们必须关注盈利能力。
在这里查看该解决方案的代码。 请随意使用 “monitor” 库来检测你自己的 OpenAI 代码。
有兴趣了解有关 Elastic Observability 的更多信息吗? 查看以下资源:
- Elastic 可观测性简介
- 可观察性基础培训
- 观看 Elastic Observability 演示
- 2023 年可观测性预测和趋势
并报名参加我们以 AWS 和 Forrester 为主题的 Elastic 可观测性趋势网络研讨会,不容错过!
在这篇博文中,我们可能使用了第三方生成式人工智能工具,这些工具由其各自所有者拥有和运营。 Elastic 对第三方工具没有任何控制权,我们对其内容、操作或使用不承担任何责任,也不对你使用此类工具可能产生的任何损失或损害负责。 使用人工智能工具处理个人、敏感或机密信息时请务必谨慎。 你提交的任何数据都可能用于人工智能培训或其他目的。 无法保证你提供的信息将得到安全或保密。 在使用之前,你应该熟悉任何生成式人工智能工具的隐私惯例和使用条款。
Elastic、Elasticsearch 和相关标志是 Elasticsearch N.V. 在美国和其他国家/地区的商标、徽标或注册商标。 所有其他公司和产品名称均为其各自所有者的商标、徽标或注册商标。
原文:Monitor OpenAI API and GPT models with OpenTelemetry and Elastic — Elastic Search Labs
相关文章:
Observability:使用 OpenTelemetry 和 Elastic 监控 OpenAI API 和 GPT 模型
作者: 来自 Elastic David Hope ChatGPT 现在非常火爆,甚至席卷了整个互联网。 作为 ChatGPT 的狂热用户和 ChatGPT 应用程序的开发人员,我对这项技术的可能性感到非常兴奋。 我看到的情况是,基于 ChatGPT 的解决方案将会呈指数级…...
靡语IT:Vue精讲(一)
Vue简介 发端于2013年的个人项目,已然成为全世界三大前端框架之一,在中国大陆更是前端首选。 它的设计思想、编码技巧也被众多的框架借鉴、模仿。 纪略 2013年,在Google工作的尤雨溪,受到Angular的启发,从中提取自…...
vue3 toRefs之后的变量修改方法
上效果 修改值需要带上解构之前的对象名obj, changeName:()>{ // toRefs 解决后变量修改值方法: 解构前变量.字段新值 obj.name FEIFEI; } } 案例源码 <!DOCTYPE html> <html> <head><me…...
【教程】详解相机模型与坐标转换
转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn] 由于复制过来,如果有格式问题,推荐大家直接去我原网站上查看: 相机模型与坐标转换 - 生活大爆炸 目录 经纬度坐标系 转 地球直角坐标系大地直角坐标系 转 经纬度坐标系地理坐标…...
171基于matlab的随机共振微弱信号检测
基于matlab的随机共振微弱信号检测,随机共振描述了过阻尼布朗粒子受周期性信号和随机噪声的共同作用下,在非线性双稳态系统中所发生的跃迁现象. 随机共振可用于弱信号的检测。程序已调通,可直接运行。...
petalinux_zynq7 驱动DAC以及ADC模块之三:实现C语言API并编译出库被python调用
前文: petalinux_zynq7 C语言驱动DAC以及ADC模块之一:建立IPhttps://blog.csdn.net/qq_27158179/article/details/136234296petalinux_zynq7 C语言驱动DAC以及ADC模块之二:petalinuxhttps://blog.csdn.net/qq_27158179/article/details/1362…...
NXP实战笔记(五):S32K3xx基于RTD-SDK在S32DS上配置ADC的硬件触发同步采样与软件采样过程
目录 1、概述 1.1、软件触发 1.2、硬件触发 - BCTU 1.3、硬件触发 - TRGMUX 1.4、ADC的校准 1.5、ADC时钟配置 2、BTCU硬件触发ADC的SDK配置 3、软件触发ADC 3.1、选择相应Port作为ADC的输入 3.2、ADC配置 3.3、代码示例 1、概述 恩智浦 S32K3xx 系列汽车微控制器…...
pikachu靶场-CSRF
CSRF: 介绍: Cross-site request forgery简称为"CSRF”。 在CSF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接) 然后欺骗目标用户进行点击,用户一旦点击了这个请求,整个攻击也就完成了࿰…...
【结合OpenAI官方文档】解决Chatgpt的API接口请求速率限制
OpenAI API接口请求速率限制 速率限制以五种方式衡量:RPM(每分钟请求数)、RPD(每天请求数)、TPM(每分钟令牌数)、TPD(每天令牌数)和IPM(每分钟图像数&#x…...
C语言实现基础数据结构——栈
目录 栈 栈的实现 数组栈 数组栈的实现 栈的初始化 栈的销毁 数据入栈 判断栈是否为空 数据出栈 获取栈顶元素 获取栈内数据个数 项目实现 栈的基础练习 有效的括号 栈 栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的…...
船舶制造5G智能工厂数字孪生可视化平台,推进船舶行业数字化转型
船舶制造5G智能工厂数字孪生可视化平台,推进船舶行业数字化转型。随着数字化时代的到来,船舶行业正面临着前所未有的机遇与挑战。为了适应这一变革,船舶制造企业需要加快数字化转型的步伐,提高生产效率、降低成本并增强市场竞争力…...
【网络编程】okhttp深入理解
newCall 实际上是创建了一个 RealCall 有三个参数:OkHttpClient(通用配置,超时时间等) Request(Http请求所用到的条件,url等) 布尔变量forWebSocket(webSocket是一种应用层的交互方式,可双向交互…...
大功率厚膜电阻器制造 – 优化性能?
通过优化工业大功率电阻器制造工艺,制造商可以提高电阻器的性能和可靠性、容差、额定电压、TCR、稳定性和额定功率。 在本文中,我们将介绍工业功率电阻器的制造过程。我们讨论了材料选择和生产技术及其对性能的潜在影响。 完美的电阻器 在其整个使用寿…...
ElasticStack安装(windows)
官网 : Elasticsearch 平台 — 大规模查找实时答案 | Elastic Elasticsearch Elastic Stack(一套技术栈) 包含了数据的整合 >提取 >存储 >使用,一整套! 各组件介绍: beats 套件:从各种不同类型的文件/应用中采集数据。比如:a,b,cd,e,aa,bb,ccLogstash:…...
gitlab的使用
前一篇文章我们已经知道Git人人都是中心,那他们怎么交互数据呢? • 使用GitHub或者码云等公共代码仓库 • 使用GitLab私有仓库 目录 一、安装配置gitlab 安装 初始化 这里初始化完成以后需要记住一个初始密码 查看状态 二、使用浏览器访问…...
基于springboot+vue的植物健康系统(前后端分离)
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 主要内容:毕业设计(Javaweb项目|小程序|Pyt…...
Python爬虫实战入门:爬取360模拟翻译(仅实验)
文章目录 需求所需第三方库requests 实战教程打开网站抓包添加请求头等信息发送请求,解析数据修改翻译内容以及实现中英互译 完整代码 需求 目标网站:https://fanyi.so.com/# 要求:爬取360翻译数据包,实现翻译功能 所需第三方库 …...
微服务-微服务API网关Spring-clould-gateway实战
1. 需求背景 在微服务架构中,通常一个系统会被拆分为多个微服务,面对这么多微服务客户端应该如何去调用呢? 如果根据每个微服务的地址发起调用,存在如下问题: 1.客户端多次请求不同的微服务,会增加客户端…...
ECMAScript modules规范示例详解
ECMAScript modules(简称 ES modules)是JavaScript的标准模块系统。每个模块都是一个独立的JavaScript文件,可以在其中定义导出的变量、函数或类,并从其他模块中导入这些变量、函数或类。以下是ES modules规范的一些示例和详解&am…...
【OpenFeign常用配置】
OpenFeign常用配置 快速入门:1、引入依赖2、启用OpenFeign 实践1、引入依赖2、开启连接池功能3、模块划分4、日志5、重试 快速入门: OpenFeign是一个声明式的http客户端,是spring cloud在eureka公司开源的feign基础上改造而来。其作用及时基于…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
