Add rate limit logging and enhance Discord bot initialization
- Introduced a new module `rate_limit_logging.py` to log HTTP headers for Discord API rate limits (HTTP 429). - Updated the Discord bot initialization in `__init__.py` to include a custom HTTP trace configuration for better rate limit handling. - Adjusted logging levels in `run-web.py` to reduce verbosity for rate limit headers.
This commit is contained in:
@@ -30,11 +30,12 @@ from discordbot.patreon import checkPatreonPosts
|
||||
from discordbot.youtube import checkYouTubeVideos
|
||||
from discordbot.auto_rooms import on_voice_state_update_auto_rooms, on_raw_reaction_add_auto_rooms, on_message_auto_rooms, cleanup_orphaned_auto_rooms
|
||||
from discordbot.member_stats import record_message, on_voice_state_update_track_voice
|
||||
from discordbot.rate_limit_logging import build_discord_http_trace_config
|
||||
from protondb import searhProtonDb
|
||||
|
||||
class DiscordBot(discord.Client):
|
||||
def __init__(self, *, intents: discord.Intents):
|
||||
super().__init__(intents=intents)
|
||||
super().__init__(intents=intents, http_trace=build_discord_http_trace_config())
|
||||
self.tree = app_commands.CommandTree(self)
|
||||
self.synced = False
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
"""
|
||||
Journalisation des en-têtes HTTP sur les réponses 429 (rate limit Discord).
|
||||
|
||||
Réf. Discord : https://support-dev.discord.com/hc/en-us/articles/6223003921559-My-Bot-is-Being-Rate-Limited
|
||||
|
||||
discord.py transmet ce TraceConfig aiohttp via l’option Client(http_trace=...).
|
||||
Le corps JSON (retry_after, global) est toujours loggé par le logger discord.http.
|
||||
"""
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
import aiohttp
|
||||
|
||||
logger = logging.getLogger('discord.ratelimit_headers')
|
||||
|
||||
# En-têtes utiles pour identifier le type de limite (global / user / shared, etc.)
|
||||
_HEADER_KEYS = (
|
||||
'X-RateLimit-Limit',
|
||||
'X-RateLimit-Remaining',
|
||||
'X-RateLimit-Reset',
|
||||
'X-RateLimit-Reset-After',
|
||||
'X-RateLimit-Scope',
|
||||
'X-Ratelimit-Bucket',
|
||||
'X-Ratelimit-Limit',
|
||||
'X-Ratelimit-Remaining',
|
||||
'X-Ratelimit-Reset',
|
||||
'Retry-After',
|
||||
'Via',
|
||||
)
|
||||
|
||||
|
||||
def _collect_headers(resp: aiohttp.ClientResponse) -> dict[str, str]:
|
||||
h = resp.headers
|
||||
out: dict[str, str] = {}
|
||||
for key in _HEADER_KEYS:
|
||||
val = h.get(key)
|
||||
if val is not None:
|
||||
out[key] = val
|
||||
return out
|
||||
|
||||
|
||||
def build_discord_http_trace_config() -> aiohttp.TraceConfig:
|
||||
trace = aiohttp.TraceConfig()
|
||||
|
||||
async def on_request_end(
|
||||
session: aiohttp.ClientSession,
|
||||
trace_config_ctx: Any,
|
||||
params: Any,
|
||||
) -> None:
|
||||
try:
|
||||
resp = getattr(params, 'response', None)
|
||||
if resp is None or getattr(resp, 'status', None) != 429:
|
||||
return
|
||||
method = getattr(params, 'method', '?')
|
||||
url = getattr(params, 'url', '?')
|
||||
hdr = _collect_headers(resp)
|
||||
logger.warning(
|
||||
'Discord API 429 %s %s | rate_limit_headers=%s',
|
||||
method,
|
||||
url,
|
||||
hdr,
|
||||
)
|
||||
except Exception:
|
||||
logger.debug('rate_limit trace callback failed', exc_info=True)
|
||||
|
||||
trace.on_request_end.append(on_request_end)
|
||||
return trace
|
||||
@@ -55,6 +55,8 @@ if __name__ == '__main__':
|
||||
# Calmer les logs verbeux de certaines libs si besoin
|
||||
logging.getLogger('werkzeug').setLevel(logging.WARNING)
|
||||
logging.getLogger('discord').setLevel(logging.WARNING)
|
||||
# 429 : en-têtes X-RateLimit-* (voir discordbot/rate_limit_logging.py + doc Discord rate limits)
|
||||
logging.getLogger('discord.ratelimit_headers').setLevel(logging.WARNING)
|
||||
|
||||
# Hook exceptions non-capturées (threads inclus)
|
||||
def _log_uncaught(exc_type, exc, tb):
|
||||
|
||||
Reference in New Issue
Block a user