metrics with aioinflux

This commit is contained in:
kiriharu 2021-01-05 20:23:28 +03:00
parent ea40f85d63
commit b755a24ce2
12 changed files with 102 additions and 3 deletions

View File

@ -10,6 +10,8 @@ aiogram = "^2.11.2"
httpx = "^0.16.1" httpx = "^0.16.1"
python-whois = "^0.7.3" python-whois = "^0.7.3"
core = {path = "../core"} core = {path = "../core"}
aioinflux = "^0.9.0"
loguru = "^0.5.3"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]

View File

@ -1,6 +1,6 @@
from aiogram import Bot, Dispatcher, executor from aiogram import Bot, Dispatcher, executor
from aiogram.contrib.fsm_storage.memory import MemoryStorage from aiogram.contrib.fsm_storage.memory import MemoryStorage
from tgbot.middlewares import WriteCommandMetric
import config import config
import handlers import handlers
@ -11,6 +11,7 @@ dp = Dispatcher(telegram_bot, storage=storage)
def on_startup(): def on_startup():
handlers.default.setup(dp) handlers.default.setup(dp)
dp.middleware.setup(WriteCommandMetric())
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -2,3 +2,10 @@ import os
# Loading token from .env # Loading token from .env
TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
# Influx for metrics
INFLUX_HOST = os.getenv("INFLUX_HOST", None)
INFLUX_PORT = os.getenv("INFLUX_PORT", None)
INFLUX_USERNAME = os.getenv("INFLUX_USERNAME", None)
INFLUX_PASSWORD = os.getenv("INFLUX_PASSWORD", None)
INFLUX_DB = os.getenv("INFLUX_DB", None)

View File

@ -7,6 +7,7 @@ from aiogram.bot import Bot
from datetime import datetime from datetime import datetime
from core.coretypes import APINodeInfo from core.coretypes import APINodeInfo
from .helpers import send_api_requests, check_int, validate_local from .helpers import send_api_requests, check_int, validate_local
from .metrics import push_metric
header = "Отчет о проверке хоста:" \ header = "Отчет о проверке хоста:" \
"\n\n— Хост: {target_fq}"\ "\n\n— Хост: {target_fq}"\

View File

@ -2,6 +2,7 @@ from aiogram.types import Message
from httpx import Response from httpx import Response
from core.coretypes import ErrorPayload, ICMPCheckerResponse, ResponseStatus from core.coretypes import ErrorPayload, ICMPCheckerResponse, ResponseStatus
from ..base import CheckerBaseHandler, NotEnoughArgs, LocalhostForbidden from ..base import CheckerBaseHandler, NotEnoughArgs, LocalhostForbidden
from ..metrics import push_status_metric
icmp_help_message = """ icmp_help_message = """
Производит проверку хоста по протоколу ICMP. Производит проверку хоста по протоколу ICMP.
@ -45,4 +46,5 @@ class ICMPCheckerHandler(CheckerBaseHandler):
if status == ResponseStatus.ERROR: if status == ResponseStatus.ERROR:
payload = ErrorPayload(**res.json().get("payload")) payload = ErrorPayload(**res.json().get("payload"))
message += f"❌️ {payload.message}" message += f"❌️ {payload.message}"
await push_status_metric(status, self.api_endpoint)
return message return message

View File

@ -2,7 +2,8 @@ from aiogram.types import Message
from core.coretypes import ResponseStatus, ErrorPayload, MinecraftResponse from core.coretypes import ResponseStatus, ErrorPayload, MinecraftResponse
from httpx import Response from httpx import Response
from tgbot.handlers.base import CheckerBaseHandler, NotEnoughArgs, InvalidPort, process_args_for_host_port from tgbot.handlers.base import CheckerBaseHandler, process_args_for_host_port
from tgbot.handlers.metrics import push_status_metric
minecraft_help_message = """ minecraft_help_message = """
Получает статистику о Minecraft сервере Получает статистику о Minecraft сервере
@ -37,4 +38,5 @@ class MinecraftCheckerHandler(CheckerBaseHandler):
if status == ResponseStatus.ERROR: if status == ResponseStatus.ERROR:
payload = ErrorPayload(**res.json().get("payload")) payload = ErrorPayload(**res.json().get("payload"))
message += f"❌️ {payload.message}" message += f"❌️ {payload.message}"
await push_status_metric(status, self.api_endpoint)
return message return message

View File

@ -4,6 +4,7 @@ from httpx import Response
from tgbot.handlers.base import CheckerBaseHandler, NotEnoughArgs, InvalidPort from tgbot.handlers.base import CheckerBaseHandler, NotEnoughArgs, InvalidPort
from tgbot.handlers.helpers import check_int from tgbot.handlers.helpers import check_int
from tgbot.handlers.metrics import push_status_metric
tcp_help_message = """ tcp_help_message = """
Производит проверку TCP порта, открыт ли он или нет Производит проверку TCP порта, открыт ли он или нет
@ -48,4 +49,5 @@ class TCPCheckerHandler(CheckerBaseHandler):
if status == ResponseStatus.ERROR: if status == ResponseStatus.ERROR:
payload = ErrorPayload(**res.json().get("payload")) payload = ErrorPayload(**res.json().get("payload"))
message += f"❌️ {payload.message}" message += f"❌️ {payload.message}"
await push_status_metric(status, self.api_endpoint)
return message return message

View File

@ -1,7 +1,8 @@
from aiogram.types import Message from aiogram.types import Message
from httpx import Response from httpx import Response
from core.coretypes import ResponseStatus, HTTP_EMOJI, HttpCheckerResponse, ErrorPayload from core.coretypes import ResponseStatus, HTTP_EMOJI, HttpCheckerResponse, ErrorPayload
from ..base import CheckerBaseHandler, NotEnoughArgs, InvalidPort, process_args_for_host_port from ..base import CheckerBaseHandler, process_args_for_host_port
from ..metrics import push_status_metric
web_help_message = """ web_help_message = """
Производит проверку хоста по протоколу HTTP. Производит проверку хоста по протоколу HTTP.
@ -36,4 +37,5 @@ class WebCheckerHandler(CheckerBaseHandler):
if status == ResponseStatus.ERROR: if status == ResponseStatus.ERROR:
payload = ErrorPayload(**res.json().get("payload")) payload = ErrorPayload(**res.json().get("payload"))
message += f"❌️ {payload.message}" message += f"❌️ {payload.message}"
await push_status_metric(status, self.api_endpoint)
return message return message

View File

@ -4,6 +4,8 @@ from core.coretypes import APINode
from ipaddress import ip_address from ipaddress import ip_address
from contextlib import suppress from contextlib import suppress
from tgbot.handlers.metrics import push_api_request_status
def check_int(value) -> bool: def check_int(value) -> bool:
try: try:
@ -47,4 +49,8 @@ async def send_api_requests(endpoint: str, data: dict, nodes: List[APINode]):
# TODO: Report problems to admins # TODO: Report problems to admins
# We yield 500 response when backend is offline # We yield 500 response when backend is offline
result = Response(500) result = Response(500)
await push_api_request_status(
result.status_code,
endpoint
)
yield result yield result

View File

@ -0,0 +1,50 @@
from aioinflux import InfluxDBClient
from typing import Dict
from tgbot.config import INFLUX_DB, INFLUX_HOST, INFLUX_PORT, INFLUX_PASSWORD, INFLUX_USERNAME
async def push_metric(measurement, tags: Dict, fields: Dict):
try:
point = {
'measurement': measurement,
'tags': tags,
'fields': fields
}
async with InfluxDBClient(
host=INFLUX_HOST,
port=INFLUX_PORT,
username=INFLUX_USERNAME,
password=INFLUX_PASSWORD,
db=INFLUX_DB,
mode='async'
) as client:
await client.write(point)
except Exception as e:
print(e)
pass
async def push_api_request_status(status_code: int, endpoint: str):
await push_metric(
measurement="bot_api_request",
fields=dict(
value=1,
),
tags=dict(
status=status_code,
endpoint=endpoint
)
)
async def push_status_metric(status, api_endpoint):
await push_metric(
measurement="bot_prepared_messages",
fields=dict(
value=1,
),
tags=dict(
rsp_status=status,
api_endpoint=api_endpoint
)
)

View File

@ -0,0 +1 @@
from tgbot.middlewares.write_command_metric import WriteCommandMetric

View File

@ -0,0 +1,23 @@
from aiogram.dispatcher.middlewares import BaseMiddleware
from aiogram.types import Message
from tgbot.handlers.metrics import push_metric
class WriteCommandMetric(BaseMiddleware):
def __init__(self):
super().__init__()
async def on_process_message(self, message: Message, data: dict):
await push_metric(
measurement="bot_processed_messages",
fields=dict(
telegram_id=message.from_user.id,
full_command=message.text,
value=1,
),
tags=dict(
command=message.text.split(" ")[0],
type="command"
)
)