refactor: заменил print() на logging для системных сообщений

- bot.py: startup, shutdown, ошибки авторизации → logger.info/error/critical
- utils/pogoda.py: retry и ошибки API → logger.warning/error
- console_commands/stop.py: ошибка остановки → logger.error
- commands/help.py: удалён артефакт print("Cog loaded!")
- Интерактивное меню и пользовательский вывод console_commands/ оставлены как print()
This commit is contained in:
deadzilla 2026-06-09 21:16:13 +05:00
parent 2690ee72e3
commit 52fdbc3778
4 changed files with 21 additions and 17 deletions

20
bot.py
View File

@ -30,17 +30,17 @@ scheduler: Scheduler | None = None
@bot.event @bot.event
async def on_ready(): async def on_ready():
global scheduler global scheduler
print(f"Бот вошёл как {bot.user}") logger.info(f"Бот вошёл как {bot.user}")
for cog_class in ALL_COMMANDS: for cog_class in ALL_COMMANDS:
cog = cog_class() cog = cog_class()
await bot.add_cog(cog) await bot.add_cog(cog)
for cog in bot.cogs: for cog in bot.cogs:
print(f" Загружен: {cog}") logger.info(f" Загружен: {cog}")
# Запуск планировщика # Запуск планировщика
morning_time = os.getenv("MORNING_TIME", "07:00") morning_time = os.getenv("MORNING_TIME", "07:00")
scheduler = Scheduler(bot, morning_time) scheduler = Scheduler(bot, morning_time)
print(f" Планировщик запущен (время: {morning_time})") logger.info(f" Планировщик запущен (время: {morning_time})")
bot_ready.set() bot_ready.set()
@ -116,20 +116,20 @@ def console_input():
try: try:
asyncio.run_coroutine_threadsafe(bot.close(), bot.loop).result(timeout=5) asyncio.run_coroutine_threadsafe(bot.close(), bot.loop).result(timeout=5)
except Exception as e: except Exception as e:
print(f"Ошибка при остановке бота: {e}") logger.error(f"Ошибка при остановке бота: {e}")
break break
if __name__ == "__main__": if __name__ == "__main__":
token = os.getenv("DISCORD_TOKEN") token = os.getenv("DISCORD_TOKEN")
if not token: if not token:
print("Ошибка: токен не найден в .env") logger.error("Токен Discord не найден в .env")
sys.exit(1) sys.exit(1)
# Консольный ввод работает только в интерактивном терминале # Консольный ввод работает только в интерактивном терминале
# В Docker stdin недоступен — пропускаем консольный режим # В Docker stdin недоступен — пропускаем консольный режим
if sys.stdin.isatty(): if sys.stdin.isatty():
print("Введите 'stop' для остановки бота") logger.info("Введите 'stop' для остановки бота")
thread = threading.Thread(target=console_input, daemon=True) thread = threading.Thread(target=console_input, daemon=True)
thread.start() thread.start()
@ -137,18 +137,18 @@ if __name__ == "__main__":
bot.run(token) bot.run(token)
except discord.LoginFailure as e: except discord.LoginFailure as e:
logger.critical(f"Ошибка авторизации бота: {e}", exc_info=True) logger.critical(f"Ошибка авторизации бота: {e}", exc_info=True)
print(f"❌ Токен неверный или бот отключён. Код ошибки: {e}") logger.error("Токен неверный или бот отключён. Код ошибки: %s", e)
sys.exit(1) sys.exit(1)
except discord.HTTPException as e: except discord.HTTPException as e:
logger.critical(f"HTTP ошибка при подключении к Discord: {e}", exc_info=True) logger.critical(f"HTTP ошибка при подключении к Discord: {e}", exc_info=True)
print(f"Сбой соединения с Discord API. Проверьте доступность сервиса.") logger.error("Сбой соединения с Discord API. Проверьте доступность сервиса.")
sys.exit(1) sys.exit(1)
except Exception as e: except Exception as e:
logger.critical(f"Непредвиденная ошибка при запуске бота: {e}", exc_info=True) logger.critical(f"Непредвиденная ошибка при запуске бота: {e}", exc_info=True)
print(f"❌ Критическая ошибка при запуске. Код ошибки: {type(e).__name__}") logger.error("Критическая ошибка при запуске. Код ошибки: %s", type(e).__name__)
sys.exit(1) sys.exit(1)
except KeyboardInterrupt: except KeyboardInterrupt:
print("\nОстановка бота...") logger.info("Остановка бота...")
stop_event.set() stop_event.set()
if scheduler: if scheduler:
scheduler.stop() scheduler.stop()

View File

@ -30,5 +30,3 @@ class Help(commands.Cog):
await ctx.send(message) await ctx.send(message)
if __name__ == "__main__":
print("Cog loaded!")

View File

@ -1,4 +1,7 @@
import asyncio import asyncio
import logging
logger = logging.getLogger(__name__)
def stop(stop_event, bot): def stop(stop_event, bot):
@ -7,4 +10,4 @@ def stop(stop_event, bot):
try: try:
asyncio.run_coroutine_threadsafe(bot.close(), bot.loop).result(timeout=5) asyncio.run_coroutine_threadsafe(bot.close(), bot.loop).result(timeout=5)
except Exception as e: except Exception as e:
print(f"Ошибка при остановке бота: {e}") logger.error("Ошибка при остановке бота: %s", e)

View File

@ -1,7 +1,10 @@
import asyncio import asyncio
import logging
import requests import requests
from requests.exceptions import ConnectionError, Timeout, SSLError from requests.exceptions import ConnectionError, Timeout, SSLError
logger = logging.getLogger(__name__)
API_URL_WEATHER = "https://wttr.in/Magnitogorsk?format=j1&lang=ru" API_URL_WEATHER = "https://wttr.in/Magnitogorsk?format=j1&lang=ru"
_session = requests.Session() _session = requests.Session()
@ -17,12 +20,12 @@ async def fetch_weather(api_url, timeout=10, max_retries=3):
except (SSLError, ConnectionError, Timeout): except (SSLError, ConnectionError, Timeout):
if attempt < max_retries - 1: if attempt < max_retries - 1:
delay = 2 ** attempt delay = 2 ** attempt
print(f"Попытка {attempt + 1} не удалась. Повтор через {delay} сек...") logger.warning("Попытка %d не удалась. Повтор через %d сек...", attempt + 1, delay)
await asyncio.sleep(delay) await asyncio.sleep(delay)
continue continue
break break
except requests.RequestException as e: except requests.RequestException as e:
print(f"Ошибка при получении данных: {e}") logger.error("Ошибка при получении данных: %s", e)
break break
# Fallback: Open-Meteo API (без ключа, HTTPS) # Fallback: Open-Meteo API (без ключа, HTTPS)
@ -59,12 +62,12 @@ async def fetch_open_meteo(lat=53.4069, lon=58.9797, timeout=10, max_retries=3):
except (SSLError, ConnectionError, Timeout): except (SSLError, ConnectionError, Timeout):
if attempt < max_retries - 1: if attempt < max_retries - 1:
delay = 2 ** attempt delay = 2 ** attempt
print(f"Попытка {attempt + 1} не удалась. Повтор через {delay} сек...") logger.warning("Попытка %d не удалась. Повтор через %d сек...", attempt + 1, delay)
await asyncio.sleep(delay) await asyncio.sleep(delay)
continue continue
break break
except requests.RequestException as e: except requests.RequestException as e:
print(f"Ошибка при получении данных: {e}") logger.error("Ошибка при получении данных: %s", e)
return None return None
return None return None