Files
LangBot/pkg/audit/gatherer.py

134 lines
4.2 KiB
Python
Raw Normal View History

2023-03-05 15:39:13 +08:00
"""
使用量统计以及数据上报功能实现
"""
import hashlib
import json
2023-01-04 17:59:10 +08:00
import logging
import requests
import pkg.utils.context
2023-01-05 15:50:45 +08:00
import pkg.utils.updater
2023-01-04 17:59:10 +08:00
class DataGatherer:
"""数据收集器"""
2023-03-05 15:39:13 +08:00
usage = {}
2023-03-05 15:39:13 +08:00
"""各api-key的使用量
以key值md5为key,{
"text": {
"text-davinci-003": 文字量:int,
},
"image": {
"256x256": 图片数量:int,
}
}为值的字典"""
version_str = "undetermined"
2023-01-05 15:50:45 +08:00
def __init__(self):
self.load_from_db()
2023-01-05 15:50:45 +08:00
try:
2023-03-05 15:39:13 +08:00
self.version_str = pkg.utils.updater.get_current_tag() # 从updater模块获取版本号
2023-01-05 15:50:45 +08:00
except:
pass
2023-01-04 17:59:10 +08:00
def report_to_server(self, subservice_name: str, count: int):
2023-03-05 15:39:13 +08:00
"""向中央服务器报告使用量
只会报告此次请求的使用量不会报告总量
不包含除版本号使用类型使用量以外的任何信息仅供开发者分析使用情况
"""
try:
config = pkg.utils.context.get_config()
if hasattr(config, "report_usage") and not config.report_usage:
return
2023-01-05 15:50:45 +08:00
res = requests.get("http://rockchin.top:18989/usage?service_name=qchatgpt.{}&version={}&count={}".format(subservice_name, self.version_str, count))
if res.status_code != 200 or res.text != "ok":
logging.warning("report to server failed, status_code: {}, text: {}".format(res.status_code, res.text))
except:
2023-01-04 17:59:10 +08:00
return
2023-01-14 22:36:48 +08:00
def get_usage(self, key_md5):
return self.usage[key_md5] if key_md5 in self.usage else {}
def report_text_model_usage(self, model, total_tokens):
2023-03-05 15:39:13 +08:00
"""调用方报告文字模型请求文字使用量"""
key_md5 = pkg.utils.context.get_openai_manager().key_mgr.get_using_key_md5() # 以key的md5进行储存
if key_md5 not in self.usage:
self.usage[key_md5] = {}
if "text" not in self.usage[key_md5]:
self.usage[key_md5]["text"] = {}
if model not in self.usage[key_md5]["text"]:
self.usage[key_md5]["text"][model] = 0
length = total_tokens
self.usage[key_md5]["text"][model] += length
self.dump_to_db()
2023-01-04 17:59:10 +08:00
self.report_to_server("text", length)
def report_image_model_usage(self, size):
2023-03-05 15:39:13 +08:00
"""调用方报告图片模型请求图片使用量"""
key_md5 = pkg.utils.context.get_openai_manager().key_mgr.get_using_key_md5()
if key_md5 not in self.usage:
self.usage[key_md5] = {}
if "image" not in self.usage[key_md5]:
self.usage[key_md5]["image"] = {}
if size not in self.usage[key_md5]["image"]:
self.usage[key_md5]["image"][size] = 0
self.usage[key_md5]["image"][size] += 1
self.dump_to_db()
2023-01-04 17:59:10 +08:00
self.report_to_server("image", 1)
def get_text_length_of_key(self, key):
2023-03-05 15:39:13 +08:00
"""获取指定api-key (明文) 的文字总使用量(本地记录)"""
key_md5 = hashlib.md5(key.encode('utf-8')).hexdigest()
if key_md5 not in self.usage:
return 0
if "text" not in self.usage[key_md5]:
return 0
# 遍历其中所有模型,求和
return sum(self.usage[key_md5]["text"].values())
def get_image_count_of_key(self, key):
2023-03-05 15:39:13 +08:00
"""获取指定api-key (明文) 的图片总使用量(本地记录)"""
key_md5 = hashlib.md5(key.encode('utf-8')).hexdigest()
if key_md5 not in self.usage:
return 0
if "image" not in self.usage[key_md5]:
return 0
# 遍历其中所有模型,求和
return sum(self.usage[key_md5]["image"].values())
2023-02-10 19:03:25 +08:00
def get_total_text_length(self):
2023-03-05 15:39:13 +08:00
"""获取所有api-key的文字总使用量(本地记录)"""
2023-02-10 19:03:25 +08:00
total = 0
for key in self.usage:
if "text" not in self.usage[key]:
continue
total += sum(self.usage[key]["text"].values())
return total
def dump_to_db(self):
pkg.utils.context.get_database_manager().dump_usage_json(self.usage)
def load_from_db(self):
json_str = pkg.utils.context.get_database_manager().load_usage_json()
if json_str is not None:
self.usage = json.loads(json_str)