From 63f59ada3c973b891cf0c6a9cdaf05be6c733294 Mon Sep 17 00:00:00 2001 From: suyiiyii Date: Wed, 20 Nov 2024 23:18:50 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E5=88=9D=E6=AD=A5=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20metrics?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nonebot_bison/admin_page/__init__.py | 2 ++ nonebot_bison/admin_page/api.py | 10 ++++++++++ nonebot_bison/metrics.py | 9 +++++++++ nonebot_bison/scheduler/scheduler.py | 6 ++++-- poetry.lock | 23 +++++++++++++++++++++-- pyproject.toml | 1 + 6 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 nonebot_bison/metrics.py diff --git a/nonebot_bison/admin_page/__init__.py b/nonebot_bison/admin_page/__init__.py index c888bf0..1afb0dc 100644 --- a/nonebot_bison/admin_page/__init__.py +++ b/nonebot_bison/admin_page/__init__.py @@ -12,6 +12,7 @@ from nonebot.adapters.onebot.v11.event import PrivateMessageEvent from .api import router as api_router from ..plugin_config import plugin_config from .token_manager import token_manager as tm +from .api import metrics_router as metrics_router if TYPE_CHECKING: from nonebot.drivers.fastapi import Driver @@ -46,6 +47,7 @@ def init_fastapi(driver: "Driver"): description="nonebot-bison webui and api", ) nonebot_app.include_router(api_router) + nonebot_app.include_router(metrics_router) nonebot_app.mount("/", SinglePageApplication(directory=static_path), name="bison-frontend") app = driver.server_app diff --git a/nonebot_bison/admin_page/api.py b/nonebot_bison/admin_page/api.py index da8208c..66f431d 100644 --- a/nonebot_bison/admin_page/api.py +++ b/nonebot_bison/admin_page/api.py @@ -3,11 +3,13 @@ from typing import cast import nonebot from fastapi import status from fastapi.routing import APIRouter +from starlette.responses import Response from fastapi.param_functions import Depends from fastapi.exceptions import HTTPException from nonebot_plugin_saa import TargetQQGroup from nonebot_plugin_saa.auto_select_bot import get_bot from fastapi.security.oauth2 import OAuth2PasswordBearer +from prometheus_client import CONTENT_TYPE_LATEST, generate_latest from ..types import WeightConfig from ..apis import check_sub_target @@ -283,3 +285,11 @@ async def get_cookie_valid(site_name: str, content: str) -> StatusResp: return StatusResp(ok=True, msg="") else: return StatusResp(ok=False, msg="") + + +metrics_router = APIRouter(prefix="/api/metrics", tags=["metrics"]) + + +@metrics_router.get("") +async def metrics(): + return Response(media_type=CONTENT_TYPE_LATEST, content=generate_latest()) diff --git a/nonebot_bison/metrics.py b/nonebot_bison/metrics.py new file mode 100644 index 0000000..fbddc98 --- /dev/null +++ b/nonebot_bison/metrics.py @@ -0,0 +1,9 @@ +from prometheus_client import Counter + +# Request counter +request_counter = Counter("bison_request_counter", "The number of requests") +# Success counter +success_counter = Counter("bison_success_counter", "The number of successful requests") + +# Sent counter +sent_counter = Counter("bison_sent_counter", "The number of sent messages") diff --git a/nonebot_bison/scheduler/scheduler.py b/nonebot_bison/scheduler/scheduler.py index f94ea87..6a292ac 100644 --- a/nonebot_bison/scheduler/scheduler.py +++ b/nonebot_bison/scheduler/scheduler.py @@ -6,6 +6,7 @@ from nonebot_plugin_apscheduler import scheduler from nonebot_plugin_saa.utils.exceptions import NoBotFound from nonebot_bison.utils import ClientManager +from nonebot_bison.metrics import sent_counter, request_counter, success_counter from ..config import config from ..send import send_msgs @@ -93,6 +94,7 @@ class Scheduler: logger.trace(f"scheduler {self.name} fetching next target: [{schedulable.platform_name}]{schedulable.target}") context = ProcessContext(self.client_mgr) + request_counter.inc() try: platform_obj = platform_manager[schedulable.platform_name](context) @@ -116,10 +118,10 @@ class Scheduler: logger.warning("API request record: " + record) err.args += (records,) raise - + success_counter.inc() if not to_send: return - + sent_counter.inc() for user, send_list in to_send: for send_post in send_list: logger.info(f"send to {user}: {send_post}") diff --git a/poetry.lock b/poetry.lock index 1d635c1..0e8dc9c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "aiodns" @@ -3207,6 +3207,25 @@ type = "legacy" url = "https://pypi.org/simple" reference = "offical-source" +[[package]] +name = "prometheus-client" +version = "0.21.0" +description = "Python client for the Prometheus monitoring system." +optional = false +python-versions = ">=3.8" +files = [ + {file = "prometheus_client-0.21.0-py3-none-any.whl", hash = "sha256:4fa6b4dd0ac16d58bb587c04b1caae65b8c5043e85f778f42f5f632f6af2e166"}, + {file = "prometheus_client-0.21.0.tar.gz", hash = "sha256:96c83c606b71ff2b0a433c98889d275f51ffec6c5e267de37c7a2b5c9aa9233e"}, +] + +[package.extras] +twisted = ["twisted"] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "offical-source" + [[package]] name = "prompt-toolkit" version = "3.0.47" @@ -5166,4 +5185,4 @@ yaml = [] [metadata] lock-version = "2.0" python-versions = ">=3.10,<4.0.0" -content-hash = "3d3bd947b91b8053fc5fed4873b6d0ed4017a5be118611cd93d30ffa265e04fb" +content-hash = "5e4ea27ea11e18451d1ad0d4bbf3b44da9334c20728889041a4c908addbfdda8" diff --git a/pyproject.toml b/pyproject.toml index 148b15c..2697442 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,6 +42,7 @@ yarl = ">=1.11.1" hishel = "^0.0.30" expiringdictx = "^1.1.0" rapidfuzz = "^3.9.7" +prometheus-client = "^0.21.0" [tool.poetry.group.dev.dependencies] black = ">=24.8.0,<25.0"