feat: support sentry

This commit is contained in:
xtaodada 2023-08-07 20:48:02 +08:00
parent 27969977f0
commit 2636bb2bcc
Signed by: xtaodada
GPG Key ID: 4CBB3F4FA8C85659
8 changed files with 70 additions and 11 deletions

View File

@ -13,6 +13,7 @@ port = 1080
[basic] [basic]
ipv6 = False ipv6 = False
cache_uri = mem:// cache_uri = mem://
sentry_dsn = abcd
[misskey] [misskey]
web_domain = misskey2tg.xtaolabs.com web_domain = misskey2tg.xtaolabs.com

View File

@ -361,7 +361,7 @@ async def send_group(
async def send_update( async def send_update(
host: str, cid: int, note: Note, topic_id: Optional[int], show_second: bool host: str, cid: int, note: Note, topic_id: Optional[int], show_second: bool
) -> List[Message]: ) -> Message | list[Message]:
files = list(note.files) files = list(note.files)
if note.reply: if note.reply:
files.extend(iter(note.reply.files)) files.extend(iter(note.reply.files))
@ -375,14 +375,12 @@ async def send_update(
file_type = file.type file_type = file.type
url = await fetch_document(file) url = await fetch_document(file)
if file_type.startswith("image"): if file_type.startswith("image"):
return [await send_photo(host, cid, url, note, topic_id, show_second)] return await send_photo(host, cid, url, note, topic_id, show_second)
elif file_type.startswith("video"): elif file_type.startswith("video"):
return [await send_video(host, cid, url, note, topic_id, show_second)] return await send_video(host, cid, url, note, topic_id, show_second)
elif file_type.startswith("audio"): elif file_type.startswith("audio"):
return [await send_audio(host, cid, url, note, topic_id, show_second)] return await send_audio(host, cid, url, note, topic_id, show_second)
else: else:
return [ return await send_document(host, cid, url, note, topic_id, show_second)
await send_document(host, cid, url, note, topic_id, show_second)
]
case _: case _:
return await send_group(host, cid, files, note, topic_id, show_second) return await send_group(host, cid, files, note, topic_id, show_second)

45
defs/sentry.py Normal file
View File

@ -0,0 +1,45 @@
from subprocess import run, PIPE
from time import time
import sentry_sdk
from pyrogram import Client
from sentry_sdk.integrations.aiohttp import AioHttpIntegration
from sentry_sdk.integrations.httpx import HttpxIntegration
from sentry_sdk.integrations.logging import LoggingIntegration
from sentry_sdk.integrations.redis import RedisIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
from glover import sentry_dsn
sentry_sdk_report_time = time()
sentry_sdk_git_hash = (
run("git rev-parse HEAD", stdout=PIPE, shell=True, check=True)
.stdout.decode()
.strip()
)
sentry_sdk.init(
sentry_dsn,
send_default_pii=True,
traces_sample_rate=1.0,
release=sentry_sdk_git_hash,
environment="production",
integrations=[
AioHttpIntegration(),
HttpxIntegration(),
LoggingIntegration(),
RedisIntegration(),
SqlalchemyIntegration(),
],
)
async def sentry_init_id(bot: Client):
if not bot.me:
bot.me = await bot.get_me()
data = {
"id": bot.me.id,
"username": bot.me.username,
"name": bot.me.first_name,
"ip_address": "{{auto}}",
}
sentry_sdk.set_user(data)

View File

@ -8,6 +8,7 @@ api_hash: str = ""
# [Basic] # [Basic]
ipv6: Union[bool, str] = "False" ipv6: Union[bool, str] = "False"
cache_uri: str = "mem://" cache_uri: str = "mem://"
sentry_dsn: str = ""
# [misskey] # [misskey]
web_domain: str = "" web_domain: str = ""
admin: int = 0 admin: int = 0
@ -18,6 +19,7 @@ api_id = config.getint("pyrogram", "api_id", fallback=api_id)
api_hash = config.get("pyrogram", "api_hash", fallback=api_hash) api_hash = config.get("pyrogram", "api_hash", fallback=api_hash)
ipv6 = config.get("basic", "ipv6", fallback=ipv6) ipv6 = config.get("basic", "ipv6", fallback=ipv6)
cache_uri = config.get("basic", "cache_uri", fallback=cache_uri) cache_uri = config.get("basic", "cache_uri", fallback=cache_uri)
sentry_dsn = config.get("basic", "sentry_dsn", fallback=sentry_dsn)
web_domain = config.get("misskey", "web_domain", fallback=web_domain) web_domain = config.get("misskey", "web_domain", fallback=web_domain)
admin = config.getint("misskey", "admin", fallback=admin) admin = config.getint("misskey", "admin", fallback=admin)
try: try:

View File

@ -4,6 +4,7 @@ from asyncio import sleep, Lock
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from typing import Optional, Union from typing import Optional, Union
import sentry_sdk
from aiohttp import ClientConnectorError from aiohttp import ClientConnectorError
from firebase_admin.exceptions import InvalidArgumentError from firebase_admin.exceptions import InvalidArgumentError
from mipa.exception import WebSocketNotConnected from mipa.exception import WebSocketNotConnected
@ -51,6 +52,7 @@ from init import bot, logs, sqlite
class MisskeyBot(commands.Bot): class MisskeyBot(commands.Bot):
def __init__(self, user: User): def __init__(self, user: User):
super().__init__() super().__init__()
self._BotBase__on_error = self.__on_error
self.user_id: int = user.user_id self.user_id: int = user.user_id
self.instance_user_id: str = user.instance_user_id self.instance_user_id: str = user.instance_user_id
self.tg_user: User = user self.tg_user: User = user
@ -133,7 +135,7 @@ class MisskeyBot(commands.Bot):
executor, func, self.tg_user.fcm_token, notice executor, func, self.tg_user.fcm_token, notice
) )
except InvalidArgumentError: except InvalidArgumentError:
logs.error(f"{self.tg_user.user_id} 无效的 FCM Token") logs.warning(f"{self.tg_user.user_id} 无效的 FCM Token")
except Exception as e: except Exception as e:
logs.error(e) logs.error(e)
@ -189,6 +191,11 @@ class MisskeyBot(commands.Bot):
if self.tg_user.fcm_token: if self.tg_user.fcm_token:
await self.send_fcm(send_fcm_quote, notice) await self.send_fcm(send_fcm_quote, notice)
@staticmethod
async def __on_error(event_method: str) -> None:
logs.exception(f"MisskeyBot 执行 {event_method} 出错", exc_info=True)
sentry_sdk.capture_exception()
misskey_bot_map: dict[int, MisskeyBot] = {} misskey_bot_map: dict[int, MisskeyBot] = {}

View File

@ -22,7 +22,8 @@ class RevokeAction:
return int(cid), [int(mid) for mid in ids.split(",")] return int(cid), [int(mid) for mid in ids.split(",")]
@staticmethod @staticmethod
async def push(uid: int, note_id: str, messages: list[Message]): async def push(uid: int, note_id: str, messages: Message | list[Message]):
messages = [messages] if isinstance(messages, Message) else messages
await cache.set( await cache.set(
f"sub:{uid}:{note_id}", f"sub:{uid}:{note_id}",
RevokeAction.encode_messages(messages), RevokeAction.encode_messages(messages),

4
modules/sentry.py Normal file
View File

@ -0,0 +1,4 @@
from init import bot
from defs.sentry import sentry_init_id
bot.loop.create_task(sentry_init_id(bot))

View File

@ -8,6 +8,7 @@ aiosqlite==0.19.0
PyYAML==6.0.1 PyYAML==6.0.1
aiofiles==23.1.0 aiofiles==23.1.0
pillow==10.0.0 pillow==10.0.0
cashews==6.2.0 cashews[redis]==6.2.0
alembic==1.11.1 alembic==1.11.2
firebase-admin==6.2.0 firebase-admin==6.2.0
sentry-sdk==1.29.2